From cvs at cvs.gnupg.org Mon Aug 1 11:19:15 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 01 Aug 2016 11:19:15 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-30-gc971ff0 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 c971ff0823d9a649b32fd9f169a12abc3095246e (commit) from 9e799b0e4f131126b80a5d3272c36d52b8ba1720 (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 c971ff0823d9a649b32fd9f169a12abc3095246e Author: Justus Winter Date: Mon Aug 1 11:08:43 2016 +0200 tests: Distribute standalone test runner. * tests/openpgp/Makefile.am (EXTRA_DIST): Add missing file 'run-tests.scm'. GnuPG-bug-id: 2431 Signed-off-by: Justus Winter diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index fa02a93..7983d6f 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -159,7 +159,7 @@ sample_msgs = samplemsgs/issue2419.asc EXTRA_DIST = defs.inc defs.scm pinentry.sh $(TESTS) $(TEST_FILES) \ mkdemodirs signdemokey $(priv_keys) $(sample_keys) \ - $(sample_msgs) ChangeLog-2011 + $(sample_msgs) ChangeLog-2011 run-tests.scm CLEANFILES = prepared.stamp x y yy z out err $(data_files) \ plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \ ----------------------------------------------------------------------- Summary of changes: tests/openpgp/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 1 12:35:37 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 01 Aug 2016 12:35:37 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-31-g40365b2 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 40365b28c3fdf087fd58401f5a6f42f9d7d29d20 (commit) from c971ff0823d9a649b32fd9f169a12abc3095246e (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 40365b28c3fdf087fd58401f5a6f42f9d7d29d20 Author: Justus Winter Date: Mon Aug 1 12:32:36 2016 +0200 gpgsm: Fix machine-readable key listing. * sm/keylist.c (list_cert_colon): Drop superfluous colon. GnuPG-bug-id: 2432 Signed-off-by: Justus Winter diff --git a/sm/keylist.c b/sm/keylist.c index dab1295..0d975c3 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -494,7 +494,6 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, es_putc (':', fp); /* Field 12, capabilities: */ print_capabilities (cert, fp); - es_putc (':', fp); /* Field 13, not used: */ es_putc (':', fp); if (have_secret || ctrl->with_secret) ----------------------------------------------------------------------- Summary of changes: sm/keylist.c | 1 - 1 file changed, 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 1 18:00:05 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 01 Aug 2016 18:00:05 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-20-gad390f2 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 ad390f29df34ef73f2393a8ad97cbe2d60af31e7 (commit) via fe5bb475da08cb46242825d5abe5b4d27e6086e3 (commit) via abf4f9924412c7afb6ce6c08eeda81b4c5365ab5 (commit) from ed066c261594de69c3c2aeaac98aeaf74bbb5f9e (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 ad390f29df34ef73f2393a8ad97cbe2d60af31e7 Author: Justus Winter Date: Mon Aug 1 17:49:50 2016 +0200 gtk2: Be more persistent trying to grab the keyboard. We seem to get the 'visibility-notify' event before X is willing to let us grab the keyboard, insisting that the target window is not viewable (sic). * gtk+-2/pinentry-gtk-2.c (grab_keyboard): Retry grabbing the keyboard. GnuPG-bug-id: 2375 Signed-off-by: Justus Winter diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 3fff176..0e6b8ff 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -165,13 +165,17 @@ static int grab_keyboard (GtkWidget *win, GdkEvent *event, gpointer data) { GdkGrabStatus err; + int tries = 0, max_tries = 4096; (void)data; if (! pinentry->grab) return FALSE; - err = gdk_keyboard_grab (gtk_widget_get_window (win), - FALSE, gdk_event_get_time (event)); + do + err = gdk_keyboard_grab (gtk_widget_get_window (win), + FALSE, gdk_event_get_time (event)); + while (tries++ < max_tries && err == GDK_GRAB_NOT_VIEWABLE); + if (err) { g_critical ("could not grab keyboard: %s (%d)", @@ -180,6 +184,9 @@ grab_keyboard (GtkWidget *win, GdkEvent *event, gpointer data) gtk_main_quit (); } + if (tries > 1) + g_warning ("it took %d tries to grab the keyboard", tries); + return FALSE; } commit fe5bb475da08cb46242825d5abe5b4d27e6086e3 Author: Justus Winter Date: Mon Aug 1 17:18:32 2016 +0200 gtk2: Print keyboard grabbing errors. * gtk+-2/pinentry-gtk-2.c (grab_strerror): New function. (grab_keyboard): Use the new function to print the error. Signed-off-by: Justus Winter diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 98d4fc2..3fff176 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -145,22 +145,41 @@ make_transient (GtkWidget *win, GdkEvent *event, gpointer data) } +/* Convert GdkGrabStatus to string. */ +static const char * +grab_strerror (GdkGrabStatus status) +{ + switch (status) { + case GDK_GRAB_SUCCESS: return "success"; + case GDK_GRAB_ALREADY_GRABBED: return "already grabbed"; + case GDK_GRAB_INVALID_TIME: return "invalid time"; + case GDK_GRAB_NOT_VIEWABLE: return "not viewable"; + case GDK_GRAB_FROZEN: return "frozen"; + } + return "unknown"; +} + + /* Grab the keyboard for maximum security */ static int grab_keyboard (GtkWidget *win, GdkEvent *event, gpointer data) { + GdkGrabStatus err; (void)data; if (! pinentry->grab) return FALSE; - if (gdk_keyboard_grab (gtk_widget_get_window (win), - FALSE, gdk_event_get_time (event))) + err = gdk_keyboard_grab (gtk_widget_get_window (win), + FALSE, gdk_event_get_time (event)); + if (err) { - g_critical ("could not grab keyboard"); + g_critical ("could not grab keyboard: %s (%d)", + grab_strerror (err), err); grab_failed = 1; gtk_main_quit (); } + return FALSE; } commit abf4f9924412c7afb6ce6c08eeda81b4c5365ab5 Author: Justus Winter Date: Mon Aug 1 15:01:21 2016 +0200 gtk2: Avoid possible format string troubles. * gtk+-2/pinentry-gtk-2.c (confirm_unhiding): Do not use message as format string. Signed-off-by: Justus Winter diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 28b4fdc..98d4fc2 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -389,7 +389,7 @@ confirm_unhiding (void) GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, - message); + "%s", message); gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, show_btn_label, GTK_RESPONSE_OK, ----------------------------------------------------------------------- Summary of changes: gtk+-2/pinentry-gtk-2.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 2 12:47:44 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 02 Aug 2016 12:47:44 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-21-g2f1f1f0 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 2f1f1f06c1885d2f5a30ea734359613609be0743 (commit) from ad390f29df34ef73f2393a8ad97cbe2d60af31e7 (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 2f1f1f06c1885d2f5a30ea734359613609be0743 Author: Justus Winter Date: Tue Aug 2 12:34:07 2016 +0200 gtk2: Also grab the pointer. * gtk+-2/pinentry-gtk-2.c (grab_pointer): New function. (ungrab_keyboard): Rename to 'ungrab_inputs' and also release the pointer grab. (create_window): Also grab the pointer. GnuPG-bug-id: 2430 Signed-off-by: Justus Winter diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 0e6b8ff..cd6270f 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -191,13 +191,53 @@ grab_keyboard (GtkWidget *win, GdkEvent *event, gpointer data) } -/* Remove grab. */ +/* Grab the pointer to prevent the user from accidentally locking + herself out of her graphical interface. */ static int -ungrab_keyboard (GtkWidget *win, GdkEvent *event, gpointer data) +grab_pointer (GtkWidget *win, GdkEvent *event, gpointer data) { + GdkGrabStatus err; + GdkCursor *cursor; + int tries = 0, max_tries = 4096; (void)data; + /* Change the cursor for the duration of the grab to indicate that + something is going on. */ + /* XXX: It would be nice to have a key cursor, unfortunately there + is none readily available. */ + cursor = gdk_cursor_new_for_display (gtk_widget_get_display (win), + GDK_DOT); + + do + err = gdk_pointer_grab (gtk_widget_get_window (win), + TRUE, 0 /* event mask */, + NULL /* confine to */, + cursor, + gdk_event_get_time (event)); + while (tries++ < max_tries && err == GDK_GRAB_NOT_VIEWABLE); + + if (err) + { + g_critical ("could not grab pointer: %s (%d)", + grab_strerror (err), err); + grab_failed = 1; + gtk_main_quit (); + } + + if (tries > 1) + g_warning ("it took %d tries to grab the pointer", tries); + + return FALSE; +} + + +/* Remove all grabs and restore the windows transient state. */ +static int +ungrab_inputs (GtkWidget *win, GdkEvent *event, gpointer data) +{ + (void)data; gdk_keyboard_ungrab (gdk_event_get_time (event)); + gdk_pointer_ungrab (gdk_event_get_time (event)); /* Unmake window transient for the root window. */ /* gdk_window_set_transient_for cannot be used with parent = NULL to unset transient hint (unlike gtk_ version which can). Replacement @@ -548,9 +588,13 @@ create_window (pinentry_t ctx) ? "visibility-notify-event" : "focus-in-event", G_CALLBACK (grab_keyboard), NULL); + if (pinentry->grab) + g_signal_connect (G_OBJECT (win), + "visibility-notify-event", + G_CALLBACK (grab_pointer), NULL); g_signal_connect (G_OBJECT (win), pinentry->grab ? "unmap-event" : "focus-out-event", - G_CALLBACK (ungrab_keyboard), NULL); + G_CALLBACK (ungrab_inputs), NULL); } gtk_window_add_accel_group (GTK_WINDOW (win), acc); ----------------------------------------------------------------------- Summary of changes: gtk+-2/pinentry-gtk-2.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 2 16:58:19 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 02 Aug 2016 16:58:19 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-253-g135185b 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 135185b7ef2225aa5e8c54a6cf1265d3e6cbbe48 (commit) via e11c65cfb56adce949cf3888545c56fbb6f5ab42 (commit) from 4e728de8421e2ade2061786aaebcdae3f60da3b8 (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 135185b7ef2225aa5e8c54a6cf1265d3e6cbbe48 Author: Justus Winter Date: Tue Aug 2 16:51:08 2016 +0200 doc: Document the Assuan protocol. * doc/gpgme.texi: Document the Assuan protocol. GnuPG-bug-id: 2407 Signed-off-by: Justus Winter diff --git a/doc/gpgme.texi b/doc/gpgme.texi index a5ba9cc..68f85ec 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -872,9 +872,12 @@ This specifies the OpenPGP protocol. @item GPGME_PROTOCOL_CMS This specifies the Cryptographic Message Syntax. - at item GPGME_PROTOCOL_ASSUAN + at item GPGME_PROTOCOL_GPGCONF Under development. Please ask on @email{gnupg-devel@@gnupg.org} for help. + at item GPGME_PROTOCOL_ASSUAN +This specifies the raw Assuan protocol. + @item GPGME_PROTOCOL_G13 Under development. Please ask on @email{gnupg-devel@@gnupg.org} for help. @@ -905,6 +908,7 @@ allocated string describing the protocol @var{protocol}, or * Engine Configuration:: Changing the engine configuration. * OpenPGP:: Support for the OpenPGP protocol. * Cryptographic Message Syntax:: Support for the CMS. +* Assuan:: Support for the raw Assuan protocol. @end menu @@ -1109,6 +1113,20 @@ GnuPG. The @acronym{CMS} protocol is specified by @code{GPGME_PROTOCOL_CMS}. + at node Assuan + at section Assuan + at cindex ASSUAN + at cindex protocol, ASSUAN + at cindex engine, ASSUAN + +Assuan is the RPC library used by the various @acronym{GnuPG} +components. The Assuan protocol allows one to talk to arbitrary +Assuan servers using @acronym{GPGME}. @xref{Using the Assuan +protocol}. + +The ASSUAN protocol is specified by @code{GPGME_PROTOCOL_ASSUAN}. + + @node Algorithms @chapter Algorithms @cindex algorithms @@ -5478,6 +5496,7 @@ Here are some support functions which are sometimes useful. @menu * Running other Programs:: Running other Programs +* Using the Assuan protocol:: Using the Assuan protocol @end menu @@ -5532,6 +5551,83 @@ This is the asynchronous variant of @code{gpgme_op_spawn}. @end deftypefun + at node Using the Assuan protocol + at subsection Using the Assuan protocol + +The Assuan protocol can be used to talk to arbitrary Assuan servers. +By default it is connected to the GnuPG agent, but it may be connected +to arbitrary servers by using @code{gpgme_ctx_set_engine_info}, +passing the location of the servers socket as @var{file_name} +argument, and an empty string as @var{home_dir} argument. + +The Assuan protocol functions use three kinds of callbacks to transfer +data: + + at deftp {Data type} {gpgme_error_t (*gpgme_assuan_data_cb_t) @ + (@w{void *@var{opaque}}, @w{const void *@var{data}}, @ + @w{size_t @var{datalen}})} + +This callback receives any data sent by the server. @var{opaque} is +the pointer passed to @code{gpgme_op_assuan_transact_start}, + at var{data} of length @var{datalen} refers to the data sent. + at end deftp + + at deftp {Data type} {gpgme_error_t (*gpgme_assuan_inquire_cb_t) @ + (@w{void *@var{opaque}}, @w{const char *@var{name}}, @ + @w{const char *@var{args}}, @w{gpgme_data_t *@var{r_data}})} + +This callback is used to provide additional data to the Assuan server. + at var{opaque} is the pointer passed to + at code{gpgme_op_assuan_transact_start}, @var{name} and @var{args} +specify what kind of data the server requested, and @var{r_data} is +used to return the actual data. + +Note: Returning data is currently not implemented in @acronym{GPGME}. + at end deftp + + at deftp {Data type} {gpgme_error_t (*gpgme_assuan_status_cb_t) @ + (@w{void *@var{opaque}}, @w{const char *@var{status}}, @ + @w{const char *@var{args}})} + +This callback receives any status lines sent by the server. + at var{opaque} is the pointer passed to + at code{gpgme_op_assuan_transact_start}, @var{status} and @var{args} +denote the status update sent. + at end deftp + + at deftypefun gpgme_error_t gpgme_op_assuan_transact_start @ + (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{command}}, @ + @w{gpgme_assuan_data_cb_t @var{data_cb}}, @ + @w{void * @var{data_cb_value}}, @ + @w{gpgme_assuan_inquire_cb_t @var{inquire_cb}}, @ + @w{void * @var{inquire_cb_value}}, @ + @w{gpgme_assuan_status_cb_t @var{status_cb}}, @ + @w{void * @var{status_cb_value}}) + +Send the Assuan @var{command} and return results via the callbacks. +Any callback may be @code{NULL}. The result of the operation may be +retrieved using @code{gpgme_wait_ext}. + +Asynchronous variant. + at end deftypefun + + at deftypefun gpgme_error_t gpgme_op_assuan_transact_ext @ + (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{command}}, @ + @w{gpgme_assuan_data_cb_t @var{data_cb}}, @ + @w{void * @var{data_cb_value}}, @ + @w{gpgme_assuan_inquire_cb_t @var{inquire_cb}}, @ + @w{void * @var{inquire_cb_value}}, @ + @w{gpgme_assuan_status_cb_t @var{status_cb}}, @ + @w{void * @var{status_cb_value}}, @ + @w{gpgme_error_t *@var{op_err}}) + +Send the Assuan @var{command} and return results via the callbacks. +The result of the operation is returned in @var{op_err}. + +Synchronous variant. + at end deftypefun + + @node Run Control @section Run Control @cindex run control commit e11c65cfb56adce949cf3888545c56fbb6f5ab42 Author: Justus Winter Date: Tue Aug 2 16:50:54 2016 +0200 doc: Fix formatting. -- Signed-off-by: Justus Winter diff --git a/doc/gpgme.texi b/doc/gpgme.texi index c514ff8..a5ba9cc 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -5492,7 +5492,7 @@ which are part of the GnuPG system but are not directly accessible with the GPGME API. - at deftypefun gpgme_error_t gpgme_op_spawn + at deftypefun gpgme_error_t gpgme_op_spawn @ (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{file}}, @ @w{const char *@var{argv}[]}, @w{gpgme_data_t @var{datain}}, @ @w{gpgme_data_t @var{dataout}}, @w{gpgme_data_t @var{dataerr}}, @ @@ -5522,7 +5522,7 @@ the foreground. @end table @end deftypefun - at deftypefun gpgme_error_t gpgme_op_spawn_start + at deftypefun gpgme_error_t gpgme_op_spawn_start @ (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{file}}, @ @w{const char *@var{argv}[]}, @w{gpgme_data_t @var{datain}}, @ @w{gpgme_data_t @var{dataout}}, @w{gpgme_data_t @var{dataerr}}, @ ----------------------------------------------------------------------- Summary of changes: doc/gpgme.texi | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 2 18:14:58 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 02 Aug 2016 18:14:58 +0200 Subject: [git] gnupg-doc - branch, master, updated. 93b627789f7fa7f61484b3cdd0f670fe22407994 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 93b627789f7fa7f61484b3cdd0f670fe22407994 (commit) from ff08d72e451c10e318b59e5c6a3b92ebbc155525 (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 93b627789f7fa7f61484b3cdd0f670fe22407994 Author: Werner Koch Date: Tue Aug 2 18:02:57 2016 +0200 web: Rename cvs_access.org to git.org diff --git a/web/documentation/guides.org b/web/documentation/guides.org index 9f59d04..2a08842 100644 --- a/web/documentation/guides.org +++ b/web/documentation/guides.org @@ -33,7 +33,7 @@ [[../../gph/it/gph.tar.gz][it]] ? [[http://www.inar.ru/~zwon/gph.tar.gz][ru]] ) - GPH is also available in the [[../download/cvs_access.org][source repository]]. + GPH is also available in the [[../download/git.org][source repository]]. ** Replacing PGP 2.x with GnuPG diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index d3e98b3..f79425c 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -58,7 +58,7 @@ - as one big HTML file ( [[../howtos/card-howto/en/smartcard-howto-single.html][en]] ) - as plain text ( [[../howtos/card-howto/en/smartcard-howto.txt][en]] ) - This smartcard howto is also available in the [[../download/cvs_access.org][source repository]]. + This smartcard howto is also available in the [[../download/git.org][source repository]]. ** GnuPG Keysigning Party HOWTO diff --git a/web/documentation/security.org b/web/documentation/security.org index e328928..783a5c9 100644 --- a/web/documentation/security.org +++ b/web/documentation/security.org @@ -6,7 +6,7 @@ The GnuPG Project takes the security of software it develops very seriously. In general we prefer a [[https://en.wikipedia.org/wiki/Full_disclosure_(computer_security)][full disclosure]] approach and all -bugs listed in our [[file:bts.org][bug tracker]] as well as code changes in our [[../download/cvs_access.org][software +bugs listed in our [[file:bts.org][bug tracker]] as well as code changes in our [[../download/git.org][software repository]] are public. Given that GnuPG is an important part of many software distributions and severe bugs in GnuPG would affect their users directly, we co-ordinate with them in private as soon as we diff --git a/web/download/cvs_access.org b/web/download/git.org similarity index 100% rename from web/download/cvs_access.org rename to web/download/git.org diff --git a/web/share/gpgweb.el b/web/share/gpgweb.el index 7458dfe..15e4162 100644 --- a/web/share/gpgweb.el +++ b/web/share/gpgweb.el @@ -105,7 +105,7 @@ if not available." ("/download/supported_systems.html" "Supported Systems") ("/download/release_notes.html" "Release Notes") ("/download/mirrors.html" "Mirrors") - ("/download/cvs_access.html" "GIT"))) + ("/download/git.html" "GIT"))) ("/documentation/index.html" "Support" (("/documentation/howtos.html" "HOWTOs") ----------------------------------------------------------------------- Summary of changes: web/documentation/guides.org | 2 +- web/documentation/howtos.org | 2 +- web/documentation/security.org | 2 +- web/download/{cvs_access.org => git.org} | 0 web/share/gpgweb.el | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename web/download/{cvs_access.org => git.org} (100%) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 2 18:49:42 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 02 Aug 2016 18:49:42 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-255-g4c8265d 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 4c8265d32ddff5960a464b8d4e8d7d2258495b2e (commit) via 0bd7d8c1977183abc414e11aafa26a4f834ca2a5 (commit) from 135185b7ef2225aa5e8c54a6cf1265d3e6cbbe48 (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 4c8265d32ddff5960a464b8d4e8d7d2258495b2e Author: Justus Winter Date: Tue Aug 2 18:45:10 2016 +0200 python: Add a flag identifying in-tree builds. * lang/python/helpers.c (pyme_in_tree_build): New variable. * lang/python/helpers.h (pyme_in_tree_build): New declaration. * lang/python/pyme/version.py.in (in_tree_build): New variable. * lang/python/setup.py.in: Rework macro handling, set 'IN_TREE_BUILD' as appropriate. Signed-off-by: Justus Winter diff --git a/lang/python/helpers.c b/lang/python/helpers.c index 0406f9f..0b4a773 100644 --- a/lang/python/helpers.c +++ b/lang/python/helpers.c @@ -28,6 +28,15 @@ #include "helpers.h" #include "private.h" +/* Flag specifying whether this is an in-tree build. */ +int pyme_in_tree_build = +#if IN_TREE_BUILD + 1 +#else + 0 +#endif + ; + static PyObject *GPGMEError = NULL; void _pyme_exception_init(void) { diff --git a/lang/python/helpers.h b/lang/python/helpers.h index 16a9b9f..9200f93 100644 --- a/lang/python/helpers.h +++ b/lang/python/helpers.h @@ -26,6 +26,9 @@ #define write(fd, str, sz) {DWORD written; WriteFile((HANDLE) fd, str, sz, &written, 0);} #endif +/* Flag specifying whether this is an in-tree build. */ +extern int pyme_in_tree_build; + PyObject *pyme_raise_callback_exception(PyObject *self); PyObject *pyme_set_passphrase_cb(PyObject *self, PyObject *cb); diff --git a/lang/python/pyme/version.py.in b/lang/python/pyme/version.py.in index a40e02d..e4a5a27 100644 --- a/lang/python/pyme/version.py.in +++ b/lang/python/pyme/version.py.in @@ -21,6 +21,7 @@ from . import gpgme productname = 'pyme' versionstr = "@VERSION@" gpgme_versionstr = gpgme.GPGME_VERSION +in_tree_build = bool(gpgme.cvar.pyme_in_tree_build) versionlist = versionstr.split(".") major = versionlist[0] diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index 45b56a3..a524c95 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -28,7 +28,9 @@ gpg_error_config = "gpg-error-config" gpgme_config = "gpgme-config" gpgme_h = "" library_dirs = [] +in_tree = False extra_swig_opts = [] +extra_macros = dict() if os.path.exists("../../src/gpgme-config"): # In-tree build. @@ -36,7 +38,10 @@ if os.path.exists("../../src/gpgme-config"): gpgme_config = "../../src/gpgme-config" gpgme_h = "../../src/gpgme.h" library_dirs = ["../../src/.libs"] # XXX uses libtool internals - extra_swig_opts = ["-DHAVE_DATA_H=1"] + extra_macros.update( + HAVE_DATA_H=1, + IN_TREE_BUILD=1, + ) try: subprocess.check_call([gpg_error_config, '--version'], @@ -87,6 +92,11 @@ include_dirs = [os.getcwd()] define_macros = [] libs = getconfig('libs') +# Define extra_macros for both the SWIG and C code +for k, v in extra_macros.items(): + extra_swig_opts.append("-D{0}={1}".format(k, v)) + define_macros.append((k, str(v))) + for item in getconfig('cflags'): if item.startswith("-I"): include_dirs.append(item[2:]) commit 0bd7d8c1977183abc414e11aafa26a4f834ca2a5 Author: Justus Winter Date: Tue Aug 2 18:42:26 2016 +0200 python: Fix build system integration. * lang/python/Makefile.am: Be more careful when cleaning the build directory, we must not delete the generated file 'pyme/version.py'. Signed-off-by: Justus Winter diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am index f0df800..8e18dab 100644 --- a/lang/python/Makefile.am +++ b/lang/python/Makefile.am @@ -32,14 +32,25 @@ COPY_FILES = \ $(srcdir)/README \ $(srcdir)/MANIFEST.in \ $(srcdir)/gpgme-h-clean.py \ - $(srcdir)/pyme \ $(srcdir)/examples \ $(srcdir)/helpers.c $(srcdir)/helpers.h $(srcdir)/private.h +COPY_FILES_PYME = \ + $(srcdir)/pyme/callbacks.py \ + $(srcdir)/pyme/constants \ + $(srcdir)/pyme/core.py \ + $(srcdir)/pyme/errors.py \ + $(srcdir)/pyme/__init__.py \ + $(srcdir)/pyme/results.py \ + $(srcdir)/pyme/util.py + # For VPATH builds we need to copy some files because Python's # distutils are not VPATH-aware. -copystamp: $(COPY_FILES) - if test "$(srcdir)" != "$(builddir)" ; then cp -r $^ . ; fi +copystamp: $(COPY_FILES) $(COPY_FILES_PYME) + if test "$(srcdir)" != "$(builddir)" ; then \ + cp -r $(COPY_FILES) . ; \ + cp -r $(COPY_FILES_PYME) pyme ; \ + fi touch $@ all-local: copystamp @@ -70,6 +81,9 @@ clean-local: if test "$(srcdir)" != "$(builddir)" ; then \ find . -type d ! -perm -200 -exec chmod u+w {} ';' ; \ for F in $(COPY_FILES); do rm -rf -- `basename $$F` ; done ; \ + for F in $(COPY_FILES_PYME); do \ + rm -rf -- pyme/`basename $$F` ; \ + done ; \ fi install-exec-local: ----------------------------------------------------------------------- Summary of changes: lang/python/Makefile.am | 20 +++++++++++++++++--- lang/python/helpers.c | 9 +++++++++ lang/python/helpers.h | 3 +++ lang/python/pyme/version.py.in | 1 + lang/python/setup.py.in | 12 +++++++++++- 5 files changed, 41 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 3 15:42:01 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 03 Aug 2016 15:42:01 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-33-g48a2c93 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 48a2c93a1886589d1a0e2a4a2173e0e81311200b (commit) via 3a2421c94015432caa49e166bc5bf5c4f80ab7c7 (commit) from 40365b28c3fdf087fd58401f5a6f42f9d7d29d20 (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 48a2c93a1886589d1a0e2a4a2173e0e81311200b Author: Werner Koch Date: Wed Aug 3 15:31:27 2016 +0200 gpg,gpgsm: Block signals during keyring/keybox update. * kbx/keybox-util.c (keybox_file_rename): Add arg BLOCK_SIGNALS. * kbx/keybox-update.c (rename_tmp_file): Block all signals when doing a double rename. * g10/keyring.c (rename_tmp_file): Block all signals during the double rename. -- This might fix Debian-bug-id: 831510 Signed-off-by: Werner Koch diff --git a/g10/keyring.c b/g10/keyring.c index 0611b2e..aa73290 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1338,6 +1338,7 @@ static int rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname) { int rc = 0; + int block = 0; /* Invalidate close caches. */ if (iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)tmpfname )) @@ -1349,12 +1350,18 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname) iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname ); /* First make a backup file. */ - rc = keybox_file_rename (fname, bakfname); + block = 1; + rc = keybox_file_rename (fname, bakfname, &block); if (rc) goto fail; /* then rename the file */ - rc = keybox_file_rename (tmpfname, fname); + rc = keybox_file_rename (tmpfname, fname, NULL); + if (block) + { + gnupg_unblock_all_signals (); + block = 0; + } if (rc) { register_secured_file (fname); @@ -1379,6 +1386,8 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname) return 0; fail: + if (block) + gnupg_unblock_all_signals (); return rc; } diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index ff65904..ec28b4c 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -97,6 +97,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname, int secret ) { int rc=0; + int block = 0; /* restrict the permissions for secret keyboxs */ #ifndef HAVE_DOSISH_SYSTEM @@ -119,27 +120,35 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, /* First make a backup file except for secret keyboxes. */ if (!secret) { - rc = keybox_file_rename (fname, bakfname); + block = 1; + rc = keybox_file_rename (fname, bakfname, &block); if (rc) - return rc; + goto leave; } /* Then rename the file. */ - rc = keybox_file_rename (tmpfname, fname); - if (rc) + rc = keybox_file_rename (tmpfname, fname, NULL); + if (block) { - if (secret) - { -/* log_info ("WARNING: 2 files with confidential" */ -/* " information exists.\n"); */ -/* log_info ("%s is the unchanged one\n", fname ); */ -/* log_info ("%s is the new one\n", tmpfname ); */ -/* log_info ("Please fix this possible security flaw\n"); */ - } - return rc; + gnupg_unblock_all_signals (); + block = 0; } + /* if (rc) */ + /* { */ + /* if (secret) */ + /* { */ + /* log_info ("WARNING: 2 files with confidential" */ + /* " information exists.\n"); */ + /* log_info ("%s is the unchanged one\n", fname ); */ + /* log_info ("%s is the new one\n", tmpfname ); */ + /* log_info ("Please fix this possible security flaw\n"); */ + /* } */ + /* } */ - return 0; + leave: + if (block) + gnupg_unblock_all_signals (); + return rc; } diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index 13fedb3..a2ca3f0 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -27,6 +27,7 @@ #endif #include "keybox-defs.h" +#include "utilproto.h" static void *(*alloc_func)(size_t n) = malloc; @@ -147,55 +148,70 @@ keybox_tmp_names (const char *filename, int for_keyring, } -/* Wrapper for rename(2) to handle Windows peculiarities. */ +/* Wrapper for rename(2) to handle Windows peculiarities. If + * BLOCK_SIGNALS is not NULL and points to a variable set to true, all + * signals will be blocked by calling gnupg_block_all_signals; the + * caller needs to call gnupg_unblock_all_signals if that variable is + * still set to true on return. */ gpg_error_t -keybox_file_rename (const char *oldname, const char *newname) +keybox_file_rename (const char *oldname, const char *newname, + int *block_signals) { gpg_error_t err = 0; -#ifdef HAVE_DOSISH_SYSTEM - int wtime = 0; + if (block_signals && *block_signals) + gnupg_block_all_signals (); - gnupg_remove (newname); - again: - if (rename (oldname, newname)) - { - if (GetLastError () == ERROR_SHARING_VIOLATION) - { - /* Another process has the file open. We do not use a lock - * for read but instead we wait until the other process has - * closed the file. This may take long but that would also - * be the case with a dotlock approach for read and write. - * Note that we don't need this on Unix due to the inode - * concept. - * - * So let's wait until the rename has worked. The retry - * intervals are 50, 100, 200, 400, 800, 50ms, ... */ - if (!wtime || wtime >= 800) - wtime = 50; - else - wtime *= 2; - - if (wtime >= 800) - log_info ("waiting for file '%s' to become accessible ...\n", - oldname); - - Sleep (wtime); - goto again; - } - err = gpg_error_from_syserror (); - } +#ifdef HAVE_DOSISH_SYSTEM + { + int wtime = 0; + gnupg_remove (newname); + again: + if (rename (oldname, newname)) + { + if (GetLastError () == ERROR_SHARING_VIOLATION) + { + /* Another process has the file open. We do not use a + * lock for read but instead we wait until the other + * process has closed the file. This may take long but + * that would also be the case with a dotlock approach for + * read and write. Note that we don't need this on Unix + * due to the inode concept. + * + * So let's wait until the rename has worked. The retry + * intervals are 50, 100, 200, 400, 800, 50ms, ... */ + if (!wtime || wtime >= 800) + wtime = 50; + else + wtime *= 2; + + if (wtime >= 800) + log_info ("waiting for file '%s' to become accessible ...\n", + oldname); + + Sleep (wtime); + goto again; + } + err = gpg_error_from_syserror (); + } + } #else /* Unix */ - + { #ifdef __riscos__ - gnupg_remove (newname); + gnupg_remove (newname); #endif - if (rename (oldname, newname) ) - err = gpg_error_from_syserror (); - + if (rename (oldname, newname) ) + err = gpg_error_from_syserror (); + } #endif /* Unix */ + if (block_signals && *block_signals && err) + { + gnupg_unblock_all_signals (); + *block_signals = 0; + } + if (err) log_error ("renaming '%s' to '%s' failed: %s\n", oldname, newname, gpg_strerror (err)); diff --git a/kbx/keybox.h b/kbx/keybox.h index bfc3586..6180a2f 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -134,7 +134,8 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), gpg_error_t keybox_tmp_names (const char *filename, int for_keyring, char **r_bakname, char **r_tmpname); -gpg_error_t keybox_file_rename (const char *oldname, const char *newname); +gpg_error_t keybox_file_rename (const char *oldname, const char *newname, + int *block_signals); #ifdef __cplusplus commit 3a2421c94015432caa49e166bc5bf5c4f80ab7c7 Author: Werner Koch Date: Wed Aug 3 15:27:03 2016 +0200 common: New file utilproto.c * common/util.h: Factor prototypes from signal.c out to ... * common/utilproto.h: new. * common/Makefile.am (common_sources): Add new file. Signed-off-by: Werner Koch diff --git a/common/Makefile.am b/common/Makefile.am index 759800b..2a24c57 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -42,7 +42,7 @@ include $(top_srcdir)/am/cmacros.am common_sources = \ common-defs.h \ - util.h fwddecl.h i18n.c i18n.h \ + util.h utilproto.h fwddecl.h i18n.c i18n.h \ types.h host2net.h dynload.h w32help.h \ mapstrings.c stringhelp.c stringhelp.h \ strlist.c strlist.h \ diff --git a/common/fwddecl.h b/common/fwddecl.h index 92f0453..f9d7536 100644 --- a/common/fwddecl.h +++ b/common/fwddecl.h @@ -1,4 +1,4 @@ -/* fwddecl.h - Formward declarations +/* fwddecl.h - Forward declarations * Copyright (C) 2015 Werner Koch * * This file is part of GnuPG. diff --git a/common/util.h b/common/util.h index eb7a3fd..29e0ec9 100644 --- a/common/util.h +++ b/common/util.h @@ -54,6 +54,7 @@ #include "../common/utf8conv.h" #include "../common/dynload.h" #include "../common/fwddecl.h" +#include "../common/utilproto.h" #include "gettime.h" @@ -114,11 +115,6 @@ out_of_core (void) } -/*-- signal.c --*/ -void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); -void gnupg_block_all_signals (void); -void gnupg_unblock_all_signals (void); - /*-- yesno.c --*/ int answer_is_yes (const char *s); int answer_is_yes_no_default (const char *s, int def_answer); diff --git a/common/fwddecl.h b/common/utilproto.h similarity index 64% copy from common/fwddecl.h copy to common/utilproto.h index 92f0453..5bb9dd1 100644 --- a/common/fwddecl.h +++ b/common/utilproto.h @@ -1,5 +1,5 @@ -/* fwddecl.h - Formward declarations - * Copyright (C) 2015 Werner Koch +/* utilproto.h - Some prototypes for inclusion by util.h + * Copyright (C) 2016 Werner Koch * * This file is part of GnuPG. * @@ -27,13 +27,18 @@ * along with this program; if not, see . */ -#ifndef GNUPG_COMMON_FWDDECL_H -#define GNUPG_COMMON_FWDDECL_H +/* This file is in general included via util.h but sometimes we do not + * want all stuff from util.h and instead use this file with its + * simple prototypes. */ +#ifndef GNUPG_COMMON_UTILPROTO_H +#define GNUPG_COMMON_UTILPROTO_H -/*-- Forward declaration of the commonly used server control structure. */ -struct server_control_s; -typedef struct server_control_s *ctrl_t; +/*-- signal.c --*/ +void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); +void gnupg_block_all_signals (void); +void gnupg_unblock_all_signals (void); -#endif /*GNUPG_COMMON_FWDDECL_H*/ + +#endif /*GNUPG_COMMON_UTILPROTO_H*/ ----------------------------------------------------------------------- Summary of changes: common/Makefile.am | 2 +- common/fwddecl.h | 2 +- common/util.h | 6 +-- common/{recsel.h => utilproto.h} | 25 +++++------ g10/keyring.c | 13 +++++- kbx/keybox-update.c | 37 ++++++++++------ kbx/keybox-util.c | 92 +++++++++++++++++++++++----------------- kbx/keybox.h | 3 +- 8 files changed, 106 insertions(+), 74 deletions(-) copy common/{recsel.h => utilproto.h} (65%) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 3 16:34:38 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 03 Aug 2016 16:34:38 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-256-g56e26b5 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 56e26b54da9f16961209275d7a61883d3ea898ca (commit) from 4c8265d32ddff5960a464b8d4e8d7d2258495b2e (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 56e26b54da9f16961209275d7a61883d3ea898ca Author: Justus Winter Date: Wed Aug 3 16:32:30 2016 +0200 python: Add a nicer interface to list keys. * lang/python/pyme/core.py (Context.keylist): New method. * lang/python/tests/t-keylist.py: Test new method. Signed-off-by: Justus Winter diff --git a/lang/python/pyme/core.py b/lang/python/pyme/core.py index e12dc7b..f9df6e8 100644 --- a/lang/python/pyme/core.py +++ b/lang/python/pyme/core.py @@ -468,6 +468,21 @@ class Context(GpgmeWrapper): plainbytes = data.read() return plainbytes, result + def keylist(self, pattern=None, secret=False): + """List keys + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + secret -- return only secret keys + + Returns: + -- an iterator returning key objects + + Raises: + GPGMEError -- as signaled by the underlying library + """ + return self.op_keylist_all(pattern, secret) + def assuan_transact(self, command, data_cb=None, inquire_cb=None, status_cb=None): """Issue a raw assuan command diff --git a/lang/python/tests/t-keylist.py b/lang/python/tests/t-keylist.py index fb59321..40d9c80 100755 --- a/lang/python/tests/t-keylist.py +++ b/lang/python/tests/t-keylist.py @@ -216,7 +216,7 @@ result = c.op_keylist_result() assert not result.truncated, "Key listing unexpectedly truncated" -for i, key in enumerate(c.op_keylist_all(None, False)): +for i, key in enumerate(c.keylist()): try: if len(keys[i]) == 4: fpr, sec_keyid, uids, n_subkeys = keys[i] ----------------------------------------------------------------------- Summary of changes: lang/python/pyme/core.py | 15 +++++++++++++++ lang/python/tests/t-keylist.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 3 17:02:56 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 03 Aug 2016 17:02:56 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-38-g993f36e 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 993f36e23cf8c2216a40d3e51b922a1edd871e1b (commit) via e3358b246d9380008a4ba7c8f2fe03659901adaf (commit) via dc107b78509807db375d3a382eb3376cd2183357 (commit) via 436b28c23194fa77919967338d5a61a82d242153 (commit) via cd45cf782b91ff0f6b023913963e5258ffcbf464 (commit) from 48a2c93a1886589d1a0e2a4a2173e0e81311200b (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 993f36e23cf8c2216a40d3e51b922a1edd871e1b Author: Justus Winter Date: Wed Aug 3 17:00:40 2016 +0200 Reword feature description. -- Suggested-by: Peter Gutmann Signed-off-by: Justus Winter diff --git a/README b/README index bb5cbef..c8b166b 100644 --- a/README +++ b/README @@ -17,8 +17,8 @@ GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications. A wealth of frontend applications and libraries are available that make use of GnuPG. - Since version 2 GnuPG provides support for S/MIME and Secure Shell - in addition to OpenPGP. + Starting with version 2 GnuPG provides support for S/MIME and Secure + Shell in addition to OpenPGP. GnuPG is Free Software (meaning that it respects your freedom). It can be freely used, modified and distributed under the terms of the diff --git a/doc/announce-2.1.txt b/doc/announce-2.1.txt index 8c35e53..eccd0e7 100644 --- a/doc/announce-2.1.txt +++ b/doc/announce-2.1.txt @@ -11,8 +11,8 @@ communication, features a versatile key management system as well as access modules for public key directories. GnuPG itself is a command line tool with features for easy integration with other applications. A wealth of frontend applications and libraries are available that -make use of GnuPG. Since version 2 GnuPG provides support for S/MIME -and Secure Shell in addition to OpenPGP. +make use of GnuPG. Starting with version 2 GnuPG provides support for +S/MIME and Secure Shell in addition to OpenPGP. GnuPG is Free Software (meaning that it respects your freedom). It can be freely used, modified and distributed under the terms of the GNU commit e3358b246d9380008a4ba7c8f2fe03659901adaf Author: Justus Winter Date: Wed Aug 3 16:58:32 2016 +0200 kbx: Add missing header file. * kbx/keybox-update.c: Add missing header file. Signed-off-by: Justus Winter diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index ec28b4c..e5d4dc8 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -29,6 +29,7 @@ #include "keybox-defs.h" #include "../common/sysutils.h" #include "../common/host2net.h" +#include "../common/utilproto.h" #define EXTSEP_S "." commit dc107b78509807db375d3a382eb3376cd2183357 Author: Daniel Kahn Gillmor Date: Mon Aug 1 22:19:17 2016 -0400 More cleanup of "allow to". * README, agent/command.c, agent/keyformat.txt, common/i18n.c, common/iobuf.c, common/keyserver.h, dirmngr/cdblib.c, dirmngr/ldap-wrapper.c, doc/DETAILS, doc/TRANSLATE, doc/announce-2.1.txt, doc/gpg.texi, doc/gpgsm.texi, doc/scdaemon.texi, doc/tools.texi, doc/whats-new-in-2.1.txt, g10/export.c, g10/getkey.c, g10/import.c, g10/keyedit.c, m4/ksba.m4, m4/libgcrypt.m4, m4/ntbtls.m4, po/ca.po, po/cs.po, po/da.po, po/de.po, po/el.po, po/eo.po, po/es.po, po/et.po, po/fi.po, po/fr.po, po/gl.po, po/hu.po, po/id.po, po/it.po, po/ja.po, po/nb.po, po/pl.po, po/pt.po, po/ro.po, po/ru.po, po/sk.po, po/sv.po, po/tr.po, po/uk.po, po/zh_CN.po, po/zh_TW.po, scd/app-p15.c, scd/ccid-driver.c, scd/command.c, sm/gpgsm.c, sm/sign.c, tools/gpgconf-comp.c, tools/gpgtar.h: replace "Allow to" with clearer text. In standard English, the normal construction is "${XXX} allows ${YYY} to" -- that is, the subject (${XXX}) of the sentence is allowing the object (${YYY}) to do something. When the object is missing, the phrasing sounds awkward, even if the object is implied by context. There's almost always a better construction that isn't as awkward. These changes should make the language a bit clearer. Signed-off-by: Daniel Kahn Gillmor diff --git a/README b/README index 224db30..bb5cbef 100644 --- a/README +++ b/README @@ -9,15 +9,16 @@ * INTRODUCTION GnuPG is a complete and free implementation of the OpenPGP standard - as defined by RFC4880 (also known as PGP). GnuPG allows to encrypt - and sign data and communication, features a versatile key management - system as well as access modules for public key directories. + as defined by RFC4880 (also known as PGP). GnuPG enables encryption + and signing of data and communication, and features a versatile key + management system as well as access modules for public key + directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications. A wealth of frontend - applications and libraries making use of GnuPG are available. Since - version 2 GnuPG provides support for S/MIME and Secure Shell in - addition to OpenPGP. + applications and libraries are available that make use of GnuPG. + Since version 2 GnuPG provides support for S/MIME and Secure Shell + in addition to OpenPGP. GnuPG is Free Software (meaning that it respects your freedom). It can be freely used, modified and distributed under the terms of the diff --git a/agent/command.c b/agent/command.c index e5d2268..1803b5f 100644 --- a/agent/command.c +++ b/agent/command.c @@ -3043,7 +3043,7 @@ io_monitor (assuan_context_t ctx, void *hook, int direction, (void) hook; - /* Note that we only check for the uppercase name. This allows to + /* Note that we only check for the uppercase name. This allows the user to see the logging for debugging if using a non-upercase command name. */ if (ctx && direction == ASSUAN_IO_FROM_PEER diff --git a/agent/keyformat.txt b/agent/keyformat.txt index c1a59ce..ddfb44b 100644 --- a/agent/keyformat.txt +++ b/agent/keyformat.txt @@ -324,7 +324,7 @@ similar to the private-key storage format. This is a master passphrase format where each file may protect several secrets under one master passphrase. It is possible to have several of those files each protected by a dedicated master passphrase. Clear text keywords -allow to list the available protected passphrases. +allow listing the available protected passphrases. The name of the files with these protected secrets have this form: pw-.dat. STRING may be an arbitrary string, as a default name diff --git a/common/i18n.c b/common/i18n.c index 39e3d8f..413fa9a 100644 --- a/common/i18n.c +++ b/common/i18n.c @@ -156,9 +156,9 @@ i18n_utf8 (const char *string) } -/* A variant of gettext which allows to specify the local to use for - translating the message. The function assumes that utf-8 is used - for the encoding. */ +/* A variant of gettext which allows the programmer to specify the + locale to use for translating the message. The function assumes + that utf-8 is used for the encoding. */ const char * i18n_localegettext (const char *lc_messages, const char *string) { diff --git a/common/iobuf.c b/common/iobuf.c index 9d582ca..06d0b61 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1198,7 +1198,7 @@ iobuf_cancel (iobuf_t a) #if defined(HAVE_W32_SYSTEM) || defined(__riscos__) if (remove_name) { - /* Argg, MSDOS does not allow to remove open files. So + /* Argg, MSDOS does not allow removing open files. So * we have to do it here */ #ifdef HAVE_W32CE_SYSTEM wchar_t *wtmp = utf8_to_wchar (remove_name); diff --git a/common/keyserver.h b/common/keyserver.h index 63dbde6..200378d 100644 --- a/common/keyserver.h +++ b/common/keyserver.h @@ -48,8 +48,8 @@ /* Must be 127 due to shell internal magic. */ #define KEYSERVER_SCHEME_NOT_FOUND 127 -/* Object to hold information pertaining to a keyserver; it further - allows to build a list of keyservers. Note that g10/options.h has +/* Object to hold information pertaining to a keyserver; it also + allows building a list of keyservers. Note that g10/options.h has a typedef for this. FIXME: We should make use of the parse_uri_t. */ struct keyserver_spec diff --git a/dirmngr/cdblib.c b/dirmngr/cdblib.c index 23cb317..52c17c9 100644 --- a/dirmngr/cdblib.c +++ b/dirmngr/cdblib.c @@ -296,7 +296,7 @@ cdb_find(struct cdb *cdbp, const void *key, cdbi_t klen) /* Sequential-find routines that used separate structure. It is possible to have many than one record with the same key in a - database, and these routines allows to enumerate all them. + database, and these routines allow enumeration of all of them. cdb_findinit() initializes search structure pointed to by cdbfp. It will return negative value on error or 0 on success. cdb_find? next() attempts to find next matching key, setting value position diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c index 55fcd8b..5fa3eac 100644 --- a/dirmngr/ldap-wrapper.c +++ b/dirmngr/ldap-wrapper.c @@ -545,8 +545,8 @@ reader_callback (void *cb_value, char *buffer, size_t count, size_t *nread) if (!buffer && !count && !nread) return -1; /* Rewind is not supported. */ - /* If we ever encountered a read error don't allow to continue and - possible overwrite the last error cause. Bail out also if the + /* If we ever encountered a read error, don't continue (we don't want to + possibly overwrite the last error cause). Bail out also if the file descriptor has been closed. */ if (ctx->fd_error || ctx->fd == -1) { diff --git a/doc/DETAILS b/doc/DETAILS index 4b3f0af..02f9bad 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -913,8 +913,8 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: *** FAILURE This is the counterpart to SUCCESS and used to indicate a program - failure. It is used similar to ISO-C's EXIT_FAILURE but allows to - convey more information, in particular an gpg-error error code. + failure. It is used similar to ISO-C's EXIT_FAILURE but allows + conveying more information, in particular a gpg-error error code. That numerical error code may optionally have a suffix made of an underscore and a string with an error symbol like "151011327_EOF". A dash may be used instead of . diff --git a/doc/TRANSLATE b/doc/TRANSLATE index 2a20aad..eb0de97 100644 --- a/doc/TRANSLATE +++ b/doc/TRANSLATE @@ -23,8 +23,8 @@ Help files GnuPG provides a little help feature (entering a ? on a prompt). This help used to be translated the usual way with gettext but it turned -out that this is too inflexible and does for example not allow to -correct little mistakes in the English text. For some newer features +out that this is too inflexible and does for example not allow +correcting little mistakes in the English text. For some newer features we require editable help files anyway and thus the existing help strings have been moved to plain text files names "help.LL.txt". We distribute these files and allow overriding them by files of that name diff --git a/doc/announce-2.1.txt b/doc/announce-2.1.txt index e165332..8c35e53 100644 --- a/doc/announce-2.1.txt +++ b/doc/announce-2.1.txt @@ -6,13 +6,13 @@ new release: Version 2.1.0. The GNU Privacy Guard (GnuPG) is a complete and free implementation of the OpenPGP standard as defined by RFC-4880 and better known as PGP. -GnuPG, also known as GPG, allows to encrypt and sign data and +GnuPG, also known as GPG, enables encryption and signing of data and communication, features a versatile key management system as well as access modules for public key directories. GnuPG itself is a command line tool with features for easy integration with other applications. -A wealth of frontend applications and libraries making use of GnuPG -are available. Since version 2 GnuPG provides support for S/MIME and -Secure Shell in addition to OpenPGP. +A wealth of frontend applications and libraries are available that +make use of GnuPG. Since version 2 GnuPG provides support for S/MIME +and Secure Shell in addition to OpenPGP. GnuPG is Free Software (meaning that it respects your freedom). It can be freely used, modified and distributed under the terms of the GNU diff --git a/doc/gpg.texi b/doc/gpg.texi index 3be401f..4d6a261 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2357,7 +2357,7 @@ obsolete; it does not harm to use it though. Revert to the pre-2.1 public key list mode. This only affects the human readable output and not the machine interface (i.e. @code{--with-colons}). Note that the legacy format does not -allow to convey suitable information for elliptic curves. +convey suitable information for elliptic curves. @item --with-fingerprint @opindex with-fingerprint diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 2f6c297..dae26b2 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -636,7 +636,7 @@ algorithm than actually used. @command{gpgsm} uses a one-pass data processing model and thus needs to rely on the announced digest algorithms to properly hash the data. As a workaround this option may be used to tell gpg to also hash the data using the algorithm - at var{name}; this slows processing down a little bit but allows to verify + at var{name}; this slows processing down a little bit but allows verification of such broken signatures. If @command{gpgsm} prints an error like ``digest algo 8 has not been enabled'' you may want to try this option, with @samp{SHA256} for @var{name}. @@ -1479,7 +1479,7 @@ GETAUDITLOG [--data] [--html] If @option{--data} is used, the audit log is send using D-lines instead of being sent to the file descriptor given by an OUTPUT -command. If @option{--html} is used, the output is formated as an +command. If @option{--html} is used, the output is formatted as an XHTML block. This is designed to be incorporated into a HTML document. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 5e53223..c145814 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -258,7 +258,7 @@ deprecated; it may be removed in future releases. @item --disable-ccid @opindex disable-ccid Disable the integrated support for CCID compliant readers. This -allows to fall back to one of the other drivers even if the internal +allows falling back to one of the other drivers even if the internal CCID driver can handle the reader. Note, that CCID support is only available if libusb was available at build time. @@ -284,10 +284,10 @@ To get a list of available CCID readers you may use this command: If @var{n} is not 0 and no client is actively using the card, the card will be powered down after @var{n} seconds. Powering down the card avoids a potential risk of damaging a card when used with certain -cheap readers. This also allows non Scdaemon aware applications to -access the card. The disadvantage of using a card timeout is that -accessing the card takes longer and that the user needs to enter the -PIN again after the next power up. +cheap readers. This also allows applications that are not aware of +Scdaemon to access the card. The disadvantage of using a card timeout +is that accessing the card takes longer and that the user needs to +enter the PIN again after the next power up. Note that with the current version of Scdaemon the card is powered down immediately at the next timer tick for any value of @var{n} other diff --git a/doc/tools.texi b/doc/tools.texi index e52d6a7..d6cf56e 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -234,7 +234,7 @@ commit the changes. @command{gpgconf} provides the backend of a configuration editor. The configuration editor would usually be a graphical user interface -program, that allows to display the current options, their default +program that displays the current options, their default values, and allows the user to make changes to the options. These changes can then be made active with @command{gpgconf} again. Such a program that uses @command{gpgconf} in this way will be called GUI @@ -999,9 +999,9 @@ This script is a wrapper around @command{gpgconf} to run it with the command @code{--apply-defaults} for all real users with an existing GnuPG home directory. Admins might want to use this script to update he GnuPG configuration files for all users after - at file{/etc/gnupg/gpgconf.conf} has been changed. This allows to enforce -certain policies for all users. Note, that this is not a bulletproof of -forcing a user to use certain options. A user may always directly edit + at file{/etc/gnupg/gpgconf.conf} has been changed. This allows enforcing +certain policies for all users. Note, that this is not a bulletproof way to +force a user to use certain options. A user may always directly edit the configuration files and bypass gpgconf. @noindent diff --git a/doc/whats-new-in-2.1.txt b/doc/whats-new-in-2.1.txt index dd29c66..19ed8b9 100644 --- a/doc/whats-new-in-2.1.txt +++ b/doc/whats-new-in-2.1.txt @@ -540,7 +540,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html key id matching the key id of another key. Importing a key with a long key id already used by another key in gpg???s local key store was not possible due to checks done on import. Now, if the ???wrong??? key - has been imported first /gpg/ would not allow to later import the + has been imported first /gpg/ would not allow later import of the second ???correct??? key. This problem has been fixed in 2.1 by allowing the import and by doing trial verification against all matching keys. diff --git a/g10/export.c b/g10/export.c index 92235fb..8c15868 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1925,7 +1925,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, continue; } - /* The agent does not yet allow to export v3 packets. It is + /* The agent does not yet allow export of v3 packets. It is actually questionable whether we should allow them at all. */ if (pk->version == 3) diff --git a/g10/getkey.c b/g10/getkey.c index 3fe8274..90083ba 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2514,7 +2514,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked, else if ((IS_UID_SIG (sig) || IS_UID_REV (sig)) && sig->timestamp >= sigdate) { - /* Note: we allow to invalidate cert revocations + /* Note: we allow invalidation of cert revocations * by a newer signature. An attacker can't use this * because a key should be revoked with a key revocation. * The reason why we have to allow for that is that at diff --git a/g10/import.c b/g10/import.c index b83f371..3c7edd7 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2020,7 +2020,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, #ifdef ENABLE_SELINUX_HACKS if (1) { - /* We don't allow to import secret keys because that may be used + /* We don't allow importing secret keys because that may be used to put a secret key into the keyring and the user might later be tricked into signing stuff with that key. */ log_error (_("importing secret keys not allowed\n")); diff --git a/g10/keyedit.c b/g10/keyedit.c index 9ebd643..4c833f8 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1338,7 +1338,7 @@ sign_uids (ctrl_t ctrl, estream_t fp, } /* Fixme: see whether there is a revocation in which - * case we should allow to sign it again. */ + * case we should allow signing it again. */ if (!node->pkt->pkt.signature->flags.exportable && local) tty_fprintf ( fp, _("\"%s\" was already locally signed by key %s\n"), diff --git a/m4/ksba.m4 b/m4/ksba.m4 index 73b2e26..3e14e67 100644 --- a/m4/ksba.m4 +++ b/m4/ksba.m4 @@ -13,11 +13,11 @@ dnl AM_PATH_KSBA([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed +dnl MINIMUM-VERSION is a string with the version number optionalliy prefixed dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.0.7 won't pass the test unless the installed +dnl a MINIMUM-VERSION of 1:1.0.7 won't pass the test unless the installed dnl version of libksba is at least 1.0.7 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libksba +dnl this feature prevents building against newer versions of libksba dnl with a changed API. dnl AC_DEFUN([AM_PATH_KSBA], diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 index c67cfec..d89fe11 100644 --- a/m4/libgcrypt.m4 +++ b/m4/libgcrypt.m4 @@ -15,11 +15,11 @@ dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed +dnl MINIMUM-VERSION is a string with the version number optionalliy prefixed dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed +dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libgcrypt +dnl this feature prevents building against newer versions of libgcrypt dnl with a changed API. dnl dnl If a prefix option is not used, the config script is first diff --git a/m4/ntbtls.m4 b/m4/ntbtls.m4 index 85c8ee9..0a30d92 100644 --- a/m4/ntbtls.m4 +++ b/m4/ntbtls.m4 @@ -14,11 +14,11 @@ dnl AM_PATH_NTBTLS([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl dnl Test for NTBTLS and define NTBTLS_CFLAGS and NTBTLS_LIBS. -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed +dnl MINIMUM-VERSION is a string with the version number optionalliy prefixed dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed -dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libgcrypt +dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed +dnl version of ntbtls is at least 1.2.5 *and* the API number is 1. Using +dnl this feature prevents building against newer versions of ntbtls dnl with a changed API. dnl AC_DEFUN([AM_PATH_NTBTLS], diff --git a/po/ca.po b/po/ca.po index 086ac26..633fc3c 100644 --- a/po/ca.po +++ b/po/ca.po @@ -8756,7 +8756,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/cs.po b/po/cs.po index 96bb049..ef00cd1 100644 --- a/po/cs.po +++ b/po/cs.po @@ -8257,7 +8257,7 @@ msgstr "|N| nastavit maxim??ln?? ??ivotnost kl?????? SSH na N sekund" msgid "Options enforcing a passphrase policy" msgstr "Volby vynucuj??c?? politiku hesel" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "nedovolit obej??t politiku hesel" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/da.po b/po/da.po index 2f8fb37..edc95da 100644 --- a/po/da.po +++ b/po/da.po @@ -8774,7 +8774,7 @@ msgstr "|N|angive maksimal livsforl??b for SSH-n??gle til N sekunder" msgid "Options enforcing a passphrase policy" msgstr "Tilvalg der fremtvinger en adgangsfrasepolitik" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "tillad ikke omg??else af adgangsfrasepolitikken" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/de.po b/po/de.po index f341c5f..c8748fe 100644 --- a/po/de.po +++ b/po/de.po @@ -8322,7 +8322,7 @@ msgstr "|N|setze die maximale Lebenszeit von SSH Schl??sseln auf N Sekunden" msgid "Options enforcing a passphrase policy" msgstr "Optionen f??r eine Passphrase-Policy" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "Einhaltung der Passphrase-Policy erzwingen" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/el.po b/po/el.po index 0160ccb..9e0cc10 100644 --- a/po/el.po +++ b/po/el.po @@ -8572,7 +8572,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/eo.po b/po/eo.po index 958c534..7b9921b 100644 --- a/po/eo.po +++ b/po/eo.po @@ -8515,7 +8515,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/es.po b/po/es.po index 5e374f5..4cbfd2e 100644 --- a/po/es.po +++ b/po/es.po @@ -8801,7 +8801,7 @@ msgstr "|N|establecer vida m msgid "Options enforcing a passphrase policy" msgstr "Opciones que fuerzan una pol?tica de frases contrase?a" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "no permitir evitar la pol?tica de frases contrase?a" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/et.po b/po/et.po index 5d9dcf3..c0534d9 100644 --- a/po/et.po +++ b/po/et.po @@ -8489,7 +8489,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/fi.po b/po/fi.po index 414f99b..0fe5521 100644 --- a/po/fi.po +++ b/po/fi.po @@ -8552,7 +8552,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/fr.po b/po/fr.po index c4b6e4d..af39a5c 100644 --- a/po/fr.po +++ b/po/fr.po @@ -8490,7 +8490,7 @@ msgstr "|N|d??finir la dur??e maximale du cache de clef SSH ?? N??secondes" msgid "Options enforcing a passphrase policy" msgstr "Options d'application d'une politique de phrase secr??te" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "pas de contournement de politique de phrase secr??te" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/gl.po b/po/gl.po index c8c5a26..c892f28 100644 --- a/po/gl.po +++ b/po/gl.po @@ -8576,7 +8576,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/hu.po b/po/hu.po index 8505a8f..392ac37 100644 --- a/po/hu.po +++ b/po/hu.po @@ -8522,7 +8522,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/id.po b/po/id.po index f1fbc44..452dccd 100644 --- a/po/id.po +++ b/po/id.po @@ -8511,7 +8511,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/it.po b/po/it.po index 3a0572b..a5cf128 100644 --- a/po/it.po +++ b/po/it.po @@ -8555,7 +8555,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/ja.po b/po/ja.po index 51cfc72..5f94814 100644 --- a/po/ja.po +++ b/po/ja.po @@ -7974,7 +7974,7 @@ msgstr "|N|??????SSH??????????????????N????????????" msgid "Options enforcing a passphrase policy" msgstr "??????????????????????????????????????????????????????" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "??????????????????????????????????????????????????????????????????" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/nb.po b/po/nb.po index db163f2..12bfd13 100644 --- a/po/nb.po +++ b/po/nb.po @@ -8090,7 +8090,7 @@ msgstr "|N|endre maksimal livstid for SSH-n??kler til N antall sekunder" msgid "Options enforcing a passphrase policy" msgstr "Valg som h??ndhever passordfrase-regler" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "ikke tillat overstyring av passordfrase-regler" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/pl.po b/po/pl.po index 74cd6d9..75822e4 100644 --- a/po/pl.po +++ b/po/pl.po @@ -8837,7 +8837,7 @@ msgstr "|N|ustawienie maksymalnego czasu msgid "Options enforcing a passphrase policy" msgstr "Opcje wymuszaj?ce polityk? hase?" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "nie zezwalanie na pomini?cie polityki hase?" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/pt.po b/po/pt.po index beee02b..63c6cec 100644 --- a/po/pt.po +++ b/po/pt.po @@ -8524,7 +8524,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/ro.po b/po/ro.po index 71435aa..dffe008 100644 --- a/po/ro.po +++ b/po/ro.po @@ -8586,7 +8586,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/ru.po b/po/ru.po index 57c4045..f36a27c 100644 --- a/po/ru.po +++ b/po/ru.po @@ -8195,7 +8195,7 @@ msgstr "|N|???????????????????? ???????????????????????? ???????? ?????????????? msgid "Options enforcing a passphrase policy" msgstr "??????????????????, ???????????????????????????? ?????????????? ?????? ????????-??????????????" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "???? ?????????????????? ???????????????? ?????????????? ?????? ????????-??????????????" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/sk.po b/po/sk.po index 8dda2be..d5e8692 100644 --- a/po/sk.po +++ b/po/sk.po @@ -8541,7 +8541,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/sv.po b/po/sv.po index 5c41560..8ff4dbf 100644 --- a/po/sv.po +++ b/po/sv.po @@ -8917,7 +8917,7 @@ msgstr "|N|st??ll in maximal livstid f??r SSH-nyckel till N sekunder" msgid "Options enforcing a passphrase policy" msgstr "Flaggor som tvingar igenom en l??senfraspolicy" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "till??t inte att g?? f??rbi l??senfraspolicyn" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/tr.po b/po/tr.po index 6e661b5..1eae9b4 100644 --- a/po/tr.po +++ b/po/tr.po @@ -8819,7 +8819,7 @@ msgstr "|N|azami SSH anahtar?? ??mr?? N saniyeye ayarlan??r" msgid "Options enforcing a passphrase policy" msgstr "Bir anahtar parolas?? kural??n?? zorlayan se??enekler" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "anahtar parolas?? kural??n??n atlanmas??na izin verilmez" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/uk.po b/po/uk.po index 97442c8..ac57ed4 100644 --- a/po/uk.po +++ b/po/uk.po @@ -8299,7 +8299,7 @@ msgstr "|N|???????????????????? ???????????????????????? ?????????? ?????? ???? msgid "Options enforcing a passphrase policy" msgstr "?????????????????? ?????????????????????? ???????????????????????? ???????????? ??????????????" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "???? ?????????????????? ?????????? ???????????? ??????????????" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/zh_CN.po b/po/zh_CN.po index 41613c7..27f88bb 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -8410,7 +8410,7 @@ msgstr "" msgid "Options enforcing a passphrase policy" msgstr "" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "" msgid "|N|set minimal required length for new passphrases to N" diff --git a/po/zh_TW.po b/po/zh_TW.po index d9a4bb8..9438e3d 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -8039,7 +8039,7 @@ msgstr "|N|??? SSH ?????????????????????????????? N ???" msgid "Options enforcing a passphrase policy" msgstr "?????????????????????????????????" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "???????????????????????????" msgid "|N|set minimal required length for new passphrases to N" diff --git a/scd/app-p15.c b/scd/app-p15.c index e4d9de0..12254ab 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -2935,8 +2935,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, /* Due to the fact that the non-repudiation signature on a BELPIC card requires a verify immediately before the DSO we set the - MSE before we do the verification. Other cards might allow to do - this also but I don't want to break anything, thus we do it only + MSE before we do the verification. Other cards might also allow + this but I don't want to break anything, thus we do it only for the BELPIC card here. */ if (app->app_local->card_type == CARD_TYPE_BELPIC) { diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 7a093f6..b1523cb 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -2980,7 +2980,7 @@ ccid_transceive (ccid_driver_t handle, nresp = &dummy_nresp; *nresp = 0; - /* Smarter readers allow to send APDUs directly; divert here. */ + /* Smarter readers allow sending APDUs directly; divert here. */ if (handle->apdu_level) { /* We employ a hack for Omnikey readers which are able to send diff --git a/scd/command.c b/scd/command.c index d90c320..239480b 100644 --- a/scd/command.c +++ b/scd/command.c @@ -499,7 +499,7 @@ static const char hlp_serialno[] = "error is returned if the application is not supported or available.\n" "The default is to auto-select the application using a hardwired\n" "preference system. Note, that a future extension to this function\n" - "may allow to specify a list and order of applications to try.\n" + "may enable specifying a list and order of applications to try.\n" "\n" "This function is special in that it can be used to reset the card.\n" "Most other functions will return an error when a card change has\n" diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 9b7dd4b..b64072e 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1681,7 +1681,7 @@ main ( int argc, char **argv) /* Build the recipient list. We first add the regular ones and then the encrypt-to ones because the underlying function will silently - ignore duplicates and we can't allow to keep a duplicate which is + ignore duplicates and we can't allow keeping a duplicate which is flagged as encrypt-to as the actually encrypt function would then complain about no (regular) recipients. */ for (sl = remusr; sl; sl = sl->next) @@ -1785,7 +1785,7 @@ main ( int argc, char **argv) { estream_t fp = open_es_fwrite (opt.outfile?opt.outfile:"-"); - /* Fixme: We should also allow to concatenate multiple files for + /* Fixme: We should also allow concatenation of multiple files for signing because that is what gpg does.*/ set_binary (stdin); if (!argc) /* Create from stdin. */ diff --git a/sm/sign.c b/sm/sign.c index 08eebb7..6cb1f86 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -109,7 +109,7 @@ hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer) es_fclose (fp); if (!any) { - /* We can't allow to sign an empty message because it does not + /* We can't allow signing an empty message because it does not make much sense and more seriously, ksba_cms_build has already written the tag for data and now expects an octet string and an octet string of size 0 is illegal. */ diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 3d456a9..82b5325 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -560,7 +560,7 @@ static gc_option_t gc_options_gpg_agent[] = "gnupg", N_("Options enforcing a passphrase policy") }, { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT, "gnupg", - N_("do not allow to bypass the passphrase policy"), + N_("do not allow bypassing the passphrase policy"), GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, { "min-passphrase-len", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", @@ -3736,7 +3736,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults, if (defaults) { - /* Here we explicitly allow to update the value again. */ + /* Here we explicitly allow updating the value again. */ if (newflags) { option_info->new_flags = 0; diff --git a/tools/gpgtar.h b/tools/gpgtar.h index 3f21ea1..7d03719 100644 --- a/tools/gpgtar.h +++ b/tools/gpgtar.h @@ -103,7 +103,7 @@ struct tar_header_s unsigned long long mtime; /* Modification time since Epoch. Note that we don't use time_t here but a type which is more likely to be larger - that 32 bit and thus allows to track + that 32 bit and thus allows tracking times beyond 2106. */ typeflag_t typeflag; /* The type of the file. */ commit 436b28c23194fa77919967338d5a61a82d242153 Author: Daniel Kahn Gillmor Date: Mon Aug 1 22:19:16 2016 -0400 dirmngr: Emit correct spelling of "superseded". * dirmngr/crlcache.c (list_one_crl_entry): Spell superseded correctly. * dirmngr/ocsp.c (ocsp_invalid): Likewise. This might break some tools which parse the existing output and expect misspellings, but i'm not sure there are many such tools, and we should use standardized orthography going forward. Signed-off-by: Daniel Kahn Gillmor diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 25ce7a6..af2a956 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -2361,7 +2361,7 @@ list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp) if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED ) es_fputs( "affiliation_changed ", fp ), any = 1; if (reason & KSBA_CRLREASON_SUPERSEDED ) - es_fputs( "superseeded", fp ), any = 1; + es_fputs( "superseded", fp ), any = 1; if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION ) es_fputs( "cessation_of_operation", fp ), any = 1; if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD ) diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index e123409..561b7d7 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -716,7 +716,7 @@ ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr, reason == KSBA_CRLREASON_CA_COMPROMISE? "CA compromise": reason == KSBA_CRLREASON_AFFILIATION_CHANGED? "affiliation changed": - reason == KSBA_CRLREASON_SUPERSEDED? "superseeded": + reason == KSBA_CRLREASON_SUPERSEDED? "superseded": reason == KSBA_CRLREASON_CESSATION_OF_OPERATION? "cessation of operation": reason == KSBA_CRLREASON_CERTIFICATE_HOLD? commit cd45cf782b91ff0f6b023913963e5258ffcbf464 Author: Daniel Kahn Gillmor Date: Mon Aug 1 22:19:15 2016 -0400 Fix spelling and grammar. * agent/learncard.c: s/coccured/occurred/ * doc/dirmngr.texi: s/ommitted/omitted/, s/orginally/originally/, s/reponses/responses/i * doc/gpg-agent.texi, doc/dirmngr.texi, doc/gpg.texi: Fix "allows to" to more conventional english usage. * doc/tools.texi, g10/gpgcommpose.c, tests/openpgp/armor.scm, tests/openpgp/armor.test: s/occured/occurred/ * tools/gpgsplit.c: s/calcualting/calculating/ * sm/server.c: s/formated/formatted/ Signed-off-by: Daniel Kahn Gillmor diff --git a/agent/learncard.c b/agent/learncard.c index e0f2340..e9304fb 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -133,7 +133,7 @@ kpinfo_cb (void *opaque, const char *line) char *p; if (parm->error) - return; /* no need to gather data after an error coccured */ + return; /* no need to gather data after an error occurred */ if ((parm->error = agent_write_status (parm->ctrl, "PROGRESS", "learncard", "k", "0", "0", NULL))) @@ -190,7 +190,7 @@ certinfo_cb (void *opaque, const char *line) char *p, *pend; if (parm->error) - return; /* no need to gather data after an error coccured */ + return; /* no need to gather data after an error occurred */ if ((parm->error = agent_write_status (parm->ctrl, "PROGRESS", "learncard", "c", "0", "0", NULL))) @@ -232,7 +232,7 @@ sinfo_cb (void *opaque, const char *keyword, size_t keywordlen, SINFO item; if (sparm->error) - return; /* no need to gather data after an error coccured */ + return; /* no need to gather data after an error occurred */ item = xtrycalloc (1, sizeof *item + keywordlen + 1 + strlen (data)); if (!item) diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index e87442f..033b5d3 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -321,9 +321,9 @@ whether @option{--honor-http-proxy} has been set. @item --ldap-proxy @var{host}[:@var{port}] @opindex ldap-proxy Use @var{host} and @var{port} to connect to LDAP servers. If @var{port} -is ommitted, port 389 (standard LDAP port) is used. This overrides any +is omitted, port 389 (standard LDAP port) is used. This overrides any specified host and port part in a LDAP URL and will also be used if host -and port have been ommitted from the URL. +and port have been omitted from the URL. @item --only-ldap-proxy @opindex only-ldap-proxy @@ -346,12 +346,12 @@ This server list file contains one LDAP server per line in the format Lines starting with a @samp{#} are comments. Note that as usual all strings entered are expected to be UTF-8 encoded. -Obviously this will lead to problems if the password has orginally been +Obviously this will lead to problems if the password has originally been encoded as Latin-1. There is no other solution here than to put such a password in the binary encoding into the file (i.e. non-ascii characters won't show up readable). at footnote{The @command{gpgconf} tool might be -helpful for frontends as it allows to edit this configuration file using -percent escaped strings.} +helpful for frontends as it enables editing this configuration file using +percent-escaped strings.} @item --ldaptimeout @var{secs} @@ -474,7 +474,7 @@ In the deprecated system daemon mode the second directory is used instead. @item /etc/gnupg/trusted-certs This directory should be filled with certificates of Root CAs you -are trusting in checking the CRLs and signing OCSP Reponses. +are trusting in checking the CRLs and signing OCSP Responses. Usually these are the same certificates you use with the applications making use of dirmngr. It is expected that each of these certificate @@ -496,7 +496,7 @@ This directory may contain extra certificates which are preloaded into the interal cache on startup. Applications using dirmngr (e.g. gpgsm) can request cached certificates to complete a trust chain. This is convenient in cases you have a couple intermediate CA certificates -or certificates ususally used to sign OCSP reponses. +or certificates ususally used to sign OCSP responses. These certificates are first tried before going out to the net to look for them. These certificates must also be @acronym{DER} encoded and suffixed with @file{.crt} or @file{.der}. diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index cd5d751..b481dd6 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -540,8 +540,8 @@ Also listen on native gpg-agent connections on the given socket. The intended use for this extra socket is to setup a Unix domain socket forwarding from a remote machine to this socket on the local machine. A @command{gpg} running on the remote machine may then connect to the -local gpg-agent and use its private keys. This allows to decrypt or -sign data on a remote machine without exposing the private keys to the +local gpg-agent and use its private keys. This enables decrypting or +signing data on a remote machine without exposing the private keys to the remote machine. @@ -633,7 +633,7 @@ agent. By default they may all be found in the current home directory lines are ignored. To mark a key as trusted you need to enter its fingerprint followed by a space and a capital letter @code{S}. Colons may optionally be used to separate the bytes of a fingerprint; this - allows to cut and paste the fingerprint from a key listing output. If + enables cutting and pasting the fingerprint from a key listing output. If the line is prefixed with a @code{!} the key is explicitly marked as not trusted. @@ -1041,8 +1041,8 @@ Here is an example session: @subsection Generating a Key This is used to create a new keypair and store the secret key inside the -active PSE --- which is in most cases a Soft-PSE. An not yet defined -option allows to choose the storage location. To get the secret key out +active PSE --- which is in most cases a Soft-PSE. A not-yet-defined +option allows choosing the storage location. To get the secret key out of the PSE, a special export tool has to be used. @example diff --git a/doc/gpg.texi b/doc/gpg.texi index 38f417e..3be401f 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1678,7 +1678,7 @@ mechanisms, in the order they are to be tried: may be used here to query that particular keyserver. @item local - Locate the key using the local keyrings. This mechanism allows to + Locate the key using the local keyrings. This mechanism allows the user to select the order a local key lookup is done. Thus using @samp{--auto-key-locate local} is identical to @option{--no-auto-key-locate}. @@ -2110,7 +2110,7 @@ Use @var{name} as the key to sign with. Note that this option overrides @opindex try-secret-key For hidden recipients GPG needs to know the keys to use for trial decryption. The key set with @option{--default-key} is always tried -first, but this is often not sufficient. This option allows to set more +first, but this is often not sufficient. This option allows setting more keys to be used for trial decryption. Although any valid user-id specification may be used for @var{name} it makes sense to use at least the long keyid to avoid ambiguities. Note that gpg-agent might pop up a @@ -2791,7 +2791,7 @@ to display the message. This option overrides @option{--set-filename}. @itemx --no-use-embedded-filename @opindex use-embedded-filename Try to create a file with a name as embedded in the data. This can be -a dangerous option as it allows to overwrite files. Defaults to no. +a dangerous option as it enables overwriting files. Defaults to no. @item --cipher-algo @code{name} @opindex cipher-algo diff --git a/doc/tools.texi b/doc/tools.texi index 577df8e..e52d6a7 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -1749,7 +1749,7 @@ The possible exit status codes of @command{symcryptrun} are: @item 0 Success. @item 1 - Some error occured. + Some error occurred. @item 2 No valid passphrase was provided. @item 3 diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index cd5346f..e3bb013 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -1317,7 +1317,7 @@ sig_notation (const char *option, int argc, char *argv[], void *cookie) else notation = string_to_notation (p, 1); if (! notation) - log_fatal ("creating notation: an unknown error occured.\n"); + log_fatal ("creating notation: an unknown error occurred.\n"); notation->next = si->notations; si->notations = notation; diff --git a/sm/server.c b/sm/server.c index 8b4a29c..cdccff3 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1039,7 +1039,7 @@ static const char hlp_getauditlog[] = "If --data is used, the output is send using D-lines and not to the\n" "file descriptor given by an OUTPUT command.\n" "\n" - "If --html is used the output is formated as an XHTML block. This is\n" + "If --html is used the output is formatted as an XHTML block. This is\n" "designed to be incorporated into a HTML document."; static gpg_error_t cmd_getauditlog (assuan_context_t ctx, char *line) diff --git a/tests/openpgp/armor.scm b/tests/openpgp/armor.scm index 5b4ea14..578e248 100755 --- a/tests/openpgp/armor.scm +++ b/tests/openpgp/armor.scm @@ -749,7 +749,7 @@ wg7Md81a5RI3F2FG8747t9gX ") ;; Bug 1179 solved 2010-05-12: -;; It occured for messages of a multiple of the iobuf block size where +;; It occurred for messages of a multiple of the iobuf block size where ;; the last line had no pad character. Due to premature poppng of thea ;; rmor filter gpg swalled the CRC line and passed the '-----END...' ;; line on to the decryption layer. diff --git a/tests/openpgp/armor.test b/tests/openpgp/armor.test index ce5939c..72831e3 100755 --- a/tests/openpgp/armor.test +++ b/tests/openpgp/armor.test @@ -742,7 +742,7 @@ wg7Md81a5RI3F2FG8747t9gX ' # Bug 1179 solved 2010-05-12: -# It occured for messages of a multiple of the iobuf block size where +# It occurred for messages of a multiple of the iobuf block size where # the last line had no pad character. Due to premature poppng of thea # rmor filter gpg swalled the CRC line and passed the '-----END...' # line on to the decryption layer. diff --git a/tools/gpgsplit.c b/tools/gpgsplit.c index 2451ab3..93dd8ed 100644 --- a/tools/gpgsplit.c +++ b/tools/gpgsplit.c @@ -577,7 +577,7 @@ write_part (FILE *fpin, unsigned long pktlen, len = public_key_length (blob, pktlen); if (!len) { - log_error ("error calcualting public key length\n"); + log_error ("error calculating public key length\n"); g10_exit (1); } if ( (hdr[0] & 0x40) ) ----------------------------------------------------------------------- Summary of changes: README | 13 +++++++------ agent/command.c | 2 +- agent/keyformat.txt | 2 +- agent/learncard.c | 6 +++--- common/i18n.c | 6 +++--- common/iobuf.c | 2 +- common/keyserver.h | 4 ++-- dirmngr/cdblib.c | 2 +- dirmngr/crlcache.c | 2 +- dirmngr/ldap-wrapper.c | 4 ++-- dirmngr/ocsp.c | 2 +- doc/DETAILS | 4 ++-- doc/TRANSLATE | 4 ++-- doc/announce-2.1.txt | 8 ++++---- doc/dirmngr.texi | 14 +++++++------- doc/gpg-agent.texi | 10 +++++----- doc/gpg.texi | 8 ++++---- doc/gpgsm.texi | 4 ++-- doc/scdaemon.texi | 10 +++++----- doc/tools.texi | 10 +++++----- doc/whats-new-in-2.1.txt | 2 +- g10/export.c | 2 +- g10/getkey.c | 2 +- g10/gpgcompose.c | 2 +- g10/import.c | 2 +- g10/keyedit.c | 2 +- kbx/keybox-update.c | 1 + m4/ksba.m4 | 6 +++--- m4/libgcrypt.m4 | 6 +++--- m4/ntbtls.m4 | 8 ++++---- po/ca.po | 2 +- po/cs.po | 2 +- po/da.po | 2 +- po/de.po | 2 +- po/el.po | 2 +- po/eo.po | 2 +- po/es.po | 2 +- po/et.po | 2 +- po/fi.po | 2 +- po/fr.po | 2 +- po/gl.po | 2 +- po/hu.po | 2 +- po/id.po | 2 +- po/it.po | 2 +- po/ja.po | 2 +- po/nb.po | 2 +- po/pl.po | 2 +- po/pt.po | 2 +- po/ro.po | 2 +- po/ru.po | 2 +- po/sk.po | 2 +- po/sv.po | 2 +- po/tr.po | 2 +- po/uk.po | 2 +- po/zh_CN.po | 2 +- po/zh_TW.po | 2 +- scd/app-p15.c | 4 ++-- scd/ccid-driver.c | 2 +- scd/command.c | 2 +- sm/gpgsm.c | 4 ++-- sm/server.c | 2 +- sm/sign.c | 2 +- tests/openpgp/armor.scm | 2 +- tests/openpgp/armor.test | 2 +- tools/gpgconf-comp.c | 4 ++-- tools/gpgsplit.c | 2 +- tools/gpgtar.h | 2 +- 67 files changed, 116 insertions(+), 114 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 09:29:17 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 04 Aug 2016 09:29:17 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-39-g6f284e6 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 6f284e6ed63f514b15fe610f490ffcefc87a2164 (commit) from 993f36e23cf8c2216a40d3e51b922a1edd871e1b (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 6f284e6ed63f514b15fe610f490ffcefc87a2164 Author: NIIBE Yutaka Date: Thu Aug 4 16:21:39 2016 +0900 g10: Fix checking key for signature validation. * g10/sig-check.c (check_signature2): Not only subkey, but also primary key should have flags.valid=1. -- The tweak of gpgv in e32c575e0f3704e7563048eea6d26844bdfc494b only makes sense with this change. Signed-off-by: NIIBE Yutaka diff --git a/g10/sig-check.c b/g10/sig-check.c index 7000b48..334add7 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -118,9 +118,9 @@ check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, } else if( get_pubkey( pk, sig->keyid ) ) rc = GPG_ERR_NO_PUBKEY; - else if(!pk->flags.valid && !pk->flags.primary) + else if(!pk->flags.valid) { - /* You cannot have a good sig from an invalid subkey. */ + /* You cannot have a good sig from an invalid key. */ rc = GPG_ERR_BAD_PUBKEY; } else ----------------------------------------------------------------------- Summary of changes: g10/sig-check.c | 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 Thu Aug 4 10:03:13 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 04 Aug 2016 10:03:13 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-40-g573e0f3 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 573e0f36190346e0263bea3ae12a389f4f598d55 (commit) from 6f284e6ed63f514b15fe610f490ffcefc87a2164 (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 573e0f36190346e0263bea3ae12a389f4f598d55 Author: NIIBE Yutaka Date: Thu Aug 4 17:02:20 2016 +0900 po: update Japanese translation. diff --git a/po/ja.po b/po/ja.po index 5f94814..35482a3 100644 --- a/po/ja.po +++ b/po/ja.po @@ -8,9 +8,9 @@ # msgid "" msgstr "" -"Project-Id-Version: gnupg 2.1.12\n" +"Project-Id-Version: gnupg 2.1.15\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2016-06-07 14:12+0900\n" +"PO-Revision-Date: 2016-08-04 16:38+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -432,10 +432,6 @@ msgid "error binding socket to '%s': %s\n" msgstr "'%s'??????????????: %s\n" #, c-format -msgid "can't set permissions of '%s': %s\n" -msgstr "'%s'???????????: %s\n" - -#, c-format msgid "listen() failed: %s\n" msgstr "listen() ???????: %s\n" @@ -452,6 +448,10 @@ msgid "directory '%s' created\n" msgstr "??????'%s'????????\n" #, c-format +msgid "can't set permissions of '%s': %s\n" +msgstr "'%s'???????????: %s\n" + +#, c-format msgid "stat() failed for '%s': %s\n" msgstr "'%s'?stat()???????: %s\n" @@ -1652,14 +1652,6 @@ msgstr "??????????????????" msgid " - skipped" msgstr " - ?????????" -#, c-format -msgid "writing to '%s'\n" -msgstr "'%s'??????\n" - -#, c-format -msgid "key %s: key material on-card - skipped\n" -msgstr "?%s: ??????????? - ???????\n" - msgid "exporting secret keys not allowed\n" msgstr "??????????????????\n" @@ -1667,6 +1659,10 @@ msgstr "??????????????????\n" msgid "key %s: PGP 2.x style key - skipped\n" msgstr "?%s: PGP 2.x?????? - ???????\n" +#, c-format +msgid "key %s: key material on-card - skipped\n" +msgstr "?%s: ??????????? - ???????\n" + msgid "WARNING: nothing exported\n" msgstr "*??*: ???????????????\n" @@ -1773,11 +1769,6 @@ msgstr "?????????????" msgid "quickly add a new user-id" msgstr "??????????ID???" -#, fuzzy -#| msgid "quickly add a new user-id" -msgid "quickly revoke a user-id" -msgstr "??????????ID???" - msgid "full featured key pair generation" msgstr "??????????" @@ -1811,13 +1802,13 @@ msgstr "?????????" msgid "export keys" msgstr "??????????" -msgid "export keys to a keyserver" +msgid "export keys to a key server" msgstr "???????????????" -msgid "import keys from a keyserver" +msgid "import keys from a key server" msgstr "???????????????" -msgid "search for keys on a keyserver" +msgid "search for keys on a key server" msgstr "???????????" msgid "update all keys from a keyserver" @@ -2034,340 +2025,6 @@ msgstr "?????????????????" msgid "show expiration dates during signature listings" msgstr "???????????????????" -msgid "available TOFU policies:\n" -msgstr "?????TOFU????:\n" - -#, c-format -msgid "unknown TOFU policy '%s'\n" -msgstr "???TOFU????'%s'\n" - -msgid "(use \"help\" to list choices)\n" -msgstr "(????????\"help\"????????)\n" - -#, c-format -msgid "unknown TOFU DB format '%s'\n" -msgstr "???TOFU DB??????'%s'\n" - -#, c-format -msgid "Note: old default options file '%s' ignored\n" -msgstr "*??*: ????????????????????'%s'????????\n" - -#, c-format -msgid "libgcrypt is too old (need %s, have %s)\n" -msgstr "libgcrypt ?????? (?? %s, ?? %s)\n" - -#, c-format -msgid "Note: %s is not for normal use!\n" -msgstr "*??*: ??%s??????!\n" - -#, c-format -msgid "'%s' is not a valid signature expiration\n" -msgstr "'%s'????????????????\n" - -#, c-format -msgid "invalid pinentry mode '%s'\n" -msgstr "??? pinentry mode '%s'??\n" - -#, c-format -msgid "'%s' is not a valid character set\n" -msgstr "'%s'????????????????\n" - -msgid "could not parse keyserver URL\n" -msgstr "?????URL?????\n" - -#, c-format -msgid "%s:%d: invalid keyserver options\n" -msgstr "%s:%d: ???????????????\n" - -msgid "invalid keyserver options\n" -msgstr "???????????????\n" - -#, c-format -msgid "%s:%d: invalid import options\n" -msgstr "%s:%d: ????????????????\n" - -msgid "invalid import options\n" -msgstr "????????????????\n" - -#, fuzzy, c-format -#| msgid "invalid list options\n" -msgid "invalid filter option: %s\n" -msgstr "????????????\n" - -#, c-format -msgid "%s:%d: invalid export options\n" -msgstr "%s:%d: ?????????????????\n" - -msgid "invalid export options\n" -msgstr "?????????????????\n" - -#, c-format -msgid "%s:%d: invalid list options\n" -msgstr "%s:%d: ????????????\n" - -msgid "invalid list options\n" -msgstr "????????????\n" - -msgid "display photo IDs during signature verification" -msgstr "??????????ID?????" - -msgid "show policy URLs during signature verification" -msgstr "???????????URL?????" - -msgid "show all notations during signature verification" -msgstr "??????????????????" - -msgid "show IETF standard notations during signature verification" -msgstr "???????IETF?????????" - -msgid "show user-supplied notations during signature verification" -msgstr "??????????????????" - -msgid "show preferred keyserver URLs during signature verification" -msgstr "?????????????URL?????" - -msgid "show user ID validity during signature verification" -msgstr "??????????ID?????????" - -msgid "show revoked and expired user IDs in signature verification" -msgstr "??????????????ID????????????ID?????" - -msgid "show only the primary user ID in signature verification" -msgstr "????????????ID????????" - -msgid "validate signatures with PKA data" -msgstr "PKA???????????" - -msgid "elevate the trust of signatures with valid PKA data" -msgstr "???PKA????????????????" - -#, c-format -msgid "%s:%d: invalid verify options\n" -msgstr "%s:%d: ????????????\n" - -msgid "invalid verify options\n" -msgstr "????????????\n" - -#, c-format -msgid "unable to set exec-path to %s\n" -msgstr "exec-path?%s?????\n" - -#, c-format -msgid "%s:%d: invalid auto-key-locate list\n" -msgstr "%s:%d: ??? auto-key-locate ?????\n" - -msgid "invalid auto-key-locate list\n" -msgstr "??? auto-key-locate ?????\n" - -msgid "WARNING: program may create a core file!\n" -msgstr "*??*: ??????core????????????????!\n" - -#, c-format -msgid "WARNING: %s overrides %s\n" -msgstr "*??*: %s?%s????\n" - -#, c-format -msgid "%s not allowed with %s!\n" -msgstr "%s?%s??????????????!\n" - -#, c-format -msgid "%s makes no sense with %s!\n" -msgstr "%s?%s?????????????!\n" - -msgid "WARNING: running with faked system time: " -msgstr "*??*: ???????????????????: " - -#, c-format -msgid "will not run with insecure memory due to %s\n" -msgstr "%s ?????????????????????\n" - -msgid "selected cipher algorithm is invalid\n" -msgstr "???????????????????\n" - -msgid "selected digest algorithm is invalid\n" -msgstr "????????????????????????\n" - -msgid "selected compression algorithm is invalid\n" -msgstr "???????????????????\n" - -msgid "selected certification digest algorithm is invalid\n" -msgstr "???????????????????????????\n" - -msgid "completes-needed must be greater than 0\n" -msgstr "completes-needed?????????\n" - -msgid "marginals-needed must be greater than 1\n" -msgstr "marginals-needed?1???????????\n" - -msgid "max-cert-depth must be in the range from 1 to 255\n" -msgstr "max-cert-depth?1??255?????????????\n" - -msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" -msgstr "???default-cert-level?0?1?2?3??????????\n" - -msgid "invalid min-cert-level; must be 1, 2, or 3\n" -msgstr "???min-cert-level?0?1?2?3??????????\n" - -msgid "Note: simple S2K mode (0) is strongly discouraged\n" -msgstr "*??*: ???S2K???(0)????????????\n" - -msgid "invalid S2K mode; must be 0, 1 or 3\n" -msgstr "???S2K????0?1?3??????????\n" - -msgid "invalid default preferences\n" -msgstr "?????????????\n" - -msgid "invalid personal cipher preferences\n" -msgstr "???????????????\n" - -msgid "invalid personal digest preferences\n" -msgstr "?????????????????\n" - -msgid "invalid personal compress preferences\n" -msgstr "?????????????\n" - -#, c-format -msgid "%s does not yet work with %s\n" -msgstr "%s?%s??????????\n" - -#, c-format -msgid "you may not use cipher algorithm '%s' while in %s mode\n" -msgstr "????????'%s'?%s??????????????\n" - -#, c-format -msgid "you may not use digest algorithm '%s' while in %s mode\n" -msgstr "?????????????'%s'?%s??????????????\n" - -#, c-format -msgid "you may not use compression algorithm '%s' while in %s mode\n" -msgstr "????????'%s'?%s??????????????\n" - -#, c-format -msgid "failed to initialize the TrustDB: %s\n" -msgstr "???????????????????: %s\n" - -msgid "WARNING: recipients (-r) given without using public key encryption\n" -msgstr "*??*: ?????????????? (-r) ????????\n" - -msgid "--store [filename]" -msgstr "--store [?????]" - -msgid "--symmetric [filename]" -msgstr "--symmetric [?????]" - -#, c-format -msgid "symmetric encryption of '%s' failed: %s\n" -msgstr "'%s'?????????????: %s\n" - -msgid "--encrypt [filename]" -msgstr "--encrypt [?????]" - -msgid "--symmetric --encrypt [filename]" -msgstr "--symmetric --encrypt [?????]" - -msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" -msgstr "--symmetric --encrypt?--s2k-mode 0???????????\n" - -#, c-format -msgid "you cannot use --symmetric --encrypt while in %s mode\n" -msgstr "--symmetric --encrypt?%s??????????????\n" - -msgid "--sign [filename]" -msgstr "--sign [?????]" - -msgid "--sign --encrypt [filename]" -msgstr "--sign --encrypt [?????]" - -msgid "--symmetric --sign --encrypt [filename]" -msgstr "--symmetric --sign --encrypt [?????]" - -msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" -msgstr "--symmetric --sign --encrypt?--s2k-mode 0???????????\n" - -#, c-format -msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n" -msgstr "--symmetric --sign --encrypt?%s??????????????\n" - -msgid "--sign --symmetric [filename]" -msgstr "--sign --symmetric [?????]" - -msgid "--clearsign [filename]" -msgstr "--clearsign [?????]" - -msgid "--decrypt [filename]" -msgstr "--decrypt [?????]" - -msgid "--sign-key user-id" -msgstr "--sign-key ???id" - -msgid "--lsign-key user-id" -msgstr "--lsign-key ???id" - -msgid "--edit-key user-id [commands]" -msgstr "--edit-key ???id [????]" - -msgid "--passwd " -msgstr "--passwd " - -#, c-format -msgid "keyserver send failed: %s\n" -msgstr "???????????????: %s\n" - -#, c-format -msgid "keyserver receive failed: %s\n" -msgstr "????????????????: %s\n" - -#, c-format -msgid "key export failed: %s\n" -msgstr "???????????????: %s\n" - -#, c-format -msgid "export as ssh key failed: %s\n" -msgstr "ssh??????????????????: %s\n" - -#, c-format -msgid "keyserver search failed: %s\n" -msgstr "??????????????: %s\n" - -#, c-format -msgid "keyserver refresh failed: %s\n" -msgstr "??????????????: %s\n" - -#, c-format -msgid "dearmoring failed: %s\n" -msgstr "???????????: %s\n" - -#, c-format -msgid "enarmoring failed: %s\n" -msgstr "?????????: %s\n" - -#, c-format -msgid "invalid hash algorithm '%s'\n" -msgstr "??????????????'%s'??\n" - -#, c-format -msgid "error parsing key specification '%s': %s\n" -msgstr "???'%s'????????: %s\n" - -#, c-format -msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" -msgstr "'%s'?????ID, ??????????keygrip?????????\n" - -msgid "[filename]" -msgstr "[?????]" - -msgid "Go ahead and type your message ...\n" -msgstr "??????????????????? ...\n" - -msgid "the given certification policy URL is invalid\n" -msgstr "?????????????URL?????\n" - -msgid "the given signature policy URL is invalid\n" -msgstr "????????????URL?????\n" - -msgid "the given preferred keyserver URL is invalid\n" -msgstr "???????????URL?????\n" - msgid "|FILE|take the keys from the keyring FILE" msgstr "|FILE|????FILE???????" @@ -2409,11 +2066,6 @@ msgstr "??????????????????????" msgid "do not update the trustdb after import" msgstr "?????????????????????" -#, fuzzy -#| msgid "show key fingerprint" -msgid "show key during import" -msgstr "??????????????" - msgid "only accept updates to existing keys" msgstr "????????????????" @@ -2423,9 +2075,6 @@ msgstr "???????????????????????? msgid "remove as much as possible from key after import" msgstr "?????????????????" -msgid "run import filters and export key immediately" -msgstr "" - #, c-format msgid "skipping block of type %d\n" msgstr "?%d?????????????\n" @@ -2567,6 +2216,10 @@ msgid "no writable keyring found: %s\n" msgstr "???????????????????: %s\n" #, c-format +msgid "writing to '%s'\n" +msgstr "'%s'??????\n" + +#, c-format msgid "error writing keyring '%s': %s\n" msgstr "????'%s'????????: %s\n" @@ -3276,11 +2929,6 @@ msgstr "?????????: %s\n" msgid "Key not changed so no update needed.\n" msgstr "????????????????\n" -#, fuzzy, c-format -#| msgid "Key generation failed: %s\n" -msgid "User ID revocation failed: %s\n" -msgstr "???????????: %s\n" - #, c-format msgid "\"%s\" is not a fingerprint\n" msgstr "\"%s\"?????????????????\n" @@ -3509,6 +3157,9 @@ msgstr "???ID\"%s\"?v3????????????\n" msgid "Enter your preferred keyserver URL: " msgstr "??????URL?????????: " +msgid "could not parse keyserver URL\n" +msgstr "?????URL?????\n" + msgid "Are you sure you want to replace it? (y/N) " msgstr "????????????? (y/N) " @@ -3582,10 +3233,6 @@ msgid "no secret key\n" msgstr "?????????\n" #, c-format -msgid "tried to revoke a non-user ID: %s\n" -msgstr "" - -#, c-format msgid "user ID \"%s\" is already revoked\n" msgstr "???ID\"%s\"????????????\n" @@ -4078,6 +3725,10 @@ msgstr[0] "*??*: %lu?????????????????? msgid "Keyring" msgstr "????" +#, c-format +msgid "skipped \"%s\": %s\n" +msgstr "\"%s\"?????????: %s\n" + msgid "Primary key fingerprint:" msgstr " ???????????:" @@ -4187,14 +3838,14 @@ msgid "no keyserver known\n" msgstr "???????????\n" #, c-format -msgid "skipped \"%s\": %s\n" -msgstr "\"%s\"?????????: %s\n" - -#, c-format msgid "sending key %s to %s\n" msgstr "?%s?%s???\n" #, c-format +msgid "keyserver send failed: %s\n" +msgstr "???????????????: %s\n" + +#, c-format msgid "requesting key from '%s'\n" msgstr "??'%s'????\n" @@ -5345,6 +4996,10 @@ msgid "error updating TOFU database: %s\n" msgstr "TOFU????????????: %s\n" #, c-format +msgid "error setting TOFU binding's trust level to %s\n" +msgstr "TOFU??????????????????: %s\n" + +#, c-format msgid "The binding %s is NOT known." msgstr "%s??????????????" @@ -5417,14 +5072,14 @@ msgid_plural " over the past %ld months." msgstr[0] "??%ld???" #. TRANSLATORS: Please translate the text found in the source -#. * file below. We don't directly internationalize that text so -#. * that we can tweak it without breaking translations. +#. file below. We don't directly internationalize that text +#. so that we can tweak it without breaking translations. msgid "TOFU detected a binding conflict" msgstr "TOFU??????????????????" #. TRANSLATORS: Two letters (normally the lower and upper case -#. * version of the hotkey) for each of the five choices. If -#. * there is only one choice in your language, repeat it. +#. version of the hotkey) for each of the five choices. If +#. there is only one choice in your language, repeat it. msgid "gGaAuUrRbB" msgstr "gGaAuUrRbB" @@ -5434,10 +5089,6 @@ msgstr "" "?, (B)ad-??? " #, c-format -msgid "error setting TOFU binding's trust level to %s\n" -msgstr "TOFU??????????????????: %s\n" - -#, c-format msgid "error changing TOFU policy: %s\n" msgstr "TOFU??????????: %s\n" @@ -6558,9 +6209,25 @@ msgstr "%s:%u: ????????????????\n" msgid "%s:%u: skipping this line\n" msgstr "%s:%u: ????????\n" +#, c-format +msgid "invalid pinentry mode '%s'\n" +msgstr "??? pinentry mode '%s'??\n" + msgid "could not parse keyserver\n" msgstr "?????URL?????\n" +msgid "WARNING: program may create a core file!\n" +msgstr "*??*: ??????core????????????????!\n" + +msgid "WARNING: running with faked system time: " +msgstr "*??*: ???????????????????: " + +msgid "selected cipher algorithm is invalid\n" +msgstr "???????????????????\n" + +msgid "selected digest algorithm is invalid\n" +msgstr "????????????????????????\n" + #, c-format msgid "importing common certificates '%s'\n" msgstr "???????????????: %s\n" @@ -7974,7 +7641,7 @@ msgstr "|N|??SSH??????N????" msgid "Options enforcing a passphrase policy" msgstr "??????????????????" -msgid "do not allow bypassing the passphrase policy" +msgid "do not allow to bypass the passphrase policy" msgstr "??????????????????????" msgid "|N|set minimal required length for new passphrases to N" @@ -8283,6 +7950,295 @@ msgstr "" "??: gpg-check-pattern [?????] ????????\n" "????????????????????????????\n" +#~ msgid "quickly revoke a user-id" +#~ msgstr "???????ID???" + +#~ msgid "available TOFU policies:\n" +#~ msgstr "?????TOFU????:\n" + +#~ msgid "unknown TOFU policy '%s'\n" +#~ msgstr "???TOFU????'%s'\n" + +#~ msgid "(use \"help\" to list choices)\n" +#~ msgstr "(????????\"help\"????????)\n" + +#~ msgid "unknown TOFU DB format '%s'\n" +#~ msgstr "???TOFU DB??????'%s'\n" + +#~ msgid "Note: old default options file '%s' ignored\n" +#~ msgstr "" +#~ "*??*: ????????????????????'%s'????????\n" + +#~ msgid "libgcrypt is too old (need %s, have %s)\n" +#~ msgstr "libgcrypt ?????? (?? %s, ?? %s)\n" + +#~ msgid "Note: %s is not for normal use!\n" +#~ msgstr "*??*: ??%s??????!\n" + +#~ msgid "'%s' is not a valid signature expiration\n" +#~ msgstr "'%s'????????????????\n" + +#~ msgid "'%s' is not a valid character set\n" +#~ msgstr "'%s'????????????????\n" + +#~ msgid "%s:%d: invalid keyserver options\n" +#~ msgstr "%s:%d: ???????????????\n" + +#~ msgid "invalid keyserver options\n" +#~ msgstr "???????????????\n" + +#~ msgid "%s:%d: invalid import options\n" +#~ msgstr "%s:%d: ????????????????\n" + +#~ msgid "invalid import options\n" +#~ msgstr "????????????????\n" + +#~ msgid "invalid filter option: %s\n" +#~ msgstr "???????????????: %s\n" + +#~ msgid "%s:%d: invalid export options\n" +#~ msgstr "%s:%d: ?????????????????\n" + +#~ msgid "invalid export options\n" +#~ msgstr "?????????????????\n" + +#~ msgid "%s:%d: invalid list options\n" +#~ msgstr "%s:%d: ????????????\n" + +#~ msgid "invalid list options\n" +#~ msgstr "????????????\n" + +#~ msgid "display photo IDs during signature verification" +#~ msgstr "??????????ID?????" + +#~ msgid "show policy URLs during signature verification" +#~ msgstr "???????????URL?????" + +#~ msgid "show all notations during signature verification" +#~ msgstr "??????????????????" + +#~ msgid "show IETF standard notations during signature verification" +#~ msgstr "???????IETF?????????" + +#~ msgid "show user-supplied notations during signature verification" +#~ msgstr "??????????????????" + +#~ msgid "show preferred keyserver URLs during signature verification" +#~ msgstr "?????????????URL?????" + +#~ msgid "show user ID validity during signature verification" +#~ msgstr "??????????ID?????????" + +#~ msgid "show revoked and expired user IDs in signature verification" +#~ msgstr "??????????????ID????????????ID?????" + +#~ msgid "show only the primary user ID in signature verification" +#~ msgstr "????????????ID????????" + +#~ msgid "validate signatures with PKA data" +#~ msgstr "PKA???????????" + +#~ msgid "elevate the trust of signatures with valid PKA data" +#~ msgstr "???PKA????????????????" + +#~ msgid "%s:%d: invalid verify options\n" +#~ msgstr "%s:%d: ????????????\n" + +#~ msgid "invalid verify options\n" +#~ msgstr "????????????\n" + +#~ msgid "unable to set exec-path to %s\n" +#~ msgstr "exec-path?%s?????\n" + +#~ msgid "%s:%d: invalid auto-key-locate list\n" +#~ msgstr "%s:%d: ??? auto-key-locate ?????\n" + +#~ msgid "invalid auto-key-locate list\n" +#~ msgstr "??? auto-key-locate ?????\n" + +#~ msgid "WARNING: %s overrides %s\n" +#~ msgstr "*??*: %s?%s????\n" + +#~ msgid "%s not allowed with %s!\n" +#~ msgstr "%s?%s??????????????!\n" + +#~ msgid "%s makes no sense with %s!\n" +#~ msgstr "%s?%s?????????????!\n" + +#~ msgid "will not run with insecure memory due to %s\n" +#~ msgstr "%s ?????????????????????\n" + +#~ msgid "selected compression algorithm is invalid\n" +#~ msgstr "???????????????????\n" + +#~ msgid "selected certification digest algorithm is invalid\n" +#~ msgstr "???????????????????????????\n" + +#~ msgid "completes-needed must be greater than 0\n" +#~ msgstr "completes-needed?????????\n" + +#~ msgid "marginals-needed must be greater than 1\n" +#~ msgstr "marginals-needed?1???????????\n" + +#~ msgid "max-cert-depth must be in the range from 1 to 255\n" +#~ msgstr "max-cert-depth?1??255?????????????\n" + +#~ msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" +#~ msgstr "???default-cert-level?0?1?2?3??????????\n" + +#~ msgid "invalid min-cert-level; must be 1, 2, or 3\n" +#~ msgstr "???min-cert-level?0?1?2?3??????????\n" + +#~ msgid "Note: simple S2K mode (0) is strongly discouraged\n" +#~ msgstr "*??*: ???S2K???(0)????????????\n" + +#~ msgid "invalid S2K mode; must be 0, 1 or 3\n" +#~ msgstr "???S2K????0?1?3??????????\n" + +#~ msgid "invalid default preferences\n" +#~ msgstr "?????????????\n" + +#~ msgid "invalid personal cipher preferences\n" +#~ msgstr "???????????????\n" + +#~ msgid "invalid personal digest preferences\n" +#~ msgstr "?????????????????\n" + +#~ msgid "invalid personal compress preferences\n" +#~ msgstr "?????????????\n" + +#~ msgid "%s does not yet work with %s\n" +#~ msgstr "%s?%s??????????\n" + +#~ msgid "you may not use cipher algorithm '%s' while in %s mode\n" +#~ msgstr "????????'%s'?%s??????????????\n" + +#~ msgid "you may not use digest algorithm '%s' while in %s mode\n" +#~ msgstr "?????????????'%s'?%s??????????????\n" + +#~ msgid "you may not use compression algorithm '%s' while in %s mode\n" +#~ msgstr "????????'%s'?%s??????????????\n" + +#~ msgid "failed to initialize the TrustDB: %s\n" +#~ msgstr "???????????????????: %s\n" + +#~ msgid "WARNING: recipients (-r) given without using public key encryption\n" +#~ msgstr "*??*: ?????????????? (-r) ????????\n" + +#~ msgid "--store [filename]" +#~ msgstr "--store [?????]" + +#~ msgid "--symmetric [filename]" +#~ msgstr "--symmetric [?????]" + +#~ msgid "symmetric encryption of '%s' failed: %s\n" +#~ msgstr "'%s'?????????????: %s\n" + +#~ msgid "--encrypt [filename]" +#~ msgstr "--encrypt [?????]" + +#~ msgid "--symmetric --encrypt [filename]" +#~ msgstr "--symmetric --encrypt [?????]" + +#~ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" +#~ msgstr "--symmetric --encrypt?--s2k-mode 0???????????\n" + +#~ msgid "you cannot use --symmetric --encrypt while in %s mode\n" +#~ msgstr "--symmetric --encrypt?%s??????????????\n" + +#~ msgid "--sign [filename]" +#~ msgstr "--sign [?????]" + +#~ msgid "--sign --encrypt [filename]" +#~ msgstr "--sign --encrypt [?????]" + +#~ msgid "--symmetric --sign --encrypt [filename]" +#~ msgstr "--symmetric --sign --encrypt [?????]" + +#~ msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" +#~ msgstr "--symmetric --sign --encrypt?--s2k-mode 0???????????\n" + +#~ msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n" +#~ msgstr "--symmetric --sign --encrypt?%s??????????????\n" + +#~ msgid "--sign --symmetric [filename]" +#~ msgstr "--sign --symmetric [?????]" + +#~ msgid "--clearsign [filename]" +#~ msgstr "--clearsign [?????]" + +#~ msgid "--decrypt [filename]" +#~ msgstr "--decrypt [?????]" + +#~ msgid "--sign-key user-id" +#~ msgstr "--sign-key ???id" + +#~ msgid "--lsign-key user-id" +#~ msgstr "--lsign-key ???id" + +#~ msgid "--edit-key user-id [commands]" +#~ msgstr "--edit-key ???id [????]" + +#~ msgid "--passwd " +#~ msgstr "--passwd " + +#~ msgid "keyserver receive failed: %s\n" +#~ msgstr "????????????????: %s\n" + +#~ msgid "key export failed: %s\n" +#~ msgstr "???????????????: %s\n" + +#~ msgid "export as ssh key failed: %s\n" +#~ msgstr "ssh??????????????????: %s\n" + +#~ msgid "keyserver search failed: %s\n" +#~ msgstr "??????????????: %s\n" + +#~ msgid "keyserver refresh failed: %s\n" +#~ msgstr "??????????????: %s\n" + +#~ msgid "dearmoring failed: %s\n" +#~ msgstr "???????????: %s\n" + +#~ msgid "enarmoring failed: %s\n" +#~ msgstr "?????????: %s\n" + +#~ msgid "invalid hash algorithm '%s'\n" +#~ msgstr "??????????????'%s'??\n" + +#~ msgid "error parsing key specification '%s': %s\n" +#~ msgstr "???'%s'????????: %s\n" + +#~ msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" +#~ msgstr "'%s'?????ID, ??????????keygrip?????????\n" + +#~ msgid "[filename]" +#~ msgstr "[?????]" + +#~ msgid "Go ahead and type your message ...\n" +#~ msgstr "??????????????????? ...\n" + +#~ msgid "the given certification policy URL is invalid\n" +#~ msgstr "?????????????URL?????\n" + +#~ msgid "the given signature policy URL is invalid\n" +#~ msgstr "????????????URL?????\n" + +#~ msgid "the given preferred keyserver URL is invalid\n" +#~ msgstr "???????????URL?????\n" + +#~ msgid "show key during import" +#~ msgstr "????????????" + +#~ msgid "run import filters and export key immediately" +#~ msgstr "????????????????????????????" + +#~ msgid "User ID revocation failed: %s\n" +#~ msgstr "???ID??????????: %s\n" + +#~ msgid "tried to revoke a non-user ID: %s\n" +#~ msgstr "???ID????????????????: %s\n" + #~ msgid "you found a bug ... (%s:%d)\n" #~ msgstr "????????????? ... (%s:%d)\n" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 728 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 342 insertions(+), 386 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 10:31:41 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 04 Aug 2016 10:31:41 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-41-g89234f7 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 89234f7f3643bad2daddc94569f1d651ec5c835e (commit) from 573e0f36190346e0263bea3ae12a389f4f598d55 (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 89234f7f3643bad2daddc94569f1d651ec5c835e Author: NIIBE Yutaka Date: Thu Aug 4 17:31:13 2016 +0900 po: Update Japanese translation. diff --git a/po/ja.po b/po/ja.po index 35482a3..8c2de0f 100644 --- a/po/ja.po +++ b/po/ja.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg 2.1.15\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2016-08-04 16:38+0900\n" +"PO-Revision-Date: 2016-08-04 17:30+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -432,6 +432,10 @@ msgid "error binding socket to '%s': %s\n" msgstr "'%s'??????????????: %s\n" #, c-format +msgid "can't set permissions of '%s': %s\n" +msgstr "'%s'???????????: %s\n" + +#, c-format msgid "listen() failed: %s\n" msgstr "listen() ???????: %s\n" @@ -448,10 +452,6 @@ msgid "directory '%s' created\n" msgstr "??????'%s'????????\n" #, c-format -msgid "can't set permissions of '%s': %s\n" -msgstr "'%s'???????????: %s\n" - -#, c-format msgid "stat() failed for '%s': %s\n" msgstr "'%s'?stat()???????: %s\n" @@ -1652,6 +1652,14 @@ msgstr "??????????????????" msgid " - skipped" msgstr " - ?????????" +#, c-format +msgid "writing to '%s'\n" +msgstr "'%s'??????\n" + +#, c-format +msgid "key %s: key material on-card - skipped\n" +msgstr "?%s: ??????????? - ???????\n" + msgid "exporting secret keys not allowed\n" msgstr "??????????????????\n" @@ -1659,10 +1667,6 @@ msgstr "??????????????????\n" msgid "key %s: PGP 2.x style key - skipped\n" msgstr "?%s: PGP 2.x?????? - ???????\n" -#, c-format -msgid "key %s: key material on-card - skipped\n" -msgstr "?%s: ??????????? - ???????\n" - msgid "WARNING: nothing exported\n" msgstr "*??*: ???????????????\n" @@ -1769,6 +1773,9 @@ msgstr "?????????????" msgid "quickly add a new user-id" msgstr "??????????ID???" +msgid "quickly revoke a user-id" +msgstr "???????ID???" + msgid "full featured key pair generation" msgstr "??????????" @@ -1802,13 +1809,13 @@ msgstr "?????????" msgid "export keys" msgstr "??????????" -msgid "export keys to a key server" +msgid "export keys to a keyserver" msgstr "???????????????" -msgid "import keys from a key server" +msgid "import keys from a keyserver" msgstr "???????????????" -msgid "search for keys on a key server" +msgid "search for keys on a keyserver" msgstr "???????????" msgid "update all keys from a keyserver" @@ -2025,6 +2032,339 @@ msgstr "?????????????????" msgid "show expiration dates during signature listings" msgstr "???????????????????" +msgid "available TOFU policies:\n" +msgstr "?????TOFU????:\n" + +#, c-format +msgid "unknown TOFU policy '%s'\n" +msgstr "???TOFU????'%s'\n" + +msgid "(use \"help\" to list choices)\n" +msgstr "(????????\"help\"????????)\n" + +#, c-format +msgid "unknown TOFU DB format '%s'\n" +msgstr "???TOFU DB??????'%s'\n" + +#, c-format +msgid "Note: old default options file '%s' ignored\n" +msgstr "*??*: ????????????????????'%s'????????\n" + +#, c-format +msgid "libgcrypt is too old (need %s, have %s)\n" +msgstr "libgcrypt ?????? (?? %s, ?? %s)\n" + +#, c-format +msgid "Note: %s is not for normal use!\n" +msgstr "*??*: ??%s??????!\n" + +#, c-format +msgid "'%s' is not a valid signature expiration\n" +msgstr "'%s'????????????????\n" + +#, c-format +msgid "invalid pinentry mode '%s'\n" +msgstr "??? pinentry mode '%s'??\n" + +#, c-format +msgid "'%s' is not a valid character set\n" +msgstr "'%s'????????????????\n" + +msgid "could not parse keyserver URL\n" +msgstr "?????URL?????\n" + +#, c-format +msgid "%s:%d: invalid keyserver options\n" +msgstr "%s:%d: ???????????????\n" + +msgid "invalid keyserver options\n" +msgstr "???????????????\n" + +#, c-format +msgid "%s:%d: invalid import options\n" +msgstr "%s:%d: ????????????????\n" + +msgid "invalid import options\n" +msgstr "????????????????\n" + +#, c-format +msgid "invalid filter option: %s\n" +msgstr "???????????????: %s\n" + +#, c-format +msgid "%s:%d: invalid export options\n" +msgstr "%s:%d: ?????????????????\n" + +msgid "invalid export options\n" +msgstr "?????????????????\n" + +#, c-format +msgid "%s:%d: invalid list options\n" +msgstr "%s:%d: ????????????\n" + +msgid "invalid list options\n" +msgstr "????????????\n" + +msgid "display photo IDs during signature verification" +msgstr "??????????ID?????" + +msgid "show policy URLs during signature verification" +msgstr "???????????URL?????" + +msgid "show all notations during signature verification" +msgstr "??????????????????" + +msgid "show IETF standard notations during signature verification" +msgstr "???????IETF?????????" + +msgid "show user-supplied notations during signature verification" +msgstr "??????????????????" + +msgid "show preferred keyserver URLs during signature verification" +msgstr "?????????????URL?????" + +msgid "show user ID validity during signature verification" +msgstr "??????????ID?????????" + +msgid "show revoked and expired user IDs in signature verification" +msgstr "??????????????ID????????????ID?????" + +msgid "show only the primary user ID in signature verification" +msgstr "????????????ID????????" + +msgid "validate signatures with PKA data" +msgstr "PKA???????????" + +msgid "elevate the trust of signatures with valid PKA data" +msgstr "???PKA????????????????" + +#, c-format +msgid "%s:%d: invalid verify options\n" +msgstr "%s:%d: ????????????\n" + +msgid "invalid verify options\n" +msgstr "????????????\n" + +#, c-format +msgid "unable to set exec-path to %s\n" +msgstr "exec-path?%s?????\n" + +#, c-format +msgid "%s:%d: invalid auto-key-locate list\n" +msgstr "%s:%d: ??? auto-key-locate ?????\n" + +msgid "invalid auto-key-locate list\n" +msgstr "??? auto-key-locate ?????\n" + +msgid "WARNING: program may create a core file!\n" +msgstr "*??*: ??????core????????????????!\n" + +#, c-format +msgid "WARNING: %s overrides %s\n" +msgstr "*??*: %s?%s????\n" + +#, c-format +msgid "%s not allowed with %s!\n" +msgstr "%s?%s??????????????!\n" + +#, c-format +msgid "%s makes no sense with %s!\n" +msgstr "%s?%s?????????????!\n" + +msgid "WARNING: running with faked system time: " +msgstr "*??*: ???????????????????: " + +#, c-format +msgid "will not run with insecure memory due to %s\n" +msgstr "%s ?????????????????????\n" + +msgid "selected cipher algorithm is invalid\n" +msgstr "???????????????????\n" + +msgid "selected digest algorithm is invalid\n" +msgstr "????????????????????????\n" + +msgid "selected compression algorithm is invalid\n" +msgstr "???????????????????\n" + +msgid "selected certification digest algorithm is invalid\n" +msgstr "???????????????????????????\n" + +msgid "completes-needed must be greater than 0\n" +msgstr "completes-needed?????????\n" + +msgid "marginals-needed must be greater than 1\n" +msgstr "marginals-needed?1???????????\n" + +msgid "max-cert-depth must be in the range from 1 to 255\n" +msgstr "max-cert-depth?1??255?????????????\n" + +msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" +msgstr "???default-cert-level?0?1?2?3??????????\n" + +msgid "invalid min-cert-level; must be 1, 2, or 3\n" +msgstr "???min-cert-level?0?1?2?3??????????\n" + +msgid "Note: simple S2K mode (0) is strongly discouraged\n" +msgstr "*??*: ???S2K???(0)????????????\n" + +msgid "invalid S2K mode; must be 0, 1 or 3\n" +msgstr "???S2K????0?1?3??????????\n" + +msgid "invalid default preferences\n" +msgstr "?????????????\n" + +msgid "invalid personal cipher preferences\n" +msgstr "???????????????\n" + +msgid "invalid personal digest preferences\n" +msgstr "?????????????????\n" + +msgid "invalid personal compress preferences\n" +msgstr "?????????????\n" + +#, c-format +msgid "%s does not yet work with %s\n" +msgstr "%s?%s??????????\n" + +#, c-format +msgid "you may not use cipher algorithm '%s' while in %s mode\n" +msgstr "????????'%s'?%s??????????????\n" + +#, c-format +msgid "you may not use digest algorithm '%s' while in %s mode\n" +msgstr "?????????????'%s'?%s??????????????\n" + +#, c-format +msgid "you may not use compression algorithm '%s' while in %s mode\n" +msgstr "????????'%s'?%s??????????????\n" + +#, c-format +msgid "failed to initialize the TrustDB: %s\n" +msgstr "???????????????????: %s\n" + +msgid "WARNING: recipients (-r) given without using public key encryption\n" +msgstr "*??*: ?????????????? (-r) ????????\n" + +msgid "--store [filename]" +msgstr "--store [?????]" + +msgid "--symmetric [filename]" +msgstr "--symmetric [?????]" + +#, c-format +msgid "symmetric encryption of '%s' failed: %s\n" +msgstr "'%s'?????????????: %s\n" + +msgid "--encrypt [filename]" +msgstr "--encrypt [?????]" + +msgid "--symmetric --encrypt [filename]" +msgstr "--symmetric --encrypt [?????]" + +msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" +msgstr "--symmetric --encrypt?--s2k-mode 0???????????\n" + +#, c-format +msgid "you cannot use --symmetric --encrypt while in %s mode\n" +msgstr "--symmetric --encrypt?%s??????????????\n" + +msgid "--sign [filename]" +msgstr "--sign [?????]" + +msgid "--sign --encrypt [filename]" +msgstr "--sign --encrypt [?????]" + +msgid "--symmetric --sign --encrypt [filename]" +msgstr "--symmetric --sign --encrypt [?????]" + +msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" +msgstr "--symmetric --sign --encrypt?--s2k-mode 0???????????\n" + +#, c-format +msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n" +msgstr "--symmetric --sign --encrypt?%s??????????????\n" + +msgid "--sign --symmetric [filename]" +msgstr "--sign --symmetric [?????]" + +msgid "--clearsign [filename]" +msgstr "--clearsign [?????]" + +msgid "--decrypt [filename]" +msgstr "--decrypt [?????]" + +msgid "--sign-key user-id" +msgstr "--sign-key ???id" + +msgid "--lsign-key user-id" +msgstr "--lsign-key ???id" + +msgid "--edit-key user-id [commands]" +msgstr "--edit-key ???id [????]" + +msgid "--passwd " +msgstr "--passwd " + +#, c-format +msgid "keyserver send failed: %s\n" +msgstr "???????????????: %s\n" + +#, c-format +msgid "keyserver receive failed: %s\n" +msgstr "????????????????: %s\n" + +#, c-format +msgid "key export failed: %s\n" +msgstr "???????????????: %s\n" + +#, c-format +msgid "export as ssh key failed: %s\n" +msgstr "ssh??????????????????: %s\n" + +#, c-format +msgid "keyserver search failed: %s\n" +msgstr "??????????????: %s\n" + +#, c-format +msgid "keyserver refresh failed: %s\n" +msgstr "??????????????: %s\n" + +#, c-format +msgid "dearmoring failed: %s\n" +msgstr "???????????: %s\n" + +#, c-format +msgid "enarmoring failed: %s\n" +msgstr "?????????: %s\n" + +#, c-format +msgid "invalid hash algorithm '%s'\n" +msgstr "??????????????'%s'??\n" + +#, c-format +msgid "error parsing key specification '%s': %s\n" +msgstr "???'%s'????????: %s\n" + +#, c-format +msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" +msgstr "'%s'?????ID, ??????????keygrip?????????\n" + +msgid "[filename]" +msgstr "[?????]" + +msgid "Go ahead and type your message ...\n" +msgstr "??????????????????? ...\n" + +msgid "the given certification policy URL is invalid\n" +msgstr "?????????????URL?????\n" + +msgid "the given signature policy URL is invalid\n" +msgstr "????????????URL?????\n" + +msgid "the given preferred keyserver URL is invalid\n" +msgstr "???????????URL?????\n" + msgid "|FILE|take the keys from the keyring FILE" msgstr "|FILE|????FILE???????" @@ -2066,6 +2406,9 @@ msgstr "??????????????????????" msgid "do not update the trustdb after import" msgstr "?????????????????????" +msgid "show key during import" +msgstr "????????????" + msgid "only accept updates to existing keys" msgstr "????????????????" @@ -2075,6 +2418,9 @@ msgstr "???????????????????????? msgid "remove as much as possible from key after import" msgstr "?????????????????" +msgid "run import filters and export key immediately" +msgstr "????????????????????????????" + #, c-format msgid "skipping block of type %d\n" msgstr "?%d?????????????\n" @@ -2216,10 +2562,6 @@ msgid "no writable keyring found: %s\n" msgstr "???????????????????: %s\n" #, c-format -msgid "writing to '%s'\n" -msgstr "'%s'??????\n" - -#, c-format msgid "error writing keyring '%s': %s\n" msgstr "????'%s'????????: %s\n" @@ -2930,6 +3272,10 @@ msgid "Key not changed so no update needed.\n" msgstr "????????????????\n" #, c-format +msgid "User ID revocation failed: %s\n" +msgstr "???ID??????????: %s\n" + +#, c-format msgid "\"%s\" is not a fingerprint\n" msgstr "\"%s\"?????????????????\n" @@ -3157,9 +3503,6 @@ msgstr "???ID\"%s\"?v3????????????\n" msgid "Enter your preferred keyserver URL: " msgstr "??????URL?????????: " -msgid "could not parse keyserver URL\n" -msgstr "?????URL?????\n" - msgid "Are you sure you want to replace it? (y/N) " msgstr "????????????? (y/N) " @@ -3233,6 +3576,10 @@ msgid "no secret key\n" msgstr "?????????\n" #, c-format +msgid "tried to revoke a non-user ID: %s\n" +msgstr "???ID????????????????: %s\n" + +#, c-format msgid "user ID \"%s\" is already revoked\n" msgstr "???ID\"%s\"????????????\n" @@ -3725,10 +4072,6 @@ msgstr[0] "*??*: %lu?????????????????? msgid "Keyring" msgstr "????" -#, c-format -msgid "skipped \"%s\": %s\n" -msgstr "\"%s\"?????????: %s\n" - msgid "Primary key fingerprint:" msgstr " ???????????:" @@ -3838,12 +4181,12 @@ msgid "no keyserver known\n" msgstr "???????????\n" #, c-format -msgid "sending key %s to %s\n" -msgstr "?%s?%s???\n" +msgid "skipped \"%s\": %s\n" +msgstr "\"%s\"?????????: %s\n" #, c-format -msgid "keyserver send failed: %s\n" -msgstr "???????????????: %s\n" +msgid "sending key %s to %s\n" +msgstr "?%s?%s???\n" #, c-format msgid "requesting key from '%s'\n" @@ -4996,10 +5339,6 @@ msgid "error updating TOFU database: %s\n" msgstr "TOFU????????????: %s\n" #, c-format -msgid "error setting TOFU binding's trust level to %s\n" -msgstr "TOFU??????????????????: %s\n" - -#, c-format msgid "The binding %s is NOT known." msgstr "%s??????????????" @@ -5072,14 +5411,14 @@ msgid_plural " over the past %ld months." msgstr[0] "??%ld???" #. TRANSLATORS: Please translate the text found in the source -#. file below. We don't directly internationalize that text -#. so that we can tweak it without breaking translations. +#. * file below. We don't directly internationalize that text so +#. * that we can tweak it without breaking translations. msgid "TOFU detected a binding conflict" msgstr "TOFU??????????????????" #. TRANSLATORS: Two letters (normally the lower and upper case -#. version of the hotkey) for each of the five choices. If -#. there is only one choice in your language, repeat it. +#. * version of the hotkey) for each of the five choices. If +#. * there is only one choice in your language, repeat it. msgid "gGaAuUrRbB" msgstr "gGaAuUrRbB" @@ -5089,6 +5428,10 @@ msgstr "" "?, (B)ad-??? " #, c-format +msgid "error setting TOFU binding's trust level to %s\n" +msgstr "TOFU??????????????????: %s\n" + +#, c-format msgid "error changing TOFU policy: %s\n" msgstr "TOFU??????????: %s\n" @@ -6209,25 +6552,9 @@ msgstr "%s:%u: ????????????????\n" msgid "%s:%u: skipping this line\n" msgstr "%s:%u: ????????\n" -#, c-format -msgid "invalid pinentry mode '%s'\n" -msgstr "??? pinentry mode '%s'??\n" - msgid "could not parse keyserver\n" msgstr "?????URL?????\n" -msgid "WARNING: program may create a core file!\n" -msgstr "*??*: ??????core????????????????!\n" - -msgid "WARNING: running with faked system time: " -msgstr "*??*: ???????????????????: " - -msgid "selected cipher algorithm is invalid\n" -msgstr "???????????????????\n" - -msgid "selected digest algorithm is invalid\n" -msgstr "????????????????????????\n" - #, c-format msgid "importing common certificates '%s'\n" msgstr "???????????????: %s\n" @@ -7641,7 +7968,7 @@ msgstr "|N|??SSH??????N????" msgid "Options enforcing a passphrase policy" msgstr "??????????????????" -msgid "do not allow to bypass the passphrase policy" +msgid "do not allow bypassing the passphrase policy" msgstr "??????????????????????" msgid "|N|set minimal required length for new passphrases to N" @@ -7950,295 +8277,6 @@ msgstr "" "??: gpg-check-pattern [?????] ????????\n" "????????????????????????????\n" -#~ msgid "quickly revoke a user-id" -#~ msgstr "???????ID???" - -#~ msgid "available TOFU policies:\n" -#~ msgstr "?????TOFU????:\n" - -#~ msgid "unknown TOFU policy '%s'\n" -#~ msgstr "???TOFU????'%s'\n" - -#~ msgid "(use \"help\" to list choices)\n" -#~ msgstr "(????????\"help\"????????)\n" - -#~ msgid "unknown TOFU DB format '%s'\n" -#~ msgstr "???TOFU DB??????'%s'\n" - -#~ msgid "Note: old default options file '%s' ignored\n" -#~ msgstr "" -#~ "*??*: ????????????????????'%s'????????\n" - -#~ msgid "libgcrypt is too old (need %s, have %s)\n" -#~ msgstr "libgcrypt ?????? (?? %s, ?? %s)\n" - -#~ msgid "Note: %s is not for normal use!\n" -#~ msgstr "*??*: ??%s??????!\n" - -#~ msgid "'%s' is not a valid signature expiration\n" -#~ msgstr "'%s'????????????????\n" - -#~ msgid "'%s' is not a valid character set\n" -#~ msgstr "'%s'????????????????\n" - -#~ msgid "%s:%d: invalid keyserver options\n" -#~ msgstr "%s:%d: ???????????????\n" - -#~ msgid "invalid keyserver options\n" -#~ msgstr "???????????????\n" - -#~ msgid "%s:%d: invalid import options\n" -#~ msgstr "%s:%d: ????????????????\n" - -#~ msgid "invalid import options\n" -#~ msgstr "????????????????\n" - -#~ msgid "invalid filter option: %s\n" -#~ msgstr "???????????????: %s\n" - -#~ msgid "%s:%d: invalid export options\n" -#~ msgstr "%s:%d: ?????????????????\n" - -#~ msgid "invalid export options\n" -#~ msgstr "?????????????????\n" - -#~ msgid "%s:%d: invalid list options\n" -#~ msgstr "%s:%d: ????????????\n" - -#~ msgid "invalid list options\n" -#~ msgstr "????????????\n" - -#~ msgid "display photo IDs during signature verification" -#~ msgstr "??????????ID?????" - -#~ msgid "show policy URLs during signature verification" -#~ msgstr "???????????URL?????" - -#~ msgid "show all notations during signature verification" -#~ msgstr "??????????????????" - -#~ msgid "show IETF standard notations during signature verification" -#~ msgstr "???????IETF?????????" - -#~ msgid "show user-supplied notations during signature verification" -#~ msgstr "??????????????????" - -#~ msgid "show preferred keyserver URLs during signature verification" -#~ msgstr "?????????????URL?????" - -#~ msgid "show user ID validity during signature verification" -#~ msgstr "??????????ID?????????" - -#~ msgid "show revoked and expired user IDs in signature verification" -#~ msgstr "??????????????ID????????????ID?????" - -#~ msgid "show only the primary user ID in signature verification" -#~ msgstr "????????????ID????????" - -#~ msgid "validate signatures with PKA data" -#~ msgstr "PKA???????????" - -#~ msgid "elevate the trust of signatures with valid PKA data" -#~ msgstr "???PKA????????????????" - -#~ msgid "%s:%d: invalid verify options\n" -#~ msgstr "%s:%d: ????????????\n" - -#~ msgid "invalid verify options\n" -#~ msgstr "????????????\n" - -#~ msgid "unable to set exec-path to %s\n" -#~ msgstr "exec-path?%s?????\n" - -#~ msgid "%s:%d: invalid auto-key-locate list\n" -#~ msgstr "%s:%d: ??? auto-key-locate ?????\n" - -#~ msgid "invalid auto-key-locate list\n" -#~ msgstr "??? auto-key-locate ?????\n" - -#~ msgid "WARNING: %s overrides %s\n" -#~ msgstr "*??*: %s?%s????\n" - -#~ msgid "%s not allowed with %s!\n" -#~ msgstr "%s?%s??????????????!\n" - -#~ msgid "%s makes no sense with %s!\n" -#~ msgstr "%s?%s?????????????!\n" - -#~ msgid "will not run with insecure memory due to %s\n" -#~ msgstr "%s ?????????????????????\n" - -#~ msgid "selected compression algorithm is invalid\n" -#~ msgstr "???????????????????\n" - -#~ msgid "selected certification digest algorithm is invalid\n" -#~ msgstr "???????????????????????????\n" - -#~ msgid "completes-needed must be greater than 0\n" -#~ msgstr "completes-needed?????????\n" - -#~ msgid "marginals-needed must be greater than 1\n" -#~ msgstr "marginals-needed?1???????????\n" - -#~ msgid "max-cert-depth must be in the range from 1 to 255\n" -#~ msgstr "max-cert-depth?1??255?????????????\n" - -#~ msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" -#~ msgstr "???default-cert-level?0?1?2?3??????????\n" - -#~ msgid "invalid min-cert-level; must be 1, 2, or 3\n" -#~ msgstr "???min-cert-level?0?1?2?3??????????\n" - -#~ msgid "Note: simple S2K mode (0) is strongly discouraged\n" -#~ msgstr "*??*: ???S2K???(0)????????????\n" - -#~ msgid "invalid S2K mode; must be 0, 1 or 3\n" -#~ msgstr "???S2K????0?1?3??????????\n" - -#~ msgid "invalid default preferences\n" -#~ msgstr "?????????????\n" - -#~ msgid "invalid personal cipher preferences\n" -#~ msgstr "???????????????\n" - -#~ msgid "invalid personal digest preferences\n" -#~ msgstr "?????????????????\n" - -#~ msgid "invalid personal compress preferences\n" -#~ msgstr "?????????????\n" - -#~ msgid "%s does not yet work with %s\n" -#~ msgstr "%s?%s??????????\n" - -#~ msgid "you may not use cipher algorithm '%s' while in %s mode\n" -#~ msgstr "????????'%s'?%s??????????????\n" - -#~ msgid "you may not use digest algorithm '%s' while in %s mode\n" -#~ msgstr "?????????????'%s'?%s??????????????\n" - -#~ msgid "you may not use compression algorithm '%s' while in %s mode\n" -#~ msgstr "????????'%s'?%s??????????????\n" - -#~ msgid "failed to initialize the TrustDB: %s\n" -#~ msgstr "???????????????????: %s\n" - -#~ msgid "WARNING: recipients (-r) given without using public key encryption\n" -#~ msgstr "*??*: ?????????????? (-r) ????????\n" - -#~ msgid "--store [filename]" -#~ msgstr "--store [?????]" - -#~ msgid "--symmetric [filename]" -#~ msgstr "--symmetric [?????]" - -#~ msgid "symmetric encryption of '%s' failed: %s\n" -#~ msgstr "'%s'?????????????: %s\n" - -#~ msgid "--encrypt [filename]" -#~ msgstr "--encrypt [?????]" - -#~ msgid "--symmetric --encrypt [filename]" -#~ msgstr "--symmetric --encrypt [?????]" - -#~ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" -#~ msgstr "--symmetric --encrypt?--s2k-mode 0???????????\n" - -#~ msgid "you cannot use --symmetric --encrypt while in %s mode\n" -#~ msgstr "--symmetric --encrypt?%s??????????????\n" - -#~ msgid "--sign [filename]" -#~ msgstr "--sign [?????]" - -#~ msgid "--sign --encrypt [filename]" -#~ msgstr "--sign --encrypt [?????]" - -#~ msgid "--symmetric --sign --encrypt [filename]" -#~ msgstr "--symmetric --sign --encrypt [?????]" - -#~ msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" -#~ msgstr "--symmetric --sign --encrypt?--s2k-mode 0???????????\n" - -#~ msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n" -#~ msgstr "--symmetric --sign --encrypt?%s??????????????\n" - -#~ msgid "--sign --symmetric [filename]" -#~ msgstr "--sign --symmetric [?????]" - -#~ msgid "--clearsign [filename]" -#~ msgstr "--clearsign [?????]" - -#~ msgid "--decrypt [filename]" -#~ msgstr "--decrypt [?????]" - -#~ msgid "--sign-key user-id" -#~ msgstr "--sign-key ???id" - -#~ msgid "--lsign-key user-id" -#~ msgstr "--lsign-key ???id" - -#~ msgid "--edit-key user-id [commands]" -#~ msgstr "--edit-key ???id [????]" - -#~ msgid "--passwd " -#~ msgstr "--passwd " - -#~ msgid "keyserver receive failed: %s\n" -#~ msgstr "????????????????: %s\n" - -#~ msgid "key export failed: %s\n" -#~ msgstr "???????????????: %s\n" - -#~ msgid "export as ssh key failed: %s\n" -#~ msgstr "ssh??????????????????: %s\n" - -#~ msgid "keyserver search failed: %s\n" -#~ msgstr "??????????????: %s\n" - -#~ msgid "keyserver refresh failed: %s\n" -#~ msgstr "??????????????: %s\n" - -#~ msgid "dearmoring failed: %s\n" -#~ msgstr "???????????: %s\n" - -#~ msgid "enarmoring failed: %s\n" -#~ msgstr "?????????: %s\n" - -#~ msgid "invalid hash algorithm '%s'\n" -#~ msgstr "??????????????'%s'??\n" - -#~ msgid "error parsing key specification '%s': %s\n" -#~ msgstr "???'%s'????????: %s\n" - -#~ msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" -#~ msgstr "'%s'?????ID, ??????????keygrip?????????\n" - -#~ msgid "[filename]" -#~ msgstr "[?????]" - -#~ msgid "Go ahead and type your message ...\n" -#~ msgstr "??????????????????? ...\n" - -#~ msgid "the given certification policy URL is invalid\n" -#~ msgstr "?????????????URL?????\n" - -#~ msgid "the given signature policy URL is invalid\n" -#~ msgstr "????????????URL?????\n" - -#~ msgid "the given preferred keyserver URL is invalid\n" -#~ msgstr "???????????URL?????\n" - -#~ msgid "show key during import" -#~ msgstr "????????????" - -#~ msgid "run import filters and export key immediately" -#~ msgstr "????????????????????????????" - -#~ msgid "User ID revocation failed: %s\n" -#~ msgstr "???ID??????????: %s\n" - -#~ msgid "tried to revoke a non-user ID: %s\n" -#~ msgstr "???ID????????????????: %s\n" - #~ msgid "you found a bug ... (%s:%d)\n" #~ msgstr "????????????? ... (%s:%d)\n" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 720 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 379 insertions(+), 341 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 10:32:29 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 04 Aug 2016 10:32:29 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.30-10-gcaff669 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 caff669212d2465a3a387571305a7230d394c0e0 (commit) from b531f2fd75be3f616073cba714d73324525fd3e4 (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 caff669212d2465a3a387571305a7230d394c0e0 Author: NIIBE Yutaka Date: Thu Aug 4 16:21:39 2016 +0900 g10: Fix checking key for signature validation. * g10/sig-check.c (signature_check2): Not only subkey, but also primary key should have flags.valid=1. -- (backport of master commit 6f284e6ed63f514b15fe610f490ffcefc87a2164) Signed-off-by: NIIBE Yutaka diff --git a/g10/sig-check.c b/g10/sig-check.c index fc5e1fa..7178d06 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -82,9 +82,9 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, } else if( get_pubkey( pk, sig->keyid ) ) rc = G10ERR_NO_PUBKEY; - else if(!pk->is_valid && !pk->is_primary) + else if(!pk->is_valid) rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an - invalid subkey */ + invalid key */ else { if(r_expiredate) ----------------------------------------------------------------------- Summary of changes: g10/sig-check.c | 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 Thu Aug 4 10:32:52 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 04 Aug 2016 10:32:52 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-16-gf474b16 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 f474b161f6c8c7a3dc0fb90d25ffceacba1ff117 (commit) from 0f6bda4ccd2091e386e78c369131388ae5ebc002 (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 f474b161f6c8c7a3dc0fb90d25ffceacba1ff117 Author: NIIBE Yutaka Date: Thu Aug 4 16:21:39 2016 +0900 g10: Fix checking key for signature validation. * g10/sig-check.c (signature_check2): Not only subkey, but also primary key should have flags.valid=1. -- (backport of master commit 6f284e6ed63f514b15fe610f490ffcefc87a2164) Signed-off-by: NIIBE Yutaka diff --git a/g10/sig-check.c b/g10/sig-check.c index 6bac630..8dd0373 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -76,9 +76,9 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, } else if( get_pubkey( pk, sig->keyid ) ) rc = G10ERR_NO_PUBKEY; - else if(!pk->is_valid && !pk->is_primary) + else if(!pk->is_valid) rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an - invalid subkey */ + invalid key */ else { if(r_expiredate) ----------------------------------------------------------------------- Summary of changes: g10/sig-check.c | 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 Thu Aug 4 12:11:27 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Thu, 04 Aug 2016 12:11:27 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-43-g05cb300 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 05cb30052cdf1d308ff7da901cfa5a809cd49479 (commit) via 3566544d04a4b81e5dd8a2883304673b2cc2f108 (commit) from 89234f7f3643bad2daddc94569f1d651ec5c835e (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 05cb30052cdf1d308ff7da901cfa5a809cd49479 Author: Justus Winter Date: Thu Aug 4 12:10:47 2016 +0200 tests: Update list of tests in Scheme test runner. * tests/openpgp/run-tests.scm: Add missing tests. Signed-off-by: Justus Winter diff --git a/tests/openpgp/run-tests.scm b/tests/openpgp/run-tests.scm index ad94baf..367c641 100644 --- a/tests/openpgp/run-tests.scm +++ b/tests/openpgp/run-tests.scm @@ -192,9 +192,15 @@ "import.scm" "ecc.scm" "4gb-packet.scm" + "tofu.scm" "gpgtar.scm" "use-exact-key.scm" - "default-key.scm")) + "default-key.scm" + "export.scm" + "ssh.scm" + "issue2015.scm" + "issue2346.scm" + "issue2419.scm")) (let* ((runner (if (member "--parallel" *args*) (if (member "--shared" *args*) commit 3566544d04a4b81e5dd8a2883304673b2cc2f108 Author: Justus Winter Date: Thu Aug 4 12:09:52 2016 +0200 tests: Fix path to fake-pinentry. * tests/openpgp/defs.scm: Correctly compute the path to fake-pinentry. Signed-off-by: Justus Winter diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index 9408cd5..2cbad46 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -60,7 +60,8 @@ "agent/gpg-preset-passphrase") (mktdata "MKTDATA" "tools/mk-tdata") (gpgtar "GPGTAR" "tools/gpgtar") - (gpg-zip "GPGZIP" "tools/gpg-zip"))) + (gpg-zip "GPGZIP" "tools/gpg-zip") + (pinentry "PINENTRY" "tests/openpgp/fake-pinentry"))) (define (tool which) (let ((t (assoc which tools)) @@ -77,7 +78,7 @@ (define GPG `(,(tool 'gpg) --no-permission-warning ,@(if have-opt-always-trust '(--always-trust) '()))) -(define PINENTRY (string-append (getcwd) "/" (qualify "fake-pinentry"))) +(define PINENTRY (tool 'pinentry)) (define (tr:gpg input args) (tr:spawn input `(, at GPG --output **out** , at args **in**))) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/defs.scm | 5 +++-- tests/openpgp/run-tests.scm | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 12:38:59 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Thu, 04 Aug 2016 12:38:59 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-18-g15d1327 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 15d13272344fa0d8753a321c087b30a6d5115dfb (commit) via 1820889e3c4a9a07981951b3e74f722658fb01c5 (commit) from f474b161f6c8c7a3dc0fb90d25ffceacba1ff117 (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 15d13272344fa0d8753a321c087b30a6d5115dfb Author: Daniel Kahn Gillmor Date: Wed Aug 3 11:56:56 2016 -0400 Clean up "allow to" * README, cipher/cipher.c, cipher/pubkey.c, doc/gpg.texi: replace "allow to" with clearer text In standard English, the normal construction is "${XXX} allows ${YYY} to" -- that is, the subject (${XXX}) of the sentence is allowing the object (${YYY}) to do something. When the object is missing, the phrasing sounds awkward, even if the object is implied by context. There's almost always a better construction that isn't as awkward. These changes should make the language a bit clearer. Signed-off-by: Daniel Kahn Gillmor diff --git a/README b/README index 85b29d0..1a331fb 100644 --- a/README +++ b/README @@ -632,7 +632,7 @@ is in general the preferable solution. However the code is new and under some cirumstances it may give different output than with the limited old - support. This option allows to explicity disable + support. This option explicitly disables the use of iconv. Note, that iconv is also disabled if gettext has been disabled. diff --git a/cipher/cipher.c b/cipher/cipher.c index 4ef0d81..f55ce8b 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -586,7 +586,7 @@ do_cfb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) /* Now we can process complete blocks. We use a loop as long as we have at least 2 blocks and use conditions for the rest. This - also allows to use a bulk encryption function if available. */ + also allows use of a bulk encryption function if available. */ #ifdef USE_AES if (nbytes >= blocksize_x_2 && (c->algo == CIPHER_ALGO_AES @@ -677,7 +677,7 @@ do_cfb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) /* Now we can process complete blocks. We use a loop as long as we have at least 2 blocks and use conditions for the rest. This - also allows to use a bulk encryption function if available. */ + also allows use of a bulk encryption function if available. */ #ifdef USE_AES if (nbytes >= blocksize_x_2 && (c->algo == CIPHER_ALGO_AES diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 02c096e..60d855c 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -276,7 +276,7 @@ check_pubkey_algo2( int algo, unsigned use ) int i; /* Map type 20 Elgamal algorithm to type 16 if it is used for - decryption. This allows to use legacy type 20 Elgamal keys for + decryption. This allows use of legacy type 20 Elgamal keys for decryption. */ if (algo == PUBKEY_ALGO_ELGAMAL && use == PUBKEY_USAGE_ENC) algo = PUBKEY_ALGO_ELGAMAL_E; diff --git a/doc/gpg.texi b/doc/gpg.texi index ee756d8..a41ab8e 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1211,7 +1211,7 @@ Use @code{file} to access the smartcard reader. The current default is @item --disable-ccid @opindex disable-ccid Disable the integrated support for CCID compliant readers. This -allows to fall back to one of the other drivers even if the internal +allows falling back to one of the other drivers even if the internal CCID driver can handle the reader. Note, that CCID support is only available if libusb was available at build time. @@ -1438,7 +1438,7 @@ mechanisms, in the order they are to be tried: may be used here to query that particular keyserver. @item local - Locate the key using the local keyrings. This mechanism allows to + Locate the key using the local keyrings. This mechanism allows the user to select the order a local key lookup is done. Thus using @samp{--auto-key-locate local} is identical to @option{--no-auto-key-locate}. @@ -2416,7 +2416,7 @@ to display the message. This option overrides @option{--set-filename}. @itemx --no-use-embedded-filename @opindex use-embedded-filename Try to create a file with a name as embedded in the data. This can be -a dangerous option as it allows to overwrite files. Defaults to no. +a dangerous option as it enables overwriting files. Defaults to no. @item --cipher-algo @code{name} @opindex cipher-algo commit 1820889e3c4a9a07981951b3e74f722658fb01c5 Author: Daniel Kahn Gillmor Date: Wed Aug 3 11:56:55 2016 -0400 Fix spelling: "occured" should be "occurred" * checks/armor.test, cipher/des.c, g10/ccid-driver.c, g10/pkclist.c, util/regcomp.c, util/regex_internal.c: correct the spelling of "occured" to "occurred" Signed-off-by: Daniel Kahn Gillmor diff --git a/checks/armor.test b/checks/armor.test index cfd2359..a23f8d8 100755 --- a/checks/armor.test +++ b/checks/armor.test @@ -734,7 +734,7 @@ wg7Md81a5RI3F2FG8747t9gX ' # Bug 1179 solved 2010-05-12: -# It occured for messages of a multiple of the iobuf block size where +# It occurred for messages of a multiple of the iobuf block size where # the last line had no pad character. Due to premature popping of the # armor filter gpg swalled the CRC line and passed the '-----END...' # line on to the decryption layer. diff --git a/cipher/des.c b/cipher/des.c index 670ba65..7eaa2df 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -104,7 +104,7 @@ * * if ( (error_msg = selftest()) ) * { - * fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg); + * fprintf(stderr, "An error in the DES/Tripple-DES implementation occurred: %s\n", error_msg); * abort(); * } */ diff --git a/g10/ccid-driver.c b/g10/ccid-driver.c index 515b15a..6f7c9b2 100644 --- a/g10/ccid-driver.c +++ b/g10/ccid-driver.c @@ -2264,7 +2264,7 @@ ccid_poll (ccid_driver_t handle) } else if (msg[0] == RDR_to_PC_HardwareError) { - DEBUGOUT ("hardware error occured\n"); + DEBUGOUT ("hardware error occurred\n"); } else { diff --git a/g10/pkclist.c b/g10/pkclist.c index 198e307..b78070e 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -952,7 +952,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) } /* Do group expand here too. The trick here is to continue - the loop if any expansion occured. The code above will + the loop if any expansion occurred. The code above will then list all expanded keys. */ if (expand_id(answer,&backlog,0)) continue; diff --git a/util/regcomp.c b/util/regcomp.c index 6964df9..aafb9c8 100644 --- a/util/regcomp.c +++ b/util/regcomp.c @@ -1764,7 +1764,7 @@ peek_token_bracket (token, input, syntax) /* Entry point of the parser. Parse the regular expression REGEXP and return the structure tree. - If an error is occured, ERR is set by error code, and return NULL. + If an error is occurred, ERR is set by error code, and return NULL. This function build the following tree, from regular expression : CAT / \ @@ -3349,7 +3349,7 @@ build_word_op (dfa, not, err) /* This is intended for the expressions like "a{1,3}". Fetch a number from `input', and return the number. Return -1, if the number field is empty like "{,1}". - Return -2, If an error is occured. */ + Return -2, If an error is occurred. */ static int fetch_number (input, token, syntax) diff --git a/util/regex_internal.c b/util/regex_internal.c index 6f3a96e..4349f1b 100644 --- a/util/regex_internal.c +++ b/util/regex_internal.c @@ -793,7 +793,7 @@ re_node_set_merge (dest, src) /* Insert the new element ELEM to the re_node_set* SET. return 0 if SET already has ELEM, - return -1 if an error is occured, return 1 otherwise. */ + return -1 if an error is occurred, return 1 otherwise. */ static int re_node_set_insert (set, elem) @@ -909,7 +909,7 @@ re_node_set_remove_at (set, idx) /* Add the token TOKEN to dfa->nodes, and return the index of the token. - Or return -1, if an error will be occured. */ + Or return -1, if an error will be occurred. */ static int re_dfa_add_node (dfa, token, mode) ----------------------------------------------------------------------- Summary of changes: README | 2 +- checks/armor.test | 2 +- cipher/cipher.c | 4 ++-- cipher/des.c | 2 +- cipher/pubkey.c | 2 +- doc/gpg.texi | 6 +++--- g10/ccid-driver.c | 2 +- g10/pkclist.c | 2 +- util/regcomp.c | 4 ++-- util/regex_internal.c | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 12:58:43 2016 From: cvs at cvs.gnupg.org (by Ben Kibbey) Date: Thu, 04 Aug 2016 12:58:43 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-22-g2227f67 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 2227f67af53f38d3d7f97760f2553d2c9ed05969 (commit) from 2f1f1f06c1885d2f5a30ea734359613609be0743 (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 2227f67af53f38d3d7f97760f2553d2c9ed05969 Author: Ben Kibbey Date: Mon Aug 1 21:25:32 2016 -0400 Fix ncurses build. * pinentry/Makefile.am: Add NCURSES_CFLAGS. Signed-off-by: Ben Kibbey diff --git a/pinentry/Makefile.am b/pinentry/Makefile.am index be99822..a99f12e 100644 --- a/pinentry/Makefile.am +++ b/pinentry/Makefile.am @@ -41,3 +41,4 @@ AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir)/secmem libpinentry_a_SOURCES = pinentry.h pinentry.c argparse.c argparse.h \ password-cache.h password-cache.c $(pinentry_emacs_sources) libpinentry_curses_a_SOURCES = pinentry-curses.h pinentry-curses.c +libpinentry_curses_a_CFLAGS = @NCURSES_CFLAGS@ ----------------------------------------------------------------------- Summary of changes: pinentry/Makefile.am | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 14:16:51 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 04 Aug 2016 14:16:51 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-45-g0c2a745 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 0c2a745a2bc21e8f439930f7c0e5d1521c2fd44c (commit) via db6f3eb926619dfe6ed2a9be197c51f9a1b6198c (commit) from 05cb30052cdf1d308ff7da901cfa5a809cd49479 (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 0c2a745a2bc21e8f439930f7c0e5d1521c2fd44c Author: Werner Koch Date: Thu Aug 4 13:04:28 2016 +0200 tests: Use gpgconf to set the ssh socket envvar. * tests/openpgp/ssh.scm ("SSH_AUTH_SOCK"): Use gpgconf. Signed-off-by: Werner Koch diff --git a/tests/openpgp/ssh.scm b/tests/openpgp/ssh.scm index fe0b115..dfa1f52 100755 --- a/tests/openpgp/ssh.scm +++ b/tests/openpgp/ssh.scm @@ -23,7 +23,9 @@ (if (string=? "" GNUPGHOME) (error "GNUPGHOME not set")) -(setenv "SSH_AUTH_SOCK" (path-join GNUPGHOME "S.gpg-agent.ssh") #t) +(setenv "SSH_AUTH_SOCK" + (call-check `(,(tool 'gpgconf) --null --list-dirs agent-ssh-socket)) + #t) (define SSH-ADD #f) (catch (skip "ssh-add not found") commit db6f3eb926619dfe6ed2a9be197c51f9a1b6198c Author: Werner Koch Date: Thu Aug 4 13:02:37 2016 +0200 gpgconf: Add limited support for -0. * tools/gpgconf.h (opt): Add field 'null'. * tools/gpgconf.c: Add option --null/-0. (list_dirs): Use it here. -- This option changes the delimites for --list-dir with arguments from LF to Nul. Signed-off-by: Werner Koch diff --git a/tools/gpgconf.c b/tools/gpgconf.c index ad61511..f7ce4c9 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -40,6 +40,7 @@ enum cmd_and_opt_values oVerbose = 'v', oRuntime = 'r', oComponent = 'c', + oNull = '0', oNoVerbose = 500, oHomedir, @@ -93,6 +94,7 @@ static ARGPARSE_OPTS opts[] = { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, /* hidden options */ { oHomedir, "homedir", 2, "@" }, + { oNull, "null", 0, "@" }, { oNoVerbose, "no-verbose", 0, "@"}, {0} }; @@ -197,7 +199,10 @@ list_dirs (estream_t fp, char **names) { for (j=0; names[j]; j++) if (!strcmp (names[j], list[idx].name)) - es_fprintf (fp, "%s\n", s); + { + es_fputs (s, fp); + es_putc (opt.null? '\0':'\n', fp); + } } xfree (tmp); @@ -241,6 +246,7 @@ main (int argc, char **argv) case oVerbose: opt.verbose++; break; case oNoVerbose: opt.verbose = 0; break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; + case oNull: opt.null = 1; break; case aListDirs: case aListComponents: diff --git a/tools/gpgconf.h b/tools/gpgconf.h index d63833d..a1e3828 100644 --- a/tools/gpgconf.h +++ b/tools/gpgconf.h @@ -29,6 +29,7 @@ struct int quiet; /* Be extra quiet. */ int dry_run; /* Don't change any persistent data. */ int runtime; /* Make changes active at runtime. */ + int null; /* Option -0 active. */ char *outfile; /* Name of output file. */ int component; /* The active component. */ ----------------------------------------------------------------------- Summary of changes: tests/openpgp/ssh.scm | 4 +++- tools/gpgconf.c | 8 +++++++- tools/gpgconf.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 15:12:08 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 04 Aug 2016 15:12:08 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-46-g54a1ed2 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 54a1ed20e203dcafeacbe21eb147efa08255dbf5 (commit) from 0c2a745a2bc21e8f439930f7c0e5d1521c2fd44c (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 54a1ed20e203dcafeacbe21eb147efa08255dbf5 Author: Werner Koch Date: Thu Aug 4 15:01:42 2016 +0200 gpg: Always print the fingerprint in colons mode. * g10/keylist.c (list_keyblock_colon): Remove arg FPR. Always print fingerprint records. For secret keys always print keygrip records. -- The fingerprint should always be used thus we should always print it. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 4d6a261..c544967 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2378,7 +2378,8 @@ Print the ICAO spelling of the fingerprint in addition to the hex digits. @item --with-keygrip @opindex with-keygrip -Include the keygrip in the key listings. +Include the keygrip in the key listings. In @code{--with-colons} mode +this is implicitly enable for secret keys. @item --with-wkd-hash @opindex with-wkd-hash diff --git a/g10/keylist.c b/g10/keylist.c index 2c99502..1ba9212 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1175,7 +1175,7 @@ print_revokers (estream_t fp, PKT_public_key * pk) secret key is available even if SECRET is not set. */ static void list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, - int secret, int has_secret, int fpr) + int secret, int has_secret) { int rc; KBNODE kbctx; @@ -1271,15 +1271,11 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, es_putc ('\n', es_stdout); print_revokers (es_stdout, pk); - if (fpr) - print_fingerprint (NULL, pk, 0); - if (opt.with_key_data || opt.with_keygrip) - { - if (hexgrip) - es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip); - if (opt.with_key_data) - print_key_data (pk); - } + print_fingerprint (NULL, pk, 0); + if (hexgrip) + es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip); + if (opt.with_key_data) + print_key_data (pk); for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));) { @@ -1408,15 +1404,11 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, } es_putc (':', es_stdout); /* End of field 17. */ es_putc ('\n', es_stdout); - if (fpr > 1) - print_fingerprint (NULL, pk2, 0); - if (opt.with_key_data || opt.with_keygrip) - { - if (hexgrip) - es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip); - if (opt.with_key_data) - print_key_data (pk2); - } + print_fingerprint (NULL, pk2, 0); + if (hexgrip) + es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip); + if (opt.with_key_data) + print_key_data (pk2); } else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE) { @@ -1599,7 +1591,7 @@ list_keyblock (ctrl_t ctrl, reorder_keyblock (keyblock); if (opt.with_colons) - list_keyblock_colon (ctrl, keyblock, secret, has_secret, fpr); + list_keyblock_colon (ctrl, keyblock, secret, has_secret); else list_keyblock_print (ctrl, keyblock, secret, fpr, listctx); ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 3 ++- g10/keylist.c | 32 ++++++++++++-------------------- 2 files changed, 14 insertions(+), 21 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 16:20:13 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 04 Aug 2016 16:20:13 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-257-g6f3dc66 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 6f3dc66634e30d86aa6250c4ac22f9b8f7ec1be9 (commit) from 56e26b54da9f16961209275d7a61883d3ea898ca (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 6f3dc66634e30d86aa6250c4ac22f9b8f7ec1be9 Author: Werner Koch Date: Thu Aug 4 16:17:01 2016 +0200 core: Extend gpgme_subkey_t to carry the keygrip. * src/gpgme.h.in (struct _gpgme_subkey): Add file 'keygrip'. * src/key.c (gpgme_key_unref): Free KEYGRIP. * src/keylist.c (keylist_colon_handler): Parse GRP records. * src/engine-gpg.c (gpg_keylist_build_options): Do not use --with-fingerprint options for gpg versions >= 2.1.15. * tests/run-keylist.c (main): Print subkeys and keygrips. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index bb31a50..09d0a1c 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] GPGME_PK_EDDSA NEW. gpgme_set_ctx_flag NEW. gpgme_signature_t EXTENDED: New field tofu. + gpgme_subkey_t EXTENDED: New field keygrip. gpgme_tofu_policy_t NEW. gpgme_tofu_info_t NEW. GPGME_STATUS_KEY_CONSIDERED NEW. diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 16571a5..942711f 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2283,12 +2283,19 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only, gpg_error_t err; err = add_arg (gpg, "--with-colons"); - if (!err) - err = add_arg (gpg, "--fixed-list-mode"); - if (!err) - err = add_arg (gpg, "--with-fingerprint"); - if (!err) - err = add_arg (gpg, "--with-fingerprint"); + + /* Since gpg 2.1.15 fingerprints are always printed, thus there is + * no more need to explictly reqeust them. */ + if (!have_gpg_version (gpg, "2.1.15")) + { + if (!err) + err = add_arg (gpg, "--fixed-list-mode"); + if (!err) + err = add_arg (gpg, "--with-fingerprint"); + if (!err) + err = add_arg (gpg, "--with-fingerprint"); + } + if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET)) err = add_arg (gpg, "--with-secret"); if (!err diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 49d56c3..c05686d 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -691,6 +691,9 @@ struct _gpgme_subkey /* The name of the curve for ECC algorithms or NULL. */ char *curve; + + /* The keygrip of the subkey in hex digit form or NULL if not availabale. */ + char *keygrip; }; typedef struct _gpgme_subkey *gpgme_subkey_t; diff --git a/src/key.c b/src/key.c index 1a68966..de97102 100644 --- a/src/key.c +++ b/src/key.c @@ -333,6 +333,8 @@ gpgme_key_unref (gpgme_key_t key) free (subkey->fpr); if (subkey->curve) free (subkey->curve); + if (subkey->keygrip) + free (subkey->keygrip); if (subkey->card_number) free (subkey->card_number); free (subkey); diff --git a/src/keylist.c b/src/keylist.c index fcf574f..5a346ea 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -426,7 +426,7 @@ keylist_colon_handler (void *priv, char *line) gpgme_ctx_t ctx = (gpgme_ctx_t) priv; enum { - RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, + RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_GRP, RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK } rectype = RT_NONE; @@ -479,6 +479,8 @@ keylist_colon_handler (void *priv, char *line) rectype = RT_CRS; else if (!strcmp (field[0], "fpr") && key) rectype = RT_FPR; + else if (!strcmp (field[0], "grp") && key) + rectype = RT_GRP; else if (!strcmp (field[0], "uid") && key) rectype = RT_UID; else if (!strcmp (field[0], "sub") && key) @@ -717,6 +719,22 @@ keylist_colon_handler (void *priv, char *line) } break; + case RT_GRP: + /* Field 10 has the keygrip. */ + if (fields >= 10 && field[9] && *field[9]) + { + /* Need to apply it to the last subkey because all subkeys + have a keygrip. */ + subkey = key->_last_subkey; + if (!subkey->keygrip) + { + subkey->keygrip = strdup (field[9]); + if (!subkey->keygrip) + return gpg_error_from_syserror (); + } + } + break; + case RT_SIG: case RT_REV: if (!opd->tmp_uid) diff --git a/tests/run-keylist.c b/tests/run-keylist.c index 8abdf43..fc0f066 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -67,6 +67,7 @@ main (int argc, char **argv) gpgme_ctx_t ctx; gpgme_keylist_mode_t mode = 0; gpgme_key_t key; + gpgme_subkey_t subkey; gpgme_keylist_result_t result; int import = 0; gpgme_key_t keyarray[100]; @@ -173,22 +174,54 @@ main (int argc, char **argv) { gpgme_user_id_t uid; int nuids; - + int nsub; printf ("keyid : %s\n", key->subkeys?nonnull (key->subkeys->keyid):"?"); printf ("fpr : %s\n", key->subkeys?nonnull (key->subkeys->fpr):"?"); + if (key->subkeys && key->subkeys->keygrip) + printf ("grip : %s\n", key->subkeys->keygrip); + if (key->subkeys && key->subkeys->curve) + printf ("curve : %s\n", key->subkeys->curve); printf ("caps : %s%s%s%s\n", key->can_encrypt? "e":"", key->can_sign? "s":"", key->can_certify? "c":"", key->can_authenticate? "a":""); - printf ("flags :%s%s%s%s%s%s\n", + printf ("flags :%s%s%s%s%s%s%s\n", key->secret? " secret":"", key->revoked? " revoked":"", key->expired? " expired":"", key->disabled? " disabled":"", key->invalid? " invalid":"", - key->is_qualified? " qualifid":""); + key->is_qualified? " qualifid":"", + key->subkeys && key->subkeys->is_cardkey? " cardkey":""); + + subkey = key->subkeys; + if (subkey) + subkey = subkey->next; + for (nsub=1; subkey; subkey = subkey->next, nsub++) + { + printf ("fpr %2d: %s\n", nsub, nonnull (subkey->fpr)); + if (subkey->keygrip) + printf ("grip %2d: %s\n", nsub, subkey->keygrip); + if (subkey->curve) + printf ("curve %2d: %s\n", nsub, subkey->curve); + printf ("caps %2d: %s%s%s%s\n", + nsub, + subkey->can_encrypt? "e":"", + subkey->can_sign? "s":"", + subkey->can_certify? "c":"", + subkey->can_authenticate? "a":""); + printf ("flags %2d:%s%s%s%s%s%s%s\n", + nsub, + subkey->secret? " secret":"", + subkey->revoked? " revoked":"", + subkey->expired? " expired":"", + subkey->disabled? " disabled":"", + subkey->invalid? " invalid":"", + subkey->is_qualified? " qualifid":"", + subkey->is_cardkey? " cardkey":""); + } for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++) { printf ("userid %d: %s\n", nuids, nonnull(uid->uid)); @@ -201,6 +234,8 @@ main (int argc, char **argv) uid->validity == GPGME_VALIDITY_ULTIMATE? "ultimate": "[?]"); } + + putchar ('\n'); if (import) ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + src/engine-gpg.c | 19 +++++++++++++------ src/gpgme.h.in | 3 +++ src/key.c | 2 ++ src/keylist.c | 20 +++++++++++++++++++- tests/run-keylist.c | 41 ++++++++++++++++++++++++++++++++++++++--- 6 files changed, 76 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 4 19:08:57 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 04 Aug 2016 19:08:57 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-47-gc8cc804 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 c8cc804f56bfefba46641f2c7078fcd67b494bae (commit) from 54a1ed20e203dcafeacbe21eb147efa08255dbf5 (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 c8cc804f56bfefba46641f2c7078fcd67b494bae Author: Werner Koch Date: Thu Aug 4 15:34:14 2016 +0200 gpg: Make sure that keygrips are printed for each subkey. * g10/keylist.c (list_keyblock_colon): Print an emprty grip in case of an error. Signed-off-by: Werner Koch diff --git a/g10/keylist.c b/g10/keylist.c index 1ba9212..60b8f23 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1186,7 +1186,8 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, int ulti_hack = 0; int i; char *p; - char *hexgrip = NULL; + char *hexgrip_buffer = NULL; + const char *hexgrip = NULL; char *serialno = NULL; int stubkey; @@ -1202,9 +1203,13 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, pk = node->pkt->pkt.public_key; if (secret || has_secret || opt.with_keygrip || opt.with_key_data) { - rc = hexkeygrip_from_pk (pk, &hexgrip); + rc = hexkeygrip_from_pk (pk, &hexgrip_buffer); if (rc) log_error ("error computing a keygrip: %s\n", gpg_strerror (rc)); + /* In the error case we print an empty string so that we have a + * "grp" record for each and subkey - even if it is empty. This + * may help to prevent sync problems. */ + hexgrip = hexgrip_buffer? hexgrip_buffer : ""; } stubkey = 0; if ((secret || has_secret) @@ -1338,16 +1343,19 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, { u32 keyid2[2]; PKT_public_key *pk2; + int need_hexgrip = !!hexgrip; pk2 = node->pkt->pkt.public_key; - xfree (hexgrip); hexgrip = NULL; + xfree (hexgrip_buffer); hexgrip_buffer = NULL; hexgrip = NULL; xfree (serialno); serialno = NULL; - if (secret || has_secret || opt.with_keygrip || opt.with_key_data) + if (need_hexgrip + || secret || has_secret || opt.with_keygrip || opt.with_key_data) { - rc = hexkeygrip_from_pk (pk2, &hexgrip); + rc = hexkeygrip_from_pk (pk2, &hexgrip_buffer); if (rc) log_error ("error computing a keygrip: %s\n", gpg_strerror (rc)); + hexgrip = hexgrip_buffer? hexgrip_buffer : ""; } stubkey = 0; if ((secret||has_secret) @@ -1523,7 +1531,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, } } - xfree (hexgrip); + xfree (hexgrip_buffer); xfree (serialno); } ----------------------------------------------------------------------- Summary of changes: g10/keylist.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 5 12:26:59 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Fri, 05 Aug 2016 12:26:59 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-48-gc9387e4 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 c9387e41db7520d176edd3d6613b85875bdeb32c (commit) from c8cc804f56bfefba46641f2c7078fcd67b494bae (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 c9387e41db7520d176edd3d6613b85875bdeb32c Author: Daniel Kahn Gillmor Date: Thu Aug 4 16:58:13 2016 -0400 gpg: Avoid publishing the GnuPG version by default * g10/gpg.c (main): initialize opt.emit_version to 0 * doc/gpg.texi: document different default for --emit-version -- The version of GnuPG in use is not particularly helpful. It is not cryptographically verifiable, and it doesn't distinguish between significant version differences like 2.0.x and 2.1.x. Additionally, it leaks metadata that can be used to distinguish users from one another, and can potentially be used to target specific attacks if there are known behaviors that differ between major versions. It's probably better to take the more parsimonious approach to metadata production by default. Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpg.texi b/doc/gpg.texi index c544967..ffbc269 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2713,9 +2713,9 @@ protected by the signature. @opindex emit-version Force inclusion of the version string in ASCII armored output. If given once only the name of the program and the major number is -emitted (default), given twice the minor is also emitted, given triple +emitted, given twice the minor is also emitted, given triple the micro is added, and given quad an operating system identification -is also emitted. @option{--no-emit-version} disables the version +is also emitted. @option{--no-emit-version} (default) disables the version line. @item --sig-notation @code{name=value} diff --git a/g10/gpg.c b/g10/gpg.c index 35d350e..b33b61b 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2269,7 +2269,7 @@ main (int argc, char **argv) opt.def_cert_expire = "0"; gnupg_set_homedir (NULL); opt.passphrase_repeat = 1; - opt.emit_version = 1; /* Limit to the major number. */ + opt.emit_version = 0; opt.weak_digests = NULL; additional_weak_digest("MD5"); ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 ++-- g10/gpg.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 5 14:07:27 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 05 Aug 2016 14:07:27 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-258-g2a613e8 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 2a613e87156b23c4aa6aa5ce38505cb285de6a18 (commit) from 6f3dc66634e30d86aa6250c4ac22f9b8f7ec1be9 (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 2a613e87156b23c4aa6aa5ce38505cb285de6a18 Author: Justus Winter Date: Fri Aug 5 14:03:15 2016 +0200 python: Clean up and modernize examples. * lang/python/examples/Examples.rst: Delete file. * lang/python/examples/t-edit.py: Likewise. This is actually a test case and has been moved to 'tests'. * lang/python/examples/assuan.py: New file. * lang/python/examples/decryption-filter.py: Likewise. * lang/python/examples/delkey.py: Modernize. * lang/python/examples/encrypt-to-all.py: Likewise. * lang/python/examples/exportimport.py: Likewise. * lang/python/examples/genkey.py: Likewise. * lang/python/examples/inter-edit.py: Likewise. * lang/python/examples/sign.py: Likewise. * lang/python/examples/signverify.py: Likewise. * lang/python/examples/simple.py: Likewise. * lang/python/examples/testCMSgetkey.py: Likewise. * lang/python/examples/verifydetails.py: Likewise. Signed-off-by: Justus Winter diff --git a/lang/python/examples/Examples.rst b/lang/python/examples/Examples.rst deleted file mode 100644 index 18b03b2..0000000 --- a/lang/python/examples/Examples.rst +++ /dev/null @@ -1,7 +0,0 @@ -=============== -Example Scripts -=============== - -Most of the examples have been converted to work with Python 3, just as the original versions worked with Python 2. A small number produce errors on OS X, but may behave differently on other POSIX systems. The GTK based scripts (PyGtkGpgKeys.py and pygpa.py) have not been modified at all. - -When using or referring to the example scripts here, the most common change has been the byte encoded strings, so if something does not work then chances are that it will be related to the encoding or decoding of UTF-8. diff --git a/lang/python/examples/assuan.py b/lang/python/examples/assuan.py new file mode 100644 index 0000000..82b1e1d --- /dev/null +++ b/lang/python/examples/assuan.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH +# +# 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, see . + +"""Demonstrate the use of the Assuan protocol engine""" + +import pyme + +with pyme.Context(protocol=pyme.constants.PROTOCOL_ASSUAN) as c: + # Invoke the pinentry to get a confirmation. + err = c.assuan_transact(['GET_CONFIRMATION', 'Hello there']) + print("You chose {}.".format("cancel" if err else "ok")) diff --git a/lang/python/examples/decryption-filter.py b/lang/python/examples/decryption-filter.py new file mode 100644 index 0000000..1647ca3 --- /dev/null +++ b/lang/python/examples/decryption-filter.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH +# +# 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, see . + +"""A decryption filter + +This demonstrates decryption using pyme3 in three lines of code. To +be used like this: + +./decryption-filter.py message.plain + +""" + +import sys +import pyme +pyme.Context().decrypt(sys.stdin, sink=sys.stdout) diff --git a/lang/python/examples/delkey.py b/lang/python/examples/delkey.py index 3fb71eb..e607f21 100755 --- a/lang/python/examples/delkey.py +++ b/lang/python/examples/delkey.py @@ -1,35 +1,30 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # -# 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 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. +# 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 -# 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . # Sample of key deletion -# It deletes keys for joe at example.org generated by genkey.pl script - -from pyme import core +# It deletes keys for joe at example.org generated by genkey.py script -core.check_version(None) +import pyme -# Note that we need to collect all keys out of the iterator return by -# c.op_keylist_all() method before starting to delete them. If you -# delete a key in the middle of iteration c.op_keylist_next() will -# raise INV_VALUE exception +with pyme.Context() as c: + # Note: We must not modify the key store during iteration, + # therefore, we explicitly make a list. + keys = list(c.keylist("joe+pyme at example.org")) -c = core.Context() -# 0 in keylist means to list not only public but secret keys as well. -for thekey in [x for x in c.op_keylist_all("joe+pyme at example.org", 0)]: - # 1 in delete means to delete not only public but secret keys as well. - c.op_delete(thekey, 1) + for k in keys: + c.op_delete(k, True) diff --git a/lang/python/examples/encrypt-to-all.py b/lang/python/examples/encrypt-to-all.py index 5e12676..4586f93 100755 --- a/lang/python/examples/encrypt-to-all.py +++ b/lang/python/examples/encrypt-to-all.py @@ -1,21 +1,21 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2008 Igor Belyi # Copyright (C) 2002 John Goerzen # -# 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 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. +# 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 -# 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . """ This program will try to encrypt a simple message to each key on your @@ -24,44 +24,28 @@ be skipped and it will re-try the encryption.""" import sys import os -from pyme import core -from pyme.core import Data, Context - -core.check_version(None) - -plain = Data('This is my message.') - -c = Context() -c.set_armor(1) +import pyme -def sendto(keylist): - cipher = Data() - c.op_encrypt(keylist, 1, plain, cipher) - cipher.seek(0, os.SEEK_SET) - return cipher.read() - -names = [] -for key in c.op_keylist_all(None, 0): - try: - print(" *** Found key for %s" % key.uids[0].uid) +with pyme.Context(armor=True) as c: + recipients = list() + for key in c.keylist(): valid = 0 - for subkey in key.subkeys: - keyid = subkey.keyid - if keyid is None: - break - can_encrypt = subkey.can_encrypt - valid += can_encrypt - print(" Subkey %s: encryption %s" % - (keyid, can_encrypt and "enabled" or "disabled")) - except UnicodeEncodeError as e: - print(e) - - if valid: - names.append(key) - else: - print(" This key cannot be used for encryption; skipping.") - -passno = 0 - -print("Encrypting to %d recipients" % len(names)) -sys.stdout.buffer.write(sendto(names)) + if any(sk.can_encrypt for sk in key.subkeys): + recipients.append(key) + print("Adding recipient {0}.".format(key.uids[0].uid)) + + ciphertext = None + while not ciphertext: + print("Encrypting to %d recipients" % len(recipients)) + try: + ciphertext, _, _ = c.encrypt(b'This is my message.', + recipients=recipients) + except pyme.errors.InvalidRecipients as e: + print("Encryption failed for these keys:\n{0!s}".format(e)) + + # filter out the bad keys + bad_keys = {bad.fpr for bad in e.recipients} + recipients = [r for r in recipients + if not r.subkeys[0].fpr in bad_keys] + + sys.stdout.buffer.write(ciphertext) diff --git a/lang/python/examples/exportimport.py b/lang/python/examples/exportimport.py index d0e1fa8..39b1595 100755 --- a/lang/python/examples/exportimport.py +++ b/lang/python/examples/exportimport.py @@ -1,75 +1,58 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # -# 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 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. +# 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 -# 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . # Sample of export and import of keys -# It uses keys for joe at example.org generated by genkey.pl script +# It uses keys for joe+pyme at example.org generated by genkey.py script import sys -from pyme import core - -core.check_version(None) - -expkey = core.Data() -c = core.Context() -c.set_armor(1) -user = b"joe at example.org" - -print(" - Export %s's public keys - " % user) -c.op_export(user, 0, expkey) - -# print out exported data to see how it looks in armor. -expkey.seek(0, 0) -expstring = expkey.read() -if expstring: - print(expstring) -else: - print("No %s's keys to export!" % user) - sys.exit(0) - - -# delete keys to ensure that they came from our imported data. -# Note that since joe's key has private part as well we can only delete -# both of them. As a side effect joe won't have private key for this -# exported public one. If it's Ok with you uncomment the next 4 lines. -# print " - Delete %s's public keys - " % user -# for thekey in [x for x in c.op_keylist_all(user, 0)]: -# if not thekey.secret: -# c.op_delete(thekey, 1) - - -# initialize import data from a string as if it was read from a file. -newkey = core.Data(expstring) - -print(" - Import exported keys - ") -c.op_import(newkey) -result = c.op_import_result() - -# show the import result -if result: - print(" - Result of the import - ") - for k in dir(result): - if k not in result.__dict__ and not k.startswith("_"): - if k == "imports": - print(k, ":") - for impkey in result.__getattr__(k): - print(" fpr=%s result=%d status=%x" % - (impkey.fpr, impkey.result, impkey.status)) - else: - print(k, ":", result.__getattr__(k)) -else: - print(" - No import result - ") +import os +import pyme + +user = "joe+pyme at example.org" + +with pyme.Context(armor=True) as c, pyme.Data() as expkey: + print(" - Export %s's public keys - " % user) + c.op_export(user, 0, expkey) + + # print out exported data to see how it looks in armor. + expkey.seek(0, os.SEEK_SET) + expstring = expkey.read() + if expstring: + sys.stdout.buffer.write(expstring) + else: + sys.exit("No %s's keys to export!" % user) + +# delete keys to ensure that they came from our imported data. Note +# that if joe's key has private part as well we can only delete both +# of them. +with pyme.Context() as c: + # Note: We must not modify the key store during iteration, + # therfore, we explicitly make a list. + keys = list(c.keylist(user)) + + for k in keys: + c.op_delete(k, True) + +with pyme.Context() as c: + print(" - Import exported keys - ") + c.op_import(expstring) + result = c.op_import_result() + if result: + print(result) + else: + sys.exit(" - No import result - ") diff --git a/lang/python/examples/genkey.py b/lang/python/examples/genkey.py index d5a88a7..66e382b 100755 --- a/lang/python/examples/genkey.py +++ b/lang/python/examples/genkey.py @@ -1,31 +1,25 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # -# 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 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. +# 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 02111-1307 USA - -from pyme import core, callbacks - -# Initialize our context. -core.check_version(None) +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . -c = core.Context() -c.set_armor(1) -c.set_progress_cb(callbacks.progress_stdout, None) +import pyme -# This example from the GPGME manual +# This is the example from the GPGME manual. parms = """ Key-Type: RSA @@ -40,5 +34,8 @@ Expire-Date: 2020-12-31 """ -c.op_genkey(parms, None, None) -print(c.op_genkey_result().fpr) +with pyme.Context() as c: + c.set_progress_cb(pyme.callbacks.progress_stdout) + c.op_genkey(parms, None, None) + print("Generated key with fingerprint {0}.".format( + c.op_genkey_result().fpr)) diff --git a/lang/python/examples/inter-edit.py b/lang/python/examples/inter-edit.py index dcb47c2..8199cc6 100644 --- a/lang/python/examples/inter-edit.py +++ b/lang/python/examples/inter-edit.py @@ -1,58 +1,60 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2005 Igor Belyi # -# 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 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. +# 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 -# 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . -import sys -from pyme import core -from pyme.core import Data, Context -from pyme.constants import status +"""Simple interactive editor to test editor scripts""" -core.check_version(None) +import sys +import pyme +import pyme.constants.status # Get names for the status codes -stat2str = {} -for name in dir(status): +status2str = {} +for name in dir(pyme.constants.status): if not name.startswith('__') and name != "util": - stat2str[getattr(status, name)] = name - - -# Print the output received since the last prompt before giving the new prompt -def edit_fnc(stat, args, helper): - global stat_strings - try: - while True: - helper["data"].seek(helper["skip"], 0) - data = helper["data"].read() - helper["skip"] += len(data) - sys.stdout.buffer.write(data) - return input("(%s) %s > " % (stat2str[stat], args)) - except EOFError: - pass - -# Simple interactive editor to test editor scripts + status2str[getattr(pyme.constants.status, name)] = name + if len(sys.argv) != 2: - sys.stderr.write("Usage: %s \n" % sys.argv[0]) -else: - c = Context() - out = Data() - c.op_keylist_start(sys.argv[1], 0) - key = c.op_keylist_next() - helper = {"skip": 0, "data": out} - c.op_edit(key, edit_fnc, helper, out) - print("[-- Final output --]") - out.seek(helper["skip"], 0) - sys.stdout.buffer.write(out.read()) + sys.exit("Usage: %s \n" % sys.argv[0]) + +name = sys.argv[1] + +with pyme.Context() as c: + keys = list(c.keylist(name)) + if len(keys) == 0: + sys.exit("No key matching {}.".format(name)) + if len(keys) > 1: + sys.exit("More than one key matching {}.".format(name)) + + key = keys[0] + print("Editing key {} ({}):".format(key.uids[0].uid, key.subkeys[0].fpr)) + + def edit_fnc(status, args): + print("Status: {} ({}), args: {} > ".format( + status2str[status], status, args), end='', flush=True) + + if not 'GET' in status2str[status]: + # no prompt + print() + return None + + try: + return input() + except EOFError: + return "quit" + + c.op_edit(key, edit_fnc, None, sys.stdout) diff --git a/lang/python/examples/sign.py b/lang/python/examples/sign.py index b6a1d3c..0dd6a7c 100755 --- a/lang/python/examples/sign.py +++ b/lang/python/examples/sign.py @@ -1,32 +1,25 @@ #!/usr/bin/env python3 -# Copyright (C) 2002 John Goerzen -# # -# 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. +# Copyright (C) 2016 g10 Code GmbH +# Copyright (C) 2002 John Goerzen # -# 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. +# 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. # -# 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 02111-1307 USA +# 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, see . import sys -import os -from pyme import core, callbacks +import pyme from pyme.constants.sig import mode -core.check_version(None) - -plain = core.Data(b"Test message") -sig = core.Data() -c = core.Context() -c.set_passphrase_cb(callbacks.passphrase_stdin, b'for signing') -c.op_sign(plain, sig, mode.CLEAR) -sig.seek(0, os.SEEK_SET) -sys.stdout.buffer.write(sig.read()) +with pyme.Context() as c: + signed, _ = c.sign(b"Test message", mode=mode.CLEAR) + sys.stdout.buffer.write(signed) diff --git a/lang/python/examples/signverify.py b/lang/python/examples/signverify.py index 6a63112..7a24d71 100755 --- a/lang/python/examples/signverify.py +++ b/lang/python/examples/signverify.py @@ -1,77 +1,39 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # -# 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 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. +# 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 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . # Sample of unattended signing/verifying of a message. -# It uses keys for joe at example.org generated by genkey.pl script +# It uses keys for joe+pyme at example.org generated by genkey.py script import sys import os -from pyme import core +import pyme from pyme.constants.sig import mode -core.check_version(None) - -plain = core.Data(b"Test message") -sig = core.Data() -c = core.Context() -user = "joe" - -c.signers_clear() -# Add joe at example.org's keys in the list of signers -for sigkey in c.op_keylist_all(user, 1): - if sigkey.can_sign: - c.signers_add(sigkey) -if not c.signers_enum(0): - print("No secret %s's keys suitable for signing!" % user) - sys.exit(0) - -# This is a map between signer e-mail and its password -passlist = { - b"": b"Crypt0R0cks" - } - -# callback will return password based on the e-mail listed in the hint. -c.set_passphrase_cb(lambda x,y,z: passlist[x[x.rindex("<"):]]) - -c.op_sign(plain, sig, mode.CLEAR) - -# Print out the signature (don't forget to rewind since signing put sig at EOF) -sig.seek(0, os.SEEK_SET) -signedtext = sig.read() -sys.stdout.buffer.write(signedtext) - -# Create Data with signed text. -sig2 = core.Data(signedtext) -plain2 = core.Data() +user = "joe+pyme" -# Verify. -c.op_verify(sig2, None, plain2) -result = c.op_verify_result() +with pyme.Context(pinentry_mode=pyme.constants.PINENTRY_MODE_LOOPBACK) as c: + keys = list(c.keylist(user)) + if len(keys) == 0: + sys.exit("No key matching {}.".format(user)) -# List results for all signatures. Status equal 0 means "Ok". -for index, sign in enumerate(result.signatures): - print("signature", index, ":") - print(" summary: ", sign.summary) - print(" status: ", sign.status) - print(" timestamp: ", sign.timestamp) - print(" fingerprint:", sign.fpr) - print(" uid: ", c.get_key(sign.fpr, 0).uids[0].uid) + c.signers = keys[:1] + c.set_passphrase_cb(lambda *args: "Crypt0R0cks") + signed_data, _ = c.sign(b"Test message", mode=mode.CLEAR) -# Print "unsigned" text. Rewind since verify put plain2 at EOF. -plain2.seek(0, os.SEEK_SET) -print("\n") -sys.stdout.buffer.write(plain2.read()) + data, result = c.verify(signed_data, verify=keys[:1]) + print("Data: {!r}\nSignature: {!s}".format(data, result.signatures[0])) diff --git a/lang/python/examples/simple.py b/lang/python/examples/simple.py index 29a4449..50a3938 100755 --- a/lang/python/examples/simple.py +++ b/lang/python/examples/simple.py @@ -1,52 +1,45 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2005 Igor Belyi # Copyright (C) 2002 John Goerzen # -# 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 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. +# 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 02111-1307 USA +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . import sys import os -from pyme import core, errors - -core.check_version(None) - -# Set up our input and output buffers. - -plain = core.Data('This is my message.') -cipher = core.Data() - -# Initialize our context. - -c = core.Context() -c.set_armor(1) - -# Set up the recipients. - -sys.stdout.write("Enter name of your recipient: ") -sys.stdout.flush() -name = sys.stdin.readline().strip() -c.op_keylist_start(name, 0) -r = c.op_keylist_next() - -if r == None: - print("The key for user \"%s\" was not found" % name) -else: - # Do the encryption. - try: - c.op_encrypt([r], 1, plain, cipher) - cipher.seek(0, os.SEEK_SET) - sys.stdout.buffer.write(cipher.read()) - except errors.GPGMEError as ex: - print(ex.getstring()) +import pyme + +with pyme.Context(armor=True) as c: + recipients = [] + print("Enter name of your recipient(s), end with a blank line.") + while True: + line = input() + if not line: + break + new = list(c.keylist(line)) + if not new: + print("Matched no known keys.") + else: + print("Adding {}.".format(", ".join(k.uids[0].name for k in new))) + recipients.extend(new) + + if not recipients: + sys.exit("No recipients.") + + print("Encrypting for {}.".format(", ".join(k.uids[0].name + for k in recipients))) + + ciphertext, _, _ = c.encrypt(b"This is my message,", recipients) + sys.stdout.buffer.write(ciphertext) diff --git a/lang/python/examples/t-edit.py b/lang/python/examples/t-edit.py deleted file mode 100644 index 4a3b8ac..0000000 --- a/lang/python/examples/t-edit.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2005 Igor Belyi -# -# 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 02111-1307 USA - -import sys -import os -from pyme import core -from pyme.core import Data, Context - -core.check_version(None) - -class KeyEditor: - def __init__(self): - self.steps = ["fpr", "expire", "1", "primary", "quit"] - self.step = 0 - - def edit_fnc(self, status, args, out): - print("[-- Response --]") - out.seek(0, os.SEEK_SET) - sys.stdout.buffer.write(out.read()) - print("[-- Code: %d, %s --]" % (status, args)) - - if args == "keyedit.prompt": - result = self.steps[self.step] - self.step += 1 - elif args == "keyedit.save.okay": - result = "Y" - elif args == "keygen.valid": - result = "0" - else: - result = None - - return result - -if not os.getenv("GNUPGHOME"): - print("Please, set GNUPGHOME env.var. pointing to GPGME's tests/gpg dir") -else: - c = Context() - c.set_passphrase_cb(lambda x,y,z: "abc") - out = Data() - c.op_keylist_start(b"Alpha", 0) - key = c.op_keylist_next() - if not key: - sys.exit("Key Alpha not found. " + - "Did you point GNUPGHOME to GPGME's tests/gpg dir?") - c.op_edit(key, KeyEditor().edit_fnc, out, out) - print("[-- Last response --]") - out.seek(0, os.SEEK_SET) - sys.stdout.buffer.write(out.read()) diff --git a/lang/python/examples/testCMSgetkey.py b/lang/python/examples/testCMSgetkey.py index 7c95301..7c642e6 100644 --- a/lang/python/examples/testCMSgetkey.py +++ b/lang/python/examples/testCMSgetkey.py @@ -1,47 +1,32 @@ #!/usr/bin/env python3 -# initial 20080124 bernhard at intevation.de -# 20080124-2: removed some superflous imports -# 20080703: adapted for pyme-0.8.0 -# This script is Free Software under GNU GPL v>=2. # -# No modification made for python3 port, Bernhard can field this one -# if it is still required. -- Ben McGinnes +# Copyright (C) 2016 g10 Code GmbH +# Copyright (C) 2008 Bernhard Reiter # -"""A test applicaton for gpg_get_key() protocol.CMS. +# 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, see . -Tested on Debian Etch with - pyme 0.8.0 (manually compiled) - libgpgme11 1.1.6-0kk2 - gpgsm 2.0.9-0kk2 -""" +"""A test applicaton for the CMS protocol.""" import sys -from pyme import core -from pyme.constants import protocol +import pyme -def printgetkeyresults(keyfpr): - """Run gpgme_get_key().""" +if len(sys.argv) != 2: + sys.exit("fingerprint or unique key ID for gpgme_get_key()") - # gpgme_check_version() necessary for initialisation according to - # gogme 1.1.6 and this is not done automatically in pyme-0.7.0 - print("gpgme version:", core.check_version(None)) - c = core.Context() - c.set_protocol(protocol.CMS) - - key = c.get_key(keyfpr, False) +with pyme.Context(protocol=pyme.constants.PROTOCOL_CMS) as c: + key = c.get_key(sys.argv[1], False) print("got key: ", key.subkeys[0].fpr) - for uid in key.uids: print(uid.uid) - -def main(): - if len(sys.argv) < 2: - print("fingerprint or unique key ID for gpgme_get_key()") - sys.exit(1) - - printgetkeyresults(sys.argv[1]) - - -if __name__ == "__main__": - main() diff --git a/lang/python/examples/verifydetails.py b/lang/python/examples/verifydetails.py index 99e5e0a..b57ed84 100755 --- a/lang/python/examples/verifydetails.py +++ b/lang/python/examples/verifydetails.py @@ -1,27 +1,21 @@ #!/usr/bin/env python3 -# initial 20080123 build from the example: -# very simple - probably INCOMPLETE -# 20080703 Bernhard -# added second usage for detached signatures. -# added output of signature.summary (another bitfield) -# printing signature bitfield in hex format -# # +# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # Copyright (c) 2008 Bernhard Reiter # -# 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 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. +# 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, see . +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . import sys import os @@ -36,60 +30,47 @@ def print_engine_infos(): print(engine.file_name, engine.version) for proto in [protocol.OpenPGP, protocol.CMS]: - print(core.get_protocol_name(proto), core.engine_check_version(proto)) + print("Have {}? {}".format(core.get_protocol_name(proto), + core.engine_check_version(proto))) -def verifyprintdetails(sigfilename, filefilename=None): +def verifyprintdetails(filename, detached_sig_filename=None): """Verify a signature, print a lot of details.""" - c = core.Context() - - # Create Data with signed text. - sig2 = core.Data(file=sigfilename) - if filefilename: - file2 = core.Data(file=filefilename) - plain2 = None - else: - file2 = None - plain2 = core.Data() - - # Verify. - c.op_verify(sig2, file2, plain2) - result = c.op_verify_result() - - # List results for all signatures. Status equal 0 means "Ok". - for index, sign in enumerate(result.signatures): - print("signature", index, ":") - print(" summary: %#0x" % (sign.summary)) - print(" status: %#0x" % (sign.status)) - print(" timestamp: ", sign.timestamp) - print(" fingerprint:", sign.fpr) - print(" uid: ", c.get_key(sign.fpr, 0).uids[0].uid) + with core.Context() as c: + + # Verify. + data, result = c.verify(open(filename), + open(detached_sig_filename) + if detached_sig_filename else None) + + # List results for all signatures. Status equal 0 means "Ok". + for index, sign in enumerate(result.signatures): + print("signature", index, ":") + print(" summary: %#0x" % (sign.summary)) + print(" status: %#0x" % (sign.status)) + print(" timestamp: ", sign.timestamp) + print(" fingerprint:", sign.fpr) + print(" uid: ", c.get_key(sign.fpr, 0).uids[0].uid) # Print "unsigned" text if inline signature - if plain2: - #Rewind since verify put plain2 at EOF. - plain2.seek(0, os.SEEK_SET) - print("\n") - sys.stdout.buffer.write(plain2.read()) + if data: + sys.stdout.buffer.write(data) def main(): print_engine_infos() - print() - argc= len(sys.argv) + argc = len(sys.argv) if argc < 2 or argc > 3: - print("need a filename for inline signature") - print("or two filename for detached signature and file to check") - sys.exit(1) + sys.exit( + "Usage: {} [ ]".format( + sys.argv[0])) if argc == 2: - print("trying to verify file: " + sys.argv[1]) + print("trying to verify file {}.".format(sys.argv[1])) verifyprintdetails(sys.argv[1]) if argc == 3: - print("trying to verify signature %s for file %s" \ - % (sys.argv[1], sys.argv[2])) - + print("trying to verify signature {1} for file {0}.".format(*sys.argv)) verifyprintdetails(sys.argv[1], sys.argv[2]) if __name__ == "__main__": ----------------------------------------------------------------------- Summary of changes: lang/python/examples/Examples.rst | 7 -- lang/python/examples/assuan.py | 25 +++++++ lang/python/examples/decryption-filter.py | 29 ++++++++ lang/python/examples/delkey.py | 45 ++++++------ lang/python/examples/encrypt-to-all.py | 86 +++++++++------------- lang/python/examples/exportimport.py | 115 +++++++++++++----------------- lang/python/examples/genkey.py | 41 +++++------ lang/python/examples/inter-edit.py | 96 +++++++++++++------------ lang/python/examples/sign.py | 41 +++++------ lang/python/examples/signverify.py | 86 +++++++--------------- lang/python/examples/simple.py | 79 ++++++++++---------- lang/python/examples/t-edit.py | 62 ---------------- lang/python/examples/testCMSgetkey.py | 55 ++++++-------- lang/python/examples/verifydetails.py | 93 ++++++++++-------------- 14 files changed, 360 insertions(+), 500 deletions(-) delete mode 100644 lang/python/examples/Examples.rst create mode 100644 lang/python/examples/assuan.py create mode 100644 lang/python/examples/decryption-filter.py delete mode 100644 lang/python/examples/t-edit.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sat Aug 6 07:49:39 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Sat, 06 Aug 2016 07:49:39 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-49-g894789c 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 894789c3299dc47a8c1ccaaa7070382f0fae0262 (commit) from c9387e41db7520d176edd3d6613b85875bdeb32c (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 894789c3299dc47a8c1ccaaa7070382f0fae0262 Author: NIIBE Yutaka Date: Sat Aug 6 14:47:29 2016 +0900 agent: Clean up SSH support. * agent/command-ssh.c (file_to_buffer): Remove. (ssh_handler_request_identities): Use agent_public_key_from_file. -- Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 48f1b3d..583b4c7 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -814,67 +814,6 @@ stream_copy (estream_t dst, estream_t src) return err; } - - -/* Read the content of the file specified by FILENAME into a newly - create buffer, which is to be stored in BUFFER; store length of - buffer in BUFFER_N. */ -static gpg_error_t -file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) -{ - unsigned char *buffer_new; - struct stat statbuf; - estream_t stream; - gpg_error_t err; - int ret; - - *buffer = NULL; - *buffer_n = 0; - - buffer_new = NULL; - err = 0; - - stream = es_fopen (filename, "rb"); - if (! stream) - { - err = gpg_error_from_syserror (); - goto out; - } - - ret = fstat (es_fileno (stream), &statbuf); - if (ret) - { - err = gpg_error_from_syserror (); - goto out; - } - - buffer_new = xtrymalloc (statbuf.st_size); - if (! buffer_new) - { - err = gpg_error_from_syserror (); - goto out; - } - - err = stream_read_data (stream, buffer_new, statbuf.st_size); - if (err) - goto out; - - *buffer = buffer_new; - *buffer_n = statbuf.st_size; - - out: - - if (stream) - es_fclose (stream); - - if (err) - xfree (buffer_new); - - return err; -} - - - /* Open the ssh control file and create it if not available. With APPEND passed as true the file will be opened in append mode, @@ -2683,12 +2622,8 @@ static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t response) { - ssh_key_type_spec_t spec; - char *key_fname = NULL; - char *fnameptr; u32 key_counter; estream_t key_blobs; - gcry_sexp_t key_secret; gcry_sexp_t key_public; gpg_error_t err; int ret; @@ -2700,7 +2635,6 @@ ssh_handler_request_identities (ctrl_t ctrl, /* Prepare buffer stream. */ - key_secret = NULL; key_public = NULL; key_counter = 0; err = 0; @@ -2729,29 +2663,6 @@ ssh_handler_request_identities (ctrl_t ctrl, key_counter++; } - - /* Prepare buffer for key name construction. */ - { - char *dname; - - dname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, NULL); - if (!dname) - { - err = gpg_err_code_from_syserror (); - goto out; - } - - key_fname = xtrymalloc (strlen (dname) + 1 + 40 + 4 + 1); - if (!key_fname) - { - err = gpg_err_code_from_syserror (); - xfree (dname); - goto out; - } - fnameptr = stpcpy (stpcpy (key_fname, dname), "/"); - xfree (dname); - } - /* Then look at all the registered and non-disabled keys. */ err = open_control_file (&cf, 0); if (err) @@ -2759,52 +2670,27 @@ ssh_handler_request_identities (ctrl_t ctrl, while (!read_control_file_item (cf)) { + unsigned char grip[20]; + if (!cf->item.valid) continue; /* Should not happen. */ if (cf->item.disabled) continue; assert (strlen (cf->item.hexgrip) == 40); + hex2bin (cf->item.hexgrip, grip, sizeof (grip)); - stpcpy (stpcpy (fnameptr, cf->item.hexgrip), ".key"); - - /* Read file content. */ - { - unsigned char *buffer; - size_t buffer_n; - - err = file_to_buffer (key_fname, &buffer, &buffer_n); - if (err) - { - log_error ("%s:%d: key '%s' skipped: %s\n", - cf->fname, cf->lnr, cf->item.hexgrip, - gpg_strerror (err)); - continue; - } - - err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n); - xfree (buffer); - if (err) - goto out; - } - - { - char *key_type = NULL; - - err = sexp_extract_identifier (key_secret, &key_type); - if (err) - goto out; - - err = ssh_key_type_lookup (NULL, key_type, &spec); - xfree (key_type); - if (err) + err = agent_public_key_from_file (ctrl, grip, &key_public); + if (err) + { + log_error ("failed to read the public key\n"); goto out; - } + } - err = ssh_send_key_public (key_blobs, key_secret, NULL); + err = ssh_send_key_public (key_blobs, key_public, NULL); if (err) goto out; - gcry_sexp_release (key_secret); - key_secret = NULL; + gcry_sexp_release (key_public); + key_public = NULL; key_counter++; } @@ -2820,7 +2706,6 @@ ssh_handler_request_identities (ctrl_t ctrl, out: /* Send response. */ - gcry_sexp_release (key_secret); gcry_sexp_release (key_public); if (!err) @@ -2838,7 +2723,6 @@ ssh_handler_request_identities (ctrl_t ctrl, es_fclose (key_blobs); close_control_file (cf); - xfree (key_fname); return ret_err; } ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 138 +++++----------------------------------------------- 1 file changed, 11 insertions(+), 127 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Aug 6 10:18:19 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 06 Aug 2016 10:18:19 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-50-g40d1602 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 40d16029ed8b334c371fa7f24ac762d47302826e (commit) from 894789c3299dc47a8c1ccaaa7070382f0fae0262 (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 40d16029ed8b334c371fa7f24ac762d47302826e Author: Werner Koch Date: Sat Aug 6 10:14:17 2016 +0200 agent: Fix long standing regression tracking the connection count. * agent/gpg-agent.c (get_agent_active_connection_count): New. (do_start_connection_thread, start_connection_thread_ssh): Bump ACTIVE_CONNECTIONS up and down. * agent/command.c (cmd_getinfo): Add subcommand "connections". -- The variable ACTIVE_CONNECTIONS is used to shutdown gpg-agent in a friendly way. Before we switched to nPth a Pth provided count of threads was used for this. During the migration to nPth ACTIVE_CONNECTIONS was introduced and checked but never set. Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 42a580c..fe5ffba 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -341,6 +341,7 @@ void agent_set_progress_cb (void (*cb)(ctrl_t ctrl, const char *what, gpg_error_t agent_copy_startup_env (ctrl_t ctrl); const char *get_agent_socket_name (void); const char *get_agent_ssh_socket_name (void); +int get_agent_active_connection_count (void); #ifdef HAVE_W32_SYSTEM void *get_agent_scd_notify_event (void); #endif diff --git a/agent/command.c b/agent/command.c index 1803b5f..7fc28ad 100644 --- a/agent/command.c +++ b/agent/command.c @@ -2775,6 +2775,7 @@ static const char hlp_getinfo[] = " std_startup_env - List the standard startup environment.\n" " cmd_has_option\n" " - Returns OK if the command CMD implements the option OPT.\n" + " connections - Return number of active connections.\n" " restricted - Returns OK if the connection is in restricted mode.\n"; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) @@ -2907,6 +2908,14 @@ cmd_getinfo (assuan_context_t ctx, char *line) } } } + else if (!strcmp (line, "connections")) + { + char numbuf[20]; + + snprintf (numbuf, sizeof numbuf, "%d", + get_agent_active_connection_count ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); return rc; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 90b0eaf..8a957cc 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1694,6 +1694,14 @@ get_agent_ssh_socket_name (void) } +/* Return the number of active connections. */ +int +get_agent_active_connection_count (void) +{ + return active_connections; +} + + /* Under W32, this function returns the handle of the scdaemon notification event. Calling it the first time creates that event. */ @@ -2302,6 +2310,7 @@ putty_message_thread (void *arg) static void * do_start_connection_thread (ctrl_t ctrl) { + active_connections++; agent_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("handler 0x%lx for fd %d started\n"), @@ -2314,6 +2323,7 @@ do_start_connection_thread (ctrl_t ctrl) agent_deinit_default_ctrl (ctrl); xfree (ctrl); + active_connections--; return NULL; } @@ -2380,6 +2390,7 @@ start_connection_thread_ssh (void *arg) if (check_nonce (ctrl, &socket_nonce_ssh)) return NULL; + active_connections++; agent_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("ssh handler 0x%lx for fd %d started\n"), @@ -2392,6 +2403,7 @@ start_connection_thread_ssh (void *arg) agent_deinit_default_ctrl (ctrl); xfree (ctrl); + active_connections--; return NULL; } ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 1 + agent/command.c | 9 +++++++++ agent/gpg-agent.c | 12 ++++++++++++ 3 files changed, 22 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 06:45:22 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 08 Aug 2016 06:45:22 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-51-g7dcad0d 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 7dcad0d3503ac0d75e09efb16246dd78518986fc (commit) from 40d16029ed8b334c371fa7f24ac762d47302826e (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 7dcad0d3503ac0d75e09efb16246dd78518986fc Author: NIIBE Yutaka Date: Mon Aug 8 13:24:02 2016 +0900 tests: Add openpgp/gpgv-forged-keyring.scm. * tests/openpgp/gpgv-forged-keyring.scm: New. * tests/openpgp/forged-keyring.gpg: New. * tests/openpgp/Makefile.am (TESTS): Add gpgv-forged-keyring.scm. * tests/openpgp/defs.scm (tools): Add GPGV. (GPGV): New. -- Signed-off-by: NIIBE Yutaka diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 7983d6f..564439a 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -72,6 +72,7 @@ TESTS = setup.scm \ conventional-mdc.scm \ multisig.scm \ verify.scm \ + gpgv-forged-keyring.scm \ armor.scm \ import.scm \ ecc.scm \ diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index 2cbad46..4a968da 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -53,6 +53,7 @@ (define tools '((gpg "GPG" "g10/gpg") + (gpgv "GPGV" "g10/gpgv") (gpg-agent "GPG_AGENT" "agent/gpg-agent") (gpg-connect-agent "GPG_CONNECT_AGENT" "tools/gpg-connect-agent") (gpgconf "GPGCONF" "tools/gpgconf") @@ -78,6 +79,7 @@ (define GPG `(,(tool 'gpg) --no-permission-warning ,@(if have-opt-always-trust '(--always-trust) '()))) +(define GPGV `(,(tool 'gpgv))) (define PINENTRY (tool 'pinentry)) (define (tr:gpg input args) diff --git a/tests/openpgp/forged-keyring.gpg b/tests/openpgp/forged-keyring.gpg new file mode 100644 index 0000000..8fe733a Binary files /dev/null and b/tests/openpgp/forged-keyring.gpg differ diff --git a/tests/openpgp/gpgv-forged-keyring.scm b/tests/openpgp/gpgv-forged-keyring.scm new file mode 100755 index 0000000..7094c96 --- /dev/null +++ b/tests/openpgp/gpgv-forged-keyring.scm @@ -0,0 +1,67 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see . + +(load (with-path "defs.scm")) + +(define msg_signed_asc " +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +This is an example text file to demonstrate a problem. + +Using forged-keyring.gpg with signature cache, it looks like it is +signed by the following key: + + Echo Test (demo key) + +But actually not. + +It is signed by a key (steve.biko at example.net) distributed as: + + gnupg/tests/openpgp/samplekeys/rsa-rsa-sample-1.asc + +in GnuPG. + +The forged-keyring.gpg file is created by a key in + + gnupg/tests/openpgp/pubdemo.asc + +Replacing the raw key material packet by one of rsa-rsa-sample-1.asc. +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQEcBAEBCAAGBQJXp+5MAAoJEKpD8dzH/tG3bGMH/1idFLJAaMxkrq+JguvAboiN +tAA44IdAgJvAxtR5w5fgfed7PfsH70+tj54/ZTObt7rZDIlj/YBQ7XeCwd7/O5vx +W0QtjjAxMuAPH80rVv4JIoflxV/deD8YaV9EhPE+6W5G0Z8SYL9B2RzdBVMwJY9+ +OZGJeKnUZ92Zg9jFr+H5gQNSeYdDHVDWYxr/xJUf0jYsZvAIBfB1mcSK1niiiVBv +GAcUC/I8g18a7pCS9Qf9iZflqxX4AXfocAGQqQAiG4744OCNhVa5q6TScqhaGUah +N1Glbw1OJfP1q+QFPMPKoCsTYmZpuugq2b5gV/eH0Abvk2pG4Fo/YTDPHhec7Jk= +=NnY/ +-----END PGP SIGNATURE----- +") + +(for-each-p + "Checking that a signature by bad key should not be verified" + (lambda (armored-file) + (catch '() + (pipe:do + (pipe:echo (eval armored-file (current-environment))) + (pipe:spawn `(, at GPGV --keyring ,(in-srcdir "forged-keyring.gpg")))) + (error "verification succeded but should not"))) + '(msg_signed_asc)) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/Makefile.am | 1 + tests/openpgp/defs.scm | 2 + tests/openpgp/forged-keyring.gpg | Bin 0 -> 970 bytes tests/openpgp/gpgv-forged-keyring.scm | 67 ++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 tests/openpgp/forged-keyring.gpg create mode 100755 tests/openpgp/gpgv-forged-keyring.scm hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 08:12:03 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 08 Aug 2016 08:12:03 +0200 Subject: [git] gnupg-doc - branch, master, updated. cc3c0679a8ff6a468fc00415a37af203a2909e1d 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 cc3c0679a8ff6a468fc00415a37af203a2909e1d (commit) from 93b627789f7fa7f61484b3cdd0f670fe22407994 (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 cc3c0679a8ff6a468fc00415a37af203a2909e1d Author: Werner Koch Date: Mon Aug 8 08:09:37 2016 +0200 web: Fixed link for WinGPG Requested by Andrei Sergeenko from scand. diff --git a/web/related_software/swlist.org b/web/related_software/swlist.org index d6b9efd..26cb2b4 100644 --- a/web/related_software/swlist.org +++ b/web/related_software/swlist.org @@ -478,7 +478,7 @@ allow users to encrypt chat and multi-user chat as well as encrypting/signing messages and signing presence of the user. It is multilingual and runs on GNU/Linux, Mac OS X and Windows. -** [[http://wingpg.com][WinGPG]] [Windows] GUI +** [[https://scand.com/products/wingpg/][WinGPG]] [Windows] GUI :PROPERTIES: :CUSTOM_ID: wingpg :END: ----------------------------------------------------------------------- Summary of changes: web/related_software/swlist.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 11:36:46 2016 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat) Date: Mon, 08 Aug 2016 11:36:46 +0200 Subject: [git] Scute - branch, master, updated. scute-1.3.0-64-g94eeb2d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PKCS#11 token on top of gpg-agent". The branch, master has been updated via 94eeb2d580f67bd56ba711e055d9ea2ea089ec89 (commit) via b9b8319083b78168e69757fde020cb7d0b1f21e9 (commit) via 0050056965eff7d3740680f49517f57851d51f38 (commit) via b04c929fcef090e0e9788a8434f3401d271a1823 (commit) via f0e91f6aeb5b8e38cfc46eeb306059136584d214 (commit) from bc6c9e746432f4005aef359a620660a9d35df791 (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 94eeb2d580f67bd56ba711e055d9ea2ea089ec89 Author: Damien Goutte-Gattat Date: Fri Aug 5 22:45:09 2016 +0200 doc: Update list of not implemented functions. * README: Update list of not implemented functions. * doc/manual/scute.texi: Likewise. * TODO: Remove C_GenerateRandom from the TODO list. Signed-off-by: Damien Goutte-Gattat diff --git a/README b/README index acc9904..7064b29 100644 --- a/README +++ b/README @@ -317,9 +317,6 @@ The following functions are not supported: C_VerifyRecoverInit, C_VerifyRec: Not supported. Only secret key operations are supported. -* C_SignInit, C_Sign: Currently, only signing 36 bytes - (MD5+SHA1) hashes is supported (used for client authentication). - * C_DecryptInit, C_Decrypt: Not yet supported, but will be in the future. @@ -337,8 +334,7 @@ The following functions are not supported: the tools accompanying the GnuPG software suite to generate and import keys for use with the token. -* C_SeedRandom, C_GenerateRandom: Not supported at this point. - C_GenerateRandom may be supported in the future, though. +* C_SeedRandom: Not supported. * C_CreateObject, C_CopyObject, C_DestroyObject, C_SetAttributeValue: Only read-only operations are supported on objects. diff --git a/TODO b/TODO index 75ef5fd..6f49130 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,6 @@ ** Windows: Find thread-safe replacement for localtime_r and timegm. * Missing features: -** Implement random number generation function C_GenerateRandom. ** Add canonical gnupg logging module. ** Mozilla ignores the CKA_TRUSTED attribute to certificates, so exporting the information from GPGSM (ISTRUSTED) will not be diff --git a/doc/manual/scute.texi b/doc/manual/scute.texi index 0d16742..7199edf 100644 --- a/doc/manual/scute.texi +++ b/doc/manual/scute.texi @@ -710,11 +710,6 @@ Passphrase queries are implemented by the use of GPG Agent and Pinentry. @itemx C_VerifyRec Not supported. Only secret key operations are supported. - at item C_SignInit - at itemx C_Sign -Currently, only signing 36 bytes (MD5+SHA1) hashes is supported (used -for client authentication). - @item C_DecryptInit @itemx C_Decrypt Not yet supported, but will be in the future. @@ -745,9 +740,7 @@ accompanying the GnuPG software suite to generate and import keys for use with the token. @item C_SeedRandom - at itemx C_GenerateRandom -Not supported at this point. @code{C_GenerateRandom} may be supported -in the future, though. +Not supported. @item C_CreateObject @itemx C_CopyObject commit b9b8319083b78168e69757fde020cb7d0b1f21e9 Author: Damien Goutte-Gattat Date: Fri Aug 5 22:45:08 2016 +0200 doc: Scute can be used to sign documents. * doc/manual/scute.texi: Explain how to use Scute with LibreOffice. * doc/manual/libreoffice-certificate-selection.png: New image. * doc/manual/libreoffice-digital-signatures.png: New image. * doc/manual/libreoffice-pdf-signature.png: New image. * doc/manual/Makefile.am: Include the new images. * README: Mention that Scute can work with LibreOffice. * doc/website/index.xhtml: Likewise. Signed-off-by: Damien Goutte-Gattat diff --git a/README b/README index 3e43aba..acc9904 100644 --- a/README +++ b/README @@ -26,7 +26,8 @@ authentication with SSL in Mozilla. See below for more details on how to get this working. Scute also allows you to sign emails with Thunderbird, using the -S/MIME protocol. +S/MIME protocol, and to sign OpenDocument and PDF files with +LibreOffice. Prerequisites diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index 14034e8..499e750 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -35,7 +35,9 @@ images = firefox-cm.png firefox-cm-view-detail.png firefox-cm-view.png \ firefox-dm-load-after.png firefox-dm-load-before.png \ firefox-dm-load.png firefox-dm-token-present.png firefox-pref.png \ firefox-pref-view.png firefox-bad-pin.png \ - thunderbird-account-settings.png thunderbird-smime-button.png + thunderbird-account-settings.png thunderbird-smime-button.png \ + libreoffice-certificate-selection.png \ + libreoffice-digital-signatures.png libreoffice-pdf-signature.png images_eps = $(images:.png=.eps) diff --git a/doc/manual/libreoffice-certificate-selection.png b/doc/manual/libreoffice-certificate-selection.png new file mode 100644 index 0000000..ca94f37 Binary files /dev/null and b/doc/manual/libreoffice-certificate-selection.png differ diff --git a/doc/manual/libreoffice-digital-signatures.png b/doc/manual/libreoffice-digital-signatures.png new file mode 100644 index 0000000..9a84d6c Binary files /dev/null and b/doc/manual/libreoffice-digital-signatures.png differ diff --git a/doc/manual/libreoffice-pdf-signature.png b/doc/manual/libreoffice-pdf-signature.png new file mode 100644 index 0000000..ab5cc35 Binary files /dev/null and b/doc/manual/libreoffice-pdf-signature.png differ diff --git a/doc/manual/scute.texi b/doc/manual/scute.texi index d7205db..0d16742 100644 --- a/doc/manual/scute.texi +++ b/doc/manual/scute.texi @@ -83,6 +83,7 @@ module. * Preparation:: What you should do before using Scute. * Client Authentication:: How to use Scute for client authentication. * Email Signing:: How to use Scute for S/MIME email signing. +* Document Signing:: How to use Scute with LibreOffice. * Troubleshooting:: What to do when things go wrong. * Internals:: Technical details about Scute. @@ -118,6 +119,8 @@ Client Authentication Email Signing +Document Signing + Troubleshooting Internals @@ -210,8 +213,8 @@ application and GnuPG 2.0. Currently supported usages are client authentication over HTTPS with Firefox (allowing users to authenticate themselves to a remote web -service without entering their log-in information), and email signing -with Thunderbird. +service without entering their log-in information), email signing +with Thunderbird, and document signing with LibreOffice. @node Preparation @@ -574,6 +577,37 @@ will be prompted for your User PIN before the message is sent. @center @image{thunderbird-smime-button,13cm} + at node Document Signing + at chapter Document Signing + +Scute can also be used with LibreOffice to sign OpenDocument files. + +First, you must load the Scute module into Mozilla Firefox according to +the above procedure. Then, configure LibreOffice to use Firefox's +certificate store by defining the @code{MOZILLA_CERTIFICATE_FOLDER} +environment variable to your Firefox profile directory. + +Then, to sign the document you are editing, select the + at code{File->Digital Signatures...} menu option to open the + at code{Digital Signatures} dialog. + + at center @image{libreoffice-digital-signatures,13cm} + +Click the @code{Sign Document} button to open the certificate selection +dialog. Select your card-based certificate, then validate. Enter your +User PIN when prompted by GPG Agent. + + at center @image{libreoffice-certificate-selection,13cm} + +You may also sign a PDF export of your document. Select the + at code{File->Export as PDF...} menu option to open the @code{PDF Options} +dialog. In the @code{Digital Signatures} tab, use the @code{Select} +button to open the certificate selection dialog as above. You will be +prompted for your User PIN when you will click the @code{Export} button. + + at center @image{libreoffice-pdf-signature,13cm} + + @node Troubleshooting @chapter Troubleshooting diff --git a/doc/website/index.xhtml b/doc/website/index.xhtml index bd60464..cd182a7 100644 --- a/doc/website/index.xhtml +++ b/doc/website/index.xhtml @@ -67,8 +67,8 @@

Currently, supported usages are HTTPS client - authentication and S/MIME email signing using X.509 - certificates. + authentication, S/MIME email signing, and document signing with + LibreOffice.

You can read the commit 0050056965eff7d3740680f49517f57851d51f38 Author: Damien Goutte-Gattat Date: Fri Aug 5 22:45:07 2016 +0200 doc: Scute can now be used to sign emails. * doc/manual/scute.texi: Explain how to use Scute for email signing. * doc/manual/thunderbird-account-settings.png: New image. * doc/manual/thunderbird-smime-button.png: New image. * doc/manual/Makefile.am: Include the two above files. * doc/website/index.xhtml: Mention the email signing capability. * README: Likewise. -- Since commit e22c8cf, which added support for generic hash functions in addition to the TLS-specific 'tls-md5sha1', Scute is no longer limited to TLS client authentication. Signed-off-by: Damien Goutte-Gattat diff --git a/README b/README index 43a6212..3e43aba 100644 --- a/README +++ b/README @@ -25,9 +25,8 @@ Scute enables you to use your OpenPGP smart card for client authentication with SSL in Mozilla. See below for more details on how to get this working. -In the future, Scute will enable you to use your OpenPGP smart card -for email decryption and signing with Thunderbird, using the X.509 -protocol. +Scute also allows you to sign emails with Thunderbird, using the +S/MIME protocol. Prerequisites diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index 62431d7..14034e8 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -34,7 +34,8 @@ DISTCLEANFILES = scute.tmp images = firefox-cm.png firefox-cm-view-detail.png firefox-cm-view.png \ firefox-dm-load-after.png firefox-dm-load-before.png \ firefox-dm-load.png firefox-dm-token-present.png firefox-pref.png \ - firefox-pref-view.png firefox-bad-pin.png + firefox-pref-view.png firefox-bad-pin.png \ + thunderbird-account-settings.png thunderbird-smime-button.png images_eps = $(images:.png=.eps) diff --git a/doc/manual/scute.texi b/doc/manual/scute.texi index 749b4c4..d7205db 100644 --- a/doc/manual/scute.texi +++ b/doc/manual/scute.texi @@ -82,6 +82,7 @@ module. * Introduction:: How to use this manual. * Preparation:: What you should do before using Scute. * Client Authentication:: How to use Scute for client authentication. +* Email Signing:: How to use Scute for S/MIME email signing. * Troubleshooting:: What to do when things go wrong. * Internals:: Technical details about Scute. @@ -115,6 +116,8 @@ Client Authentication * Application Configuration:: Preparing the application for use with Scute. * Authentication With Service:: Using Scute for client authentication. +Email Signing + Troubleshooting Internals @@ -178,7 +181,7 @@ Anybody can use, modify, and redistribute it under the terms of the GNU General Public License (@pxref{Copying}). @item it's built to grow -Although Scute currently only provides a single function, client +Although Scute initially provided a single function, client authentication using OpenPGP smart cards in Mozilla-based web browsers, it was built with the intention of supporting other applications as well in the future. @@ -205,10 +208,10 @@ Instead, it uses the GnuPG 2.0 framework to access the smart cards and associated data like certificates. Scute acts as the glue between the application and GnuPG 2.0. -Currently, only client authentication over HTTPS with Firefox using the -OpenPGP card is supported. In this configuration, Scute allows users to -authenticate themselves to a remote web service without entering their -log-in information. +Currently supported usages are client authentication over HTTPS with +Firefox (allowing users to authenticate themselves to a remote web +service without entering their log-in information), and email signing +with Thunderbird. @node Preparation @@ -545,6 +548,32 @@ the @code{Try Again} button does not work as expected: @comment FIXME: Document possible error codes. + at node Email Signing + at chapter Email Signing + +Scute also allows you to use your card-based X.509 certificate to sign +your emails with the S/MIME signature format. This has been tested +with Mozilla Thunderbird only, but should work with any mail client +with support for PKCS #11 (notably GNOME Evolution). + +You must first load the Scute module into your mail client. With +Mozilla Thunderbird, the procedure is the same as the one described +above for Mozilla Firefox. + +Then, open your accent configuration dialog (@code{Edit->Account +Settings}), and in the @code{Security} tab, under the section + at code{Digital Signing}, use the @code{Select...} button to associate +your card-based certificate with your account. + + at center @image{thunderbird-account-settings,13cm} + +When writing a new message, you may then use the @code{S/MIME} button +and select @code{Digitally sign this message} in the popup menu. You +will be prompted for your User PIN before the message is sent. + + at center @image{thunderbird-smime-button,13cm} + + @node Troubleshooting @chapter Troubleshooting diff --git a/doc/manual/thunderbird-account-settings.png b/doc/manual/thunderbird-account-settings.png new file mode 100644 index 0000000..a1caa4e Binary files /dev/null and b/doc/manual/thunderbird-account-settings.png differ diff --git a/doc/manual/thunderbird-smime-button.png b/doc/manual/thunderbird-smime-button.png new file mode 100644 index 0000000..5492b08 Binary files /dev/null and b/doc/manual/thunderbird-smime-button.png differ diff --git a/doc/website/index.xhtml b/doc/website/index.xhtml index 78f8d82..bd60464 100644 --- a/doc/website/index.xhtml +++ b/doc/website/index.xhtml @@ -65,12 +65,10 @@ that makes use the NSS library.

- Currently, only HTTPS client - authentication is supported. In the future, Scute will also - allow you to use your OpenPGP Card with Thunderbird for signing and - decrypting e-mails using X.509 certificates. + authentication and S/MIME email signing using X.509 + certificates.

You can read the commit b04c929fcef090e0e9788a8434f3401d271a1823 Author: Damien Goutte-Gattat Date: Fri Aug 5 22:45:06 2016 +0200 doc: Remove obsolete info about Mozilla PSM. * README: Remove obsolete instruction about the Mozilla Personal Security Manager. -- Mozilla does no longer ship the Personal Security Manager as a separate package; it is now built directly with Firefox. Signed-off-by: Damien Goutte-Gattat diff --git a/README b/README index e4dc01e..43a6212 100644 --- a/README +++ b/README @@ -47,10 +47,7 @@ Installation ============ To install the PKCS #11 Module, follow the generic installation -instructions in the file INSTALL that accompanies this software. You -also need to install the Mozilla Personal Security Manager (PSM), -which may come with your GNU/Linux distribution in a package named -mozilla-psm or similar. +instructions in the file INSTALL that accompanies this software. After installation, you can configure Mozilla to use Scute by visiting the preferences dialog in the "advanced" category, under commit f0e91f6aeb5b8e38cfc46eeb306059136584d214 Author: Damien Goutte-Gattat Date: Fri Aug 5 22:45:05 2016 +0200 doc: Scute can automatically start the agent. * README: Remove paragraph about the need to have an agent up and running and the GPG_AGENT_INFO variable set. * doc/manual/scute.texi: Likewise. -- As all other components of GnuPG, Scute does not need the GPG_AGENT_INFO variable anymore, and can start the agent on demand. Signed-off-by: Damien Goutte-Gattat diff --git a/README b/README index 5483062..e4dc01e 100644 --- a/README +++ b/README @@ -57,11 +57,6 @@ visiting the preferences dialog in the "advanced" category, under "Security Devices". There you can "load" the module from its installed path, e.g. "/usr/lib/libscute.so". -Note that for the module load to complete successfully, the GPG Agent -must be running and available. On Unix systems this means that -Mozilla needs to have the GPG_AGENT_INFO variable set correctly in its -environment. - Client Authentication ===================== diff --git a/doc/manual/scute.texi b/doc/manual/scute.texi index 35e0af2..749b4c4 100644 --- a/doc/manual/scute.texi +++ b/doc/manual/scute.texi @@ -258,14 +258,6 @@ configured: Scute uses the GnuPG 2.0 framework to access the OpenPGP card and for certificate management. The minimum version required is 2.0.0. - at strong{Caution:} A functional installation of GnuPG 2.0 requires a -running GPG Agent process, which must be advertised to the applications -via the @code{GPG_AGENT_INFO} environment variable. Please make sure -that you fulfill this requirement before using Scute in an application, -running the Scute test suite, or preparing certificates as described in - at ref{Certificate Preparation}. @xref{Invoking GPG-AGENT, , , gnupg, -Using the GNU Privacy Guard}, for details on how to run the GPG Agent. - @item Pinentry Pinentry is a dependency of GnuPG 2.0, so it also needs to be installed with it. ----------------------------------------------------------------------- Summary of changes: README | 22 ++---- TODO | 1 - doc/manual/Makefile.am | 5 +- doc/manual/libreoffice-certificate-selection.png | Bin 0 -> 5267 bytes doc/manual/libreoffice-digital-signatures.png | Bin 0 -> 4998 bytes doc/manual/libreoffice-pdf-signature.png | Bin 0 -> 8607 bytes doc/manual/scute.texi | 90 +++++++++++++++++------ doc/manual/thunderbird-account-settings.png | Bin 0 -> 20010 bytes doc/manual/thunderbird-smime-button.png | Bin 0 -> 7197 bytes doc/website/index.xhtml | 8 +- 10 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 doc/manual/libreoffice-certificate-selection.png create mode 100644 doc/manual/libreoffice-digital-signatures.png create mode 100644 doc/manual/libreoffice-pdf-signature.png create mode 100644 doc/manual/thunderbird-account-settings.png create mode 100644 doc/manual/thunderbird-smime-button.png hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 11:58:16 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 08 Aug 2016 11:58:16 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-52-g591a837 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 591a8373a5d9567db9b1a1a48205e8a206c7b669 (commit) from 7dcad0d3503ac0d75e09efb16246dd78518986fc (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 591a8373a5d9567db9b1a1a48205e8a206c7b669 Author: NIIBE Yutaka Date: Mon Aug 8 18:46:44 2016 +0900 agent: More clean up of SSH support. * common/util.h (get_pk_algo_from_key): New. * common/sexputil.c (get_pk_algo_from_key): The implementation. * agent/gpg-agent.c: Remove include of openpgpdefs.h. * agent/command-ssh.c (struct ssh_key_type_spec): Use integer ALGO. (ssh_key_types): Update with GCRY_PK_*. (make_cstring, sexp_extract_identifier): Remove. (sexp_key_construct): Use gcry_pk_algo_name to get ALGO string. (ssh_key_to_blob): Use cadr to get value list. (ssh_key_type_lookup): Lookup with integer ALGO. (ssh_receive_key): Follow the change of ssh_key_type_lookup. (ssh_send_key_public): Likewise. Use get_pk_algo_from_key to get ALGO. -- This fixes the regresson introduced by the commit 894789c3299dc47a8c1ccaaa7070382f0fae0262. Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 583b4c7..df38ad6 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -44,7 +44,8 @@ #include "agent.h" #include "i18n.h" -#include "../common/ssh-utils.h" +#include "util.h" +#include "ssh-utils.h" @@ -153,7 +154,7 @@ struct ssh_key_type_spec const char *name; /* Algorithm identifier as used by GnuPG. */ - const char *identifier; + int algo; /* List of MPI names for secret keys; order matches the one of the agent protocol. */ @@ -275,68 +276,68 @@ static ssh_request_spec_t request_specs[] = static ssh_key_type_spec_t ssh_key_types[] = { { - "ssh-ed25519", "Ed25519", "ecc", "qd", "q", "rs", "qd", + "ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_eddsa, "Ed25519", 0, SPEC_FLAG_IS_EdDSA }, { - "ssh-rsa", "RSA", "rsa", "nedupq", "en", "s", "nedpqu", + "ssh-rsa", "RSA", GCRY_PK_RSA, "nedupq", "en", "s", "nedpqu", ssh_key_modifier_rsa, ssh_signature_encoder_rsa, NULL, 0, SPEC_FLAG_USE_PKCS1V2 }, { - "ssh-dss", "DSA", "dsa", "pqgyx", "pqgy", "rs", "pqgyx", + "ssh-dss", "DSA", GCRY_PK_DSA, "pqgyx", "pqgy", "rs", "pqgyx", NULL, ssh_signature_encoder_dsa, NULL, 0, 0 }, { - "ecdsa-sha2-nistp256", "ECDSA", "ecdsa", "qd", "q", "rs", "qd", + "ecdsa-sha2-nistp256", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA }, { - "ecdsa-sha2-nistp384", "ECDSA", "ecdsa", "qd", "q", "rs", "qd", + "ecdsa-sha2-nistp384", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA }, { - "ecdsa-sha2-nistp521", "ECDSA", "ecdsa", "qd", "q", "rs", "qd", + "ecdsa-sha2-nistp521", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA }, { "ssh-ed25519-cert-v01 at openssh.com", "Ed25519", - "ecc", "qd", "q", "rs", "qd", + GCRY_PK_EDDSA, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_eddsa, "Ed25519", 0, SPEC_FLAG_IS_EdDSA | SPEC_FLAG_WITH_CERT }, { "ssh-rsa-cert-v01 at openssh.com", "RSA", - "rsa", "nedupq", "en", "s", "nedpqu", + GCRY_PK_RSA, "nedupq", "en", "s", "nedpqu", ssh_key_modifier_rsa, ssh_signature_encoder_rsa, NULL, 0, SPEC_FLAG_USE_PKCS1V2 | SPEC_FLAG_WITH_CERT }, { "ssh-dss-cert-v01 at openssh.com", "DSA", - "dsa", "pqgyx", "pqgy", "rs", "pqgyx", + GCRY_PK_DSA, "pqgyx", "pqgy", "rs", "pqgyx", NULL, ssh_signature_encoder_dsa, NULL, 0, SPEC_FLAG_WITH_CERT | SPEC_FLAG_WITH_CERT }, { "ecdsa-sha2-nistp256-cert-v01 at openssh.com", "ECDSA", - "ecdsa", "qd", "q", "rs", "qd", + GCRY_PK_ECC, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT }, { "ecdsa-sha2-nistp384-cert-v01 at openssh.com", "ECDSA", - "ecdsa", "qd", "q", "rs", "qd", + GCRY_PK_ECC, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT }, { "ecdsa-sha2-nistp521-cert-v01 at openssh.com", "ECDSA", - "ecdsa", "qd", "q", "rs", "qd", + GCRY_PK_ECC, "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT } @@ -368,23 +369,6 @@ realloc_secure (void *a, size_t n) } -/* Create and return a new C-string from DATA/DATA_N (i.e.: add - NUL-termination); return NULL on OOM. */ -static char * -make_cstring (const char *data, size_t data_n) -{ - char *s; - - s = xtrymalloc (data_n + 1); - if (s) - { - memcpy (s, data, data_n); - s[data_n] = 0; - } - - return s; -} - /* Lookup the ssh-identifier for the ECC curve CURVE_NAME. Returns NULL if not found. */ static const char * @@ -1739,6 +1723,7 @@ sexp_key_construct (gcry_sexp_t *r_sexp, const char *elems; size_t elems_n; unsigned int i, j; + const char *algo_name; if (secret) elems = key_spec.elems_sexp_order; @@ -1765,7 +1750,8 @@ sexp_key_construct (gcry_sexp_t *r_sexp, es_fputs ("(%s(%s", format); arg_list[arg_idx++] = &key_identifier[secret]; - arg_list[arg_idx++] = &key_spec.identifier; + algo_name = gcry_pk_algo_name (key_spec.algo); + arg_list[arg_idx++] = &algo_name; if (curve_name) { es_fputs ("(curve%s)", format); @@ -1868,8 +1854,8 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret, goto out; } - /* Get the algorithm identifier. */ - value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0); + /* Get key value list. */ + value_list = gcry_sexp_cadr (sexp); if (!value_list) { err = gpg_error (GPG_ERR_INV_SEXP); @@ -2009,51 +1995,6 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret, return err; } - -/* Extract the car from SEXP, and create a newly created C-string - which is to be stored in IDENTIFIER. */ -static gpg_error_t -sexp_extract_identifier (gcry_sexp_t sexp, char **identifier) -{ - char *identifier_new; - gcry_sexp_t sublist; - const char *data; - size_t data_n; - gpg_error_t err; - - identifier_new = NULL; - err = 0; - - sublist = gcry_sexp_nth (sexp, 1); - if (! sublist) - { - err = gpg_error (GPG_ERR_INV_SEXP); - goto out; - } - - data = gcry_sexp_nth_data (sublist, 0, &data_n); - if (! data) - { - err = gpg_error (GPG_ERR_INV_SEXP); - goto out; - } - - identifier_new = make_cstring (data, data_n); - if (! identifier_new) - { - err = gpg_err_code_from_errno (errno); - goto out; - } - - *identifier = identifier_new; - - out: - - gcry_sexp_release (sublist); - - return err; -} - /* @@ -2064,23 +2005,18 @@ sexp_extract_identifier (gcry_sexp_t sexp, char **identifier) /* Search for a key specification entry. If SSH_NAME is not NULL, search for an entry whose "ssh_name" is equal to SSH_NAME; - otherwise, search for an entry whose "name" is equal to NAME. + otherwise, search for an entry whose algorithm is equal to ALGO. Store found entry in SPEC on success, return error otherwise. */ static gpg_error_t -ssh_key_type_lookup (const char *ssh_name, const char *name, +ssh_key_type_lookup (const char *ssh_name, int algo, ssh_key_type_spec_t *spec) { gpg_error_t err; unsigned int i; - /* FIXME: Although this sees to work, it not be correct if the - lookup is done via name which might be "ecc" but actually it need - to check the flags to see whether it is eddsa or ecdsa. Maybe - the entire parameter controlled logic is too complicated and we - would do better by just switching on the ssh_name. */ for (i = 0; i < DIM (ssh_key_types); i++) if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier))) - || (name && (! strcmp (name, ssh_key_types[i].identifier)))) + || algo == ssh_key_types[i].algo) break; if (i == DIM (ssh_key_types)) @@ -2119,7 +2055,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, if (err) goto out; - err = ssh_key_type_lookup (key_type, NULL, &spec); + err = ssh_key_type_lookup (key_type, 0, &spec); if (err) goto out; @@ -2346,17 +2282,17 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key, const char *override_comment) { ssh_key_type_spec_t spec; - char *key_type = NULL; + int algo; char *comment = NULL; void *blob = NULL; size_t bloblen; - gpg_error_t err; + gpg_error_t err = 0; - err = sexp_extract_identifier (key, &key_type); - if (err) + algo = get_pk_algo_from_key (key); + if (algo == 0) goto out; - err = ssh_key_type_lookup (NULL, key_type, &spec); + err = ssh_key_type_lookup (NULL, algo, &spec); if (err) goto out; @@ -2382,7 +2318,6 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key, goto out; out: - xfree (key_type); xfree (comment); es_free (blob); diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 8a957cc..8d6ecfc 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -58,7 +58,6 @@ #include "gc-opt-flags.h" #include "exechelp.h" #include "asshelp.h" -#include "openpgpdefs.h" /* for PUBKEY_ALGO_ECDSA, PUBKEY_ALGO_ECDH */ #include "../common/init.h" diff --git a/common/sexputil.c b/common/sexputil.c index a63fc20..5063546 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -45,6 +45,7 @@ #include "util.h" #include "tlv.h" #include "sexp-parse.h" +#include "openpgpdefs.h" /* for pubkey_algo_t */ /* Return a malloced string with the S-expression CANON in advanced @@ -556,3 +557,52 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, return 0; } + + +/* Return the algo of a public KEY of SEXP. */ +int +get_pk_algo_from_key (gcry_sexp_t key) +{ + gcry_sexp_t list; + const char *s; + size_t n; + char algoname[6]; + int algo = 0; + + list = gcry_sexp_nth (key, 1); + if (!list) + goto out; + s = gcry_sexp_nth_data (list, 0, &n); + if (!s) + goto out; + if (n >= sizeof (algoname)) + goto out; + memcpy (algoname, s, n); + algoname[n] = 0; + + algo = gcry_pk_map_name (algoname); + if (algo == GCRY_PK_ECC) + { + gcry_sexp_t l1 = gcry_sexp_find_token (list, "flags", 0); + int i; + + for (i = l1 ? gcry_sexp_length (l1)-1 : 0; i > 0; i--) + { + s = gcry_sexp_nth_data (l1, i, &n); + if (!s) + continue; /* Not a data element. */ + + if (n == 5 && !memcmp (s, "eddsa", 5)) + { + algo = GCRY_PK_EDDSA; + break; + } + } + gcry_sexp_release (l1); + } + + out: + gcry_sexp_release (list); + + return algo; +} diff --git a/common/util.h b/common/util.h index 29e0ec9..3f2d174 100644 --- a/common/util.h +++ b/common/util.h @@ -183,6 +183,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, const char **r_algo); +int get_pk_algo_from_key (gcry_sexp_t key); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 123 +++++++++++++--------------------------------------- agent/gpg-agent.c | 1 - common/sexputil.c | 50 +++++++++++++++++++++ common/util.h | 1 + 4 files changed, 80 insertions(+), 95 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 15:11:48 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 08 Aug 2016 15:11:48 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-259-gab6f66d 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 ab6f66d676581cb497e581e4af40e2fe5bff507b (commit) from 2a613e87156b23c4aa6aa5ce38505cb285de6a18 (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 ab6f66d676581cb497e581e4af40e2fe5bff507b Author: Andre Heinecke Date: Mon Aug 8 15:04:01 2016 +0200 Prepend LD_LIBRARY_PATH for python tests * lang/python/tests/Makefile.am (TESTS_ENVIRONMENT): Prepend path instead of setting the value. -- This fixes the case where tools / libararies are needed for a working GnuPG system that are pointed to by LD_LIBRARY_PATH. E.g. GnuPG itself is installed in a custom prefix and PATH / LD_LIBRARY_PATH is set accordingly. diff --git a/lang/python/tests/Makefile.am b/lang/python/tests/Makefile.am index bc571fe..83c4d8e 100644 --- a/lang/python/tests/Makefile.am +++ b/lang/python/tests/Makefile.am @@ -26,7 +26,7 @@ test_srcdir = $(top_srcdir)/tests/gpg TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) \ LC_ALL=C GPG_AGENT_INFO= \ top_srcdir=$(top_srcdir) \ - LD_LIBRARY_PATH="../../../src/.libs" \ + LD_LIBRARY_PATH="../../../src/.libs:$(LD_LIBRARY_PATH)" \ PYTHONPATH=`echo $(abs_builddir)/../build/lib.*` py_tests = t-wrapper.py \ ----------------------------------------------------------------------- Summary of changes: lang/python/tests/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 17:05:51 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 08 Aug 2016 17:05:51 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-260-gb5e16b0 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 b5e16b036f0045524a583d8a366d8a3366fc0005 (commit) from ab6f66d676581cb497e581e4af40e2fe5bff507b (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 b5e16b036f0045524a583d8a366d8a3366fc0005 Author: Werner Koch Date: Mon Aug 8 17:02:54 2016 +0200 core: Let GPGME_PROTOCOL_ASSUAN pass Assuan comments through. * src/engine-assuan.c (llass_new): Set ASSUAN_CONVEY_COMMENTS, -- GnuPG-bug-id: 2429 Signed-off-by: Werner Koch diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 93d54d2..681be62 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -248,6 +248,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir, if (err) goto leave; assuan_ctx_set_system_hooks (llass->assuan_ctx, &_gpgme_assuan_system_hooks); + assuan_set_flag (llass->assuan_ctx, ASSUAN_CONVEY_COMMENTS, 1); err = assuan_socket_connect (llass->assuan_ctx, file_name, 0, 0); if (err) ----------------------------------------------------------------------- Summary of changes: src/engine-assuan.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 8 20:35:25 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 08 Aug 2016 20:35:25 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-54-g491d6fd 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 491d6fdabb3d95905cd96d905e1f965ce8ff07e1 (commit) via 5b614973fe2d4b5ef402a3057c31c3ef3042a483 (commit) from 591a8373a5d9567db9b1a1a48205e8a206c7b669 (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 491d6fdabb3d95905cd96d905e1f965ce8ff07e1 Author: Werner Koch Date: Mon Aug 8 18:45:29 2016 +0200 gpg: Cleanup of dek_to_passphrase function (part 2). * g10/passphrase.c (passphrase_get): Remove arg KEYID. Change arg MODE to NOCACHE. (passphrase_to_dek): Remove args KEYID and PUBKEY_ALGO. Split arg MODE into CREATE and NOCACHE. Change all callers and adjust stubs. (passphrase_clear_cache): Remove args KEYID and ALGO. They are not used. Change caller. Signed-off-by: Werner Koch diff --git a/g10/encrypt.c b/g10/encrypt.c index 54a17c3..2985408 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -221,8 +221,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) s2k = xmalloc_clear( sizeof *s2k ); s2k->mode = opt.s2k_mode; s2k->hash_algo = S2K_DIGEST_ALGO; - cfx.dek = passphrase_to_dek (NULL, 0, - default_cipher_algo(), s2k, 4, + cfx.dek = passphrase_to_dek (default_cipher_algo (), s2k, 1, 0, NULL, &canceled); if ( !cfx.dek || !cfx.dek->keylen ) { @@ -413,8 +412,8 @@ setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek) (*symkey_s2k)->mode = opt.s2k_mode; (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO; - *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo, - *symkey_s2k, 4, NULL, &canceled); + *symkey_dek = passphrase_to_dek (opt.s2k_cipher_algo, + *symkey_s2k, 1, 0, NULL, &canceled); if(!*symkey_dek || !(*symkey_dek)->keylen) { xfree(*symkey_dek); diff --git a/g10/gpgv.c b/g10/gpgv.c index d08dc5a..59edbb9 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -486,15 +486,13 @@ check_secret_key (PKT_public_key *pk, int n) * No secret key, so no passphrase needed */ DEK * -passphrase_to_dek (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, +passphrase_to_dek (int cipher_algo, STRING2KEY *s2k, int create, int nocache, const char *tmp, int *canceled) { - (void)keyid; - (void)pubkey_algo; (void)cipher_algo; (void)s2k; - (void)mode; + (void)create; + (void)nocache; (void)tmp; if (canceled) @@ -503,11 +501,9 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, } void -passphrase_clear_cache (u32 *keyid, const char *cacheid, int algo) +passphrase_clear_cache (const char *cacheid) { - (void)keyid; (void)cacheid; - (void)algo; } struct keyserver_spec * diff --git a/g10/keydb.h b/g10/keydb.h index 4e8f3f2..35512bb 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -252,14 +252,14 @@ int have_static_passphrase(void); const char *get_static_passphrase (void); void set_passphrase_from_string(const char *pass); void read_passphrase_from_fd( int fd ); -void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ); +void passphrase_clear_cache (const char *cacheid); DEK *passphrase_to_dek_ext(u32 *keyid, int pubkey_algo, int cipher_algo, STRING2KEY *s2k, int mode, const char *tryagain_text, const char *custdesc, const char *custprompt, int *canceled); -DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, +DEK *passphrase_to_dek (int cipher_algo, STRING2KEY *s2k, + int create, int nocache, const char *tryagain_text, int *canceled); void set_next_passphrase( const char *s ); char *get_last_passphrase(void); diff --git a/g10/mainproc.c b/g10/mainproc.c index 4217ccd..e50e212 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -329,7 +329,7 @@ proc_symkey_enc (CTX c, PACKET *pkt) } else { - c->dek = passphrase_to_dek (NULL, 0, algo, &enc->s2k, 3, NULL, NULL); + c->dek = passphrase_to_dek (algo, &enc->s2k, 0, 0, NULL, NULL); if (c->dek) { c->dek->symmetric = 1; @@ -587,7 +587,7 @@ proc_encrypted (CTX c, PACKET *pkt) log_info (_("assuming %s encrypted data\n"), "IDEA"); } - c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 3, NULL, &canceled); + c->dek = passphrase_to_dek (algo, s2k, 0, 0, NULL, &canceled); if (c->dek) c->dek->algo_info_printed = 1; else if (canceled) @@ -646,7 +646,7 @@ proc_encrypted (CTX c, PACKET *pkt) if (opt.debug) log_debug ("cleared passphrase cached with ID: %s\n", c->dek->s2k_cacheid); - passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0); + passphrase_clear_cache (c->dek->s2k_cacheid); } glo_ctrl.lasterr = result; write_status (STATUS_DECRYPTION_FAILED); diff --git a/g10/passphrase.c b/g10/passphrase.c index 475c892..be71b68 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -207,9 +207,7 @@ read_passphrase_from_fd( int fd ) /* * Ask the GPG Agent for the passphrase. - * Mode 0: Allow cached passphrase - * 1: No cached passphrase; that is we are asking for a new passphrase - * FIXME: Only partially implemented + * If NOCACHE is set the symmetric passpharse caching will not be used. * * Note that TRYAGAIN_TEXT must not be translated. If CANCELED is not * NULL, the function does set it to 1 if the user canceled the @@ -218,92 +216,30 @@ read_passphrase_from_fd( int fd ) * computed, this will be used as the cacheid. */ static char * -passphrase_get (u32 *keyid, int mode, const char *cacheid, int repeat, +passphrase_get (int nocache, const char *cacheid, int repeat, const char *tryagain_text, int *canceled) { int rc; - char *atext = NULL; char *pw = NULL; - PKT_public_key *pk = xmalloc_clear( sizeof *pk ); - byte fpr[MAX_FINGERPRINT_LEN]; - int have_fpr = 0; char *orig_codeset; - char hexfprbuf[20*2+1]; const char *my_cacheid; - int check = (mode == 1); if (canceled) *canceled = 0; -#if MAX_FINGERPRINT_LEN < 20 -#error agent needs a 20 byte fingerprint -#endif - - memset (fpr, 0, MAX_FINGERPRINT_LEN ); - if( keyid && get_pubkey( pk, keyid ) ) - { - free_public_key (pk); - pk = NULL; /* oops: no key for some reason */ - } - orig_codeset = i18n_switchto_utf8 (); - if ( !mode && pk && keyid ) - { - char *uid; - size_t uidlen; - const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo ); - const char *timestr; - char *maink; - - if ( !algo_name ) - algo_name = "?"; - - if (keyid[2] && keyid[3] - && keyid[0] != keyid[2] - && keyid[1] != keyid[3] ) - maink = xasprintf (_(" (main key ID %s)"), keystr (&keyid[2])); - else - maink = xstrdup (""); - - uid = get_user_id ( keyid, &uidlen ); - timestr = strtimestamp (pk->timestamp); - - atext = xasprintf (_("Please enter the passphrase to unlock the" - " secret key for the OpenPGP certificate:\n" - "\"%.*s\"\n" - "%u-bit %s key, ID %s,\n" - "created %s%s.\n"), - (int)uidlen, uid, - nbits_from_pk (pk), algo_name, keystr(&keyid[0]), - timestr, maink); - xfree (uid); - xfree (maink); - - { - size_t dummy; - fingerprint_from_pk( pk, fpr, &dummy ); - have_fpr = 1; - } - - } - else - atext = xstrdup ( _("Enter passphrase\n") ); - - - if (!mode && cacheid) + if (!nocache && cacheid) my_cacheid = cacheid; - else if (!mode && have_fpr) - my_cacheid = bin2hex (fpr, 20, hexfprbuf); else my_cacheid = NULL; if (tryagain_text) tryagain_text = _(tryagain_text); - rc = agent_get_passphrase (my_cacheid, tryagain_text, NULL, atext, - repeat, check, &pw); - xfree (atext); atext = NULL; + rc = agent_get_passphrase (my_cacheid, tryagain_text, NULL, + _("Enter passphrase\n"), + repeat, nocache, &pw); i18n_switchback (orig_codeset); @@ -333,74 +269,39 @@ passphrase_get (u32 *keyid, int mode, const char *cacheid, int repeat, write_status_errcode ("get_passphrase", rc); } - free_public_key (pk); if (rc) { xfree (pw); - return NULL; + pw = NULL; } return pw; } /* - * Clear the cached passphrase. If CACHEID is not NULL, it will be - * used instead of a cache ID derived from KEYID. + * Clear the cached passphrase with CACHEID. */ void -passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) +passphrase_clear_cache (const char *cacheid) { int rc; - (void)algo; - - if (!cacheid) - { - PKT_public_key *pk; -# if MAX_FINGERPRINT_LEN < 20 -# error agent needs a 20 byte fingerprint -# endif - byte fpr[MAX_FINGERPRINT_LEN]; - char hexfprbuf[2*20+1]; - size_t dummy; - - pk = xcalloc (1, sizeof *pk); - if ( !keyid || get_pubkey( pk, keyid ) ) - { - log_error ("key not found in passphrase_clear_cache\n"); - free_public_key (pk); - return; - } - memset (fpr, 0, MAX_FINGERPRINT_LEN ); - fingerprint_from_pk ( pk, fpr, &dummy ); - bin2hex (fpr, 20, hexfprbuf); - rc = agent_clear_passphrase (hexfprbuf); - free_public_key ( pk ); - } - else - rc = agent_clear_passphrase (cacheid); - + rc = agent_clear_passphrase (cacheid); if (rc) log_error (_("problem with the agent: %s\n"), gpg_strerror (rc)); } -/* Return a new DEK object using the string-to-key specifier S2K. Use - KEYID and PUBKEY_ALGO to prompt the user. Returns NULL is the user - selected to cancel the passphrase entry and if CANCELED is not - NULL, sets it to true. - - MODE 0: Allow cached passphrase - 1: Ignore cached passphrase - 2: Ditto, but create a new key - 3: Allow cached passphrase; use the S2K salt as the cache ID - 4: Ditto, but create a new key -*/ +/* Return a new DEK object using the string-to-key specifier S2K. + * Returns NULL if the user canceled the passphrase entry and if + * CANCELED is not NULL, sets it to true. + * + * If CREATE is true a new passphrase sll be created. If NOCACHE is + * true the symmetric key caching will not be used. */ DEK * -passphrase_to_dek (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, - int *canceled) +passphrase_to_dek (int cipher_algo, STRING2KEY *s2k, + int create, int nocache, + const char *tryagain_text, int *canceled) { char *pw = NULL; DEK *dek; @@ -415,7 +316,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, if ( !s2k ) { - log_assert (mode != 3 && mode != 4); + log_assert (create && !nocache); /* This is used for the old rfc1991 mode * Note: This must match the code in encode.c with opt.rfc1991 set */ s2k = &help_s2k; @@ -425,7 +326,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, /* Create a new salt or what else to be filled into the s2k for a new key. */ - if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) + if (create && (s2k->mode == 1 || s2k->mode == 3)) { gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); if ( s2k->mode == 3 ) @@ -446,59 +347,9 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, { char buf[50]; - if ( keyid ) - { - emit_status_need_passphrase (keyid, - keyid[2] && keyid[3]? keyid+2:NULL, - pubkey_algo); - } - else - { - snprintf (buf, sizeof buf -1, "%d %d %d", - cipher_algo, s2k->mode, s2k->hash_algo ); - write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf ); - } - } - - /* If we do have a keyID, we do not have a passphrase available in - NEXT_PW, we are not running in batch mode and we do not want to - ignore the passphrase cache (mode!=1), print a prompt with - information on that key. */ - if ( keyid && !opt.batch && !next_pw && mode!=1 ) - { - PKT_public_key *pk = xmalloc_clear( sizeof *pk ); - char *p; - - p = get_user_id_native(keyid); - tty_printf ("\n"); - tty_printf (_("You need a passphrase to unlock the secret key for\n" - "user: \"%s\"\n"),p); - xfree(p); - - if ( !get_pubkey( pk, keyid ) ) - { - const char *s = openpgp_pk_algo_name ( pk->pubkey_algo ); - - tty_printf (_("%u-bit %s key, ID %s, created %s"), - nbits_from_pk( pk ), s?s:"?", keystr(keyid), - strtimestamp(pk->timestamp) ); - if ( keyid[2] && keyid[3] - && keyid[0] != keyid[2] && keyid[1] != keyid[3] ) - { - if ( keystrlen () > 10 ) - { - tty_printf ("\n"); - tty_printf (_(" (subkey on main key ID %s)"), - keystr(&keyid[2]) ); - } - else - tty_printf ( _(" (main key ID %s)"), keystr(&keyid[2]) ); - } - tty_printf("\n"); - } - - tty_printf("\n"); - free_public_key (pk); + snprintf (buf, sizeof buf -1, "%d %d %d", + cipher_algo, s2k->mode, s2k->hash_algo ); + write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf ); } if ( next_pw ) @@ -515,7 +366,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, } else { - if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) + if (!nocache && (s2k->mode == 1 || s2k->mode == 3)) { memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf); *s2k_cacheidbuf = 'S'; @@ -532,8 +383,8 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, } /* Divert to the gpg-agent. */ - pw = passphrase_get (keyid, mode == 2, s2k_cacheid, - (mode == 2 || mode == 4)? opt.passphrase_repeat : 0, + pw = passphrase_get (create && nocache, s2k_cacheid, + create? opt.passphrase_repeat : 0, tryagain_text, canceled); if (*canceled) { @@ -551,7 +402,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, get_last_passphrase(). */ dek = xmalloc_secure_clear ( sizeof *dek ); dek->algo = cipher_algo; - if ( (!pw || !*pw) && (mode == 2 || mode == 4)) + if ( (!pw || !*pw) && create) dek->keylen = 0; else { diff --git a/g10/sign.c b/g10/sign.c index 6a7a87e..217196d 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1270,7 +1270,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) if (!opt.quiet || !opt.batch) log_info (_("%s encryption will be used\n"), openpgp_cipher_algo_name (algo) ); - cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, &canceled); + cfx.dek = passphrase_to_dek (algo, s2k, 1, 1, NULL, &canceled); if (!cfx.dek || !cfx.dek->keylen) { rc = gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE); diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 6f50759..6cf43a3 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -294,15 +294,13 @@ check_secret_key (PKT_public_key *pk, int n) * No secret key, so no passphrase needed */ DEK * -passphrase_to_dek (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, +passphrase_to_dek (int cipher_algo, STRING2KEY *s2k, int create, int nocache, const char *tmp, int *canceled) { - (void)keyid; - (void)pubkey_algo; (void)cipher_algo; (void)s2k; - (void)mode; + (void)create; + (void)nocache; (void)tmp; if (canceled) @@ -311,11 +309,9 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, } void -passphrase_clear_cache (u32 *keyid, const char *cacheid, int algo) +passphrase_clear_cache (const char *cacheid) { - (void)keyid; (void)cacheid; - (void)algo; } struct keyserver_spec * commit 5b614973fe2d4b5ef402a3057c31c3ef3042a483 Author: Werner Koch Date: Mon Aug 8 17:42:37 2016 +0200 gpg: Cleanup of dek_to_passphrase function (part 1). * g10/passphrase.c (passphrase_to_dek_ext): Remove args CUSTDESC and CUSTPROMPT. Merge into the passphrase_to_dek wrapper. (passphrase_get): Remove args CUSTOM_DESCRIPTION and CUSTOM_PROMPT. -- The function is nowadays only used for symmetric encryption. Thus we do not need all the former advanced stuff. Signed-off-by: Werner Koch diff --git a/g10/passphrase.c b/g10/passphrase.c index b1d1a05..475c892 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -218,10 +218,8 @@ read_passphrase_from_fd( int fd ) * computed, this will be used as the cacheid. */ static char * -passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, - const char *tryagain_text, - const char *custom_description, - const char *custom_prompt, int *canceled) +passphrase_get (u32 *keyid, int mode, const char *cacheid, int repeat, + const char *tryagain_text, int *canceled) { int rc; char *atext = NULL; @@ -230,7 +228,6 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, byte fpr[MAX_FINGERPRINT_LEN]; int have_fpr = 0; char *orig_codeset; - char *my_prompt; char hexfprbuf[20*2+1]; const char *my_cacheid; int check = (mode == 1); @@ -251,9 +248,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, orig_codeset = i18n_switchto_utf8 (); - if (custom_description) - atext = native_to_utf8 (custom_description); - else if ( !mode && pk && keyid ) + if ( !mode && pk && keyid ) { char *uid; size_t uidlen; @@ -306,12 +301,8 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, if (tryagain_text) tryagain_text = _(tryagain_text); - my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL; - - rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, + rc = agent_get_passphrase (my_cacheid, tryagain_text, NULL, atext, repeat, check, &pw); - - xfree (my_prompt); xfree (atext); atext = NULL; i18n_switchback (orig_codeset); @@ -406,17 +397,17 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) 4: Ditto, but create a new key */ DEK * -passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, - const char *custdesc, const char *custprompt, - int *canceled) +passphrase_to_dek (u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, + int *canceled) { char *pw = NULL; DEK *dek; STRING2KEY help_s2k; int dummy_canceled; - char s2k_cacheidbuf[1+16+1], *s2k_cacheid = NULL; + char s2k_cacheidbuf[1+16+1]; + char *s2k_cacheid = NULL; if (!canceled) canceled = &dummy_canceled; @@ -543,7 +534,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, /* Divert to the gpg-agent. */ pw = passphrase_get (keyid, mode == 2, s2k_cacheid, (mode == 2 || mode == 4)? opt.passphrase_repeat : 0, - tryagain_text, custdesc, custprompt, canceled); + tryagain_text, canceled); if (*canceled) { xfree (pw); @@ -593,17 +584,6 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, } -DEK * -passphrase_to_dek (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled) -{ - return passphrase_to_dek_ext (keyid, pubkey_algo, cipher_algo, - s2k, mode, tryagain_text, NULL, NULL, - canceled); -} - - /* Emit the USERID_HINT and the NEED_PASSPHRASE status messages. MAINKEYID may be NULL. */ void ----------------------------------------------------------------------- Summary of changes: g10/encrypt.c | 7 +- g10/gpgv.c | 12 +-- g10/keydb.h | 6 +- g10/mainproc.c | 6 +- g10/passphrase.c | 233 ++++++++----------------------------------------------- g10/sign.c | 2 +- g10/test-stubs.c | 12 +-- 7 files changed, 50 insertions(+), 228 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 04:54:57 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 09 Aug 2016 04:54:57 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-55-gebf24e3 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 ebf24e3b29766595204355d82f435a3e675bfbbc (commit) from 491d6fdabb3d95905cd96d905e1f965ce8ff07e1 (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 ebf24e3b29766595204355d82f435a3e675bfbbc Author: NIIBE Yutaka Date: Tue Aug 9 11:42:20 2016 +0900 agent: SSH support improvement. * agent/command-ssh.c (ssh_handler_request_identities): Skip a key with error, not giving up to handle the request itself. * agent/cvt-openpgp.c (extract_private_key): Support "ecdsa" key. -- Note that "ecdsa" key is still in use by old versions of gpg-agent through its SSH handling (until 2.1.14). With old versions of gpg-agent, adding ECDSA key by ssh-add command, "ecdsa" key will be created. So, "ecdsa" key should be supported. For g10/gpg, "ecdsa" and "ecdh" was only used in some experimental versions of libgcrypt, with parameters. We now use "ecc" for all cases in released versions. Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index df38ad6..b01cc06 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2618,7 +2618,7 @@ ssh_handler_request_identities (ctrl_t ctrl, if (err) { log_error ("failed to read the public key\n"); - goto out; + continue; } err = ssh_send_key_public (key_blobs, key_public, NULL); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 40d9a3e..eb420b0 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -1271,7 +1271,7 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data, array+0, array+1, array+2, array+3, array+4, NULL); } - else if (!strcmp (name, "ecc")) + else if (!strcmp (name, "ecc") || !strcmp (name, "ecdsa")) { algoname = "ecc"; format = "qd?"; ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 2 +- agent/cvt-openpgp.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 Tue Aug 9 10:41:11 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 09 Aug 2016 10:41:11 +0200 Subject: [git] GnuPG - branch, justus/issue1955, updated. gnupg-2.1.14-21-g3e2af1d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/issue1955 has been updated via 3e2af1db7e178065dd30b9d7b3f76ac3e201e580 (commit) from ddd69ff66c28f237ad262040a6cffc15be691a9e (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 3e2af1db7e178065dd30b9d7b3f76ac3e201e580 Author: Justus Winter Date: Tue Aug 9 10:40:33 2016 +0200 Add missing test messages diff --git a/tests/openpgp/samplemsgs/issue1955.one.two.gpg b/tests/openpgp/samplemsgs/issue1955.one.two.gpg new file mode 100644 index 0000000..94e2f74 Binary files /dev/null and b/tests/openpgp/samplemsgs/issue1955.one.two.gpg differ diff --git a/tests/openpgp/samplemsgs/issue1955.two.one.gpg b/tests/openpgp/samplemsgs/issue1955.two.one.gpg new file mode 100644 index 0000000..b8ac35d Binary files /dev/null and b/tests/openpgp/samplemsgs/issue1955.two.one.gpg differ ----------------------------------------------------------------------- Summary of changes: tests/openpgp/samplemsgs/issue1955.one.two.gpg | Bin 0 -> 611 bytes tests/openpgp/samplemsgs/issue1955.two.one.gpg | Bin 0 -> 611 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/openpgp/samplemsgs/issue1955.one.two.gpg create mode 100644 tests/openpgp/samplemsgs/issue1955.two.one.gpg hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 10:58:56 2016 From: cvs at cvs.gnupg.org (by Ben Kibbey) Date: Tue, 09 Aug 2016 10:58:56 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-56-g49829c2 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 49829c29e541546084950b8a153067db371d101a (commit) from ebf24e3b29766595204355d82f435a3e675bfbbc (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 49829c29e541546084950b8a153067db371d101a Author: Ben Kibbey Date: Mon Aug 8 18:40:03 2016 -0400 Cleanup initialization of libgcrypt. * common/init.c (init_common_subsystems): Initialize libgcrypt. * dirmngr/Makefile.am (dirmngr_ldap): Link with libgcrypt. -- Most other modules already call gcry_check_version() after init_common_subsystems() so may as well move initialization of libgcrypt to here. Also fixes a warning in the system log from gpgconf --homedir. Signed-off-by: Ben Kibbey diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 8d6ecfc..b8a5a3e 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -764,14 +764,6 @@ main (int argc, char **argv ) npth_init (); - /* Check that the libraries are suitable. Do it here because - the option parsing may need services of the library. */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - malloc_hooks.malloc = gcry_malloc; malloc_hooks.realloc = gcry_realloc; malloc_hooks.free = gcry_free; diff --git a/agent/protect-tool.c b/agent/protect-tool.c index c2bf87d..f41cc0b 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -566,16 +566,9 @@ main (int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - setup_libgcrypt_logging (); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - pargs.argc = &argc; pargs.argv = &argv; pargs.flags= 1; /* (do not remove the args) */ diff --git a/common/init.c b/common/init.c index c406ffe..591c854 100644 --- a/common/init.c +++ b/common/init.c @@ -47,7 +47,9 @@ # include /* For _assuan_w32ce_finish_pipe. */ #endif +#include #include "util.h" +#include "i18n.h" /* This object is used to register memory cleanup functions. Technically they are not needed but they can avoid frequent @@ -186,6 +188,12 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp) atexit (sleep_on_exit); #endif + if (!gcry_check_version (NEED_LIBGCRYPT_VERSION)) + { + log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", + NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL)); + } + /* Initialize the Estream library. */ gpgrt_init (); gpgrt_set_alloc_func (gcry_realloc); diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index aaa9050..64bc058 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -94,8 +94,8 @@ dirmngr_ldap_SOURCES = dirmngr_ldap.c $(ldap_url) dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) dirmngr_ldap_LDFLAGS = dirmngr_ldap_LDADD = $(libcommon) no-libgcrypt.o \ - $(GPG_ERROR_LIBS) $(LDAPLIBS) $(LBER_LIBS) $(LIBINTL) \ - $(LIBICONV) + $(GPG_ERROR_LIBS) $(LIBGCRYPT_LIBS) $(LDAPLIBS) \ + $(LBER_LIBS) $(LIBINTL) $(LIBICONV) endif dirmngr_client_SOURCES = dirmngr-client.c diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 7e629db..007fa10 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -755,10 +755,6 @@ main (int argc, char **argv) /* Check that the libraries are suitable. Do it here because the option parsing may need services of the libraries. */ - - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); if (!ksba_check_version (NEED_KSBA_VERSION) ) log_fatal( _("%s is too old (need %s, have %s)\n"), "libksba", NEED_KSBA_VERSION, ksba_check_version (NULL) ); diff --git a/g10/gpg.c b/g10/gpg.c index b33b61b..91f3472 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2201,14 +2201,6 @@ main (int argc, char **argv) i18n_init(); init_common_subsystems (&argc, &argv); - /* Check that the libraries are suitable. Do it right here because the - option parsing may need services of the library. */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal ( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - /* Use our own logging handler for Libcgrypt. */ setup_libgcrypt_logging (); diff --git a/g10/gpgv.c b/g10/gpgv.c index 59edbb9..729fcf8 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -155,11 +155,6 @@ main( int argc, char **argv ) i18n_init(); init_common_subsystems (&argc, &argv); - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal ( _("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gnupg_init_signals (0, NULL); diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index f3c20f5..0bb34da 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -250,11 +250,6 @@ main ( int argc, char **argv) i18n_init (); init_common_subsystems (&argc, &argv); - /* Check that the Libgcrypt is suitable. */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - /* Take extra care of the random pool. */ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); diff --git a/g13/g13.c b/g13/g13.c index 0499a18..082edc9 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -372,11 +372,6 @@ main ( int argc, char **argv) npth_init (); - /* Check that the Libgcrypt is suitable. */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - /* Take extra care of the random pool. */ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index d55a118..e452b4d 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -460,14 +460,6 @@ main( int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - /* Check that the libraries are suitable. Do it here because - the option parsing may need services of the library. */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - gcry_set_log_handler (my_gcry_logger, NULL); /*create_dotlock(NULL); register locking cleanup */ diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 7dbb9c7..263d9bd 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -424,14 +424,6 @@ main (int argc, char **argv ) npth_init (); - /* Check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); malloc_hooks.malloc = gcry_malloc; diff --git a/sm/gpgsm.c b/sm/gpgsm.c index b64072e..42b6706 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -938,9 +938,6 @@ main ( int argc, char **argv) /* Check that the libraries are suitable. Do it here because the option parse may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); if (!ksba_check_version (NEED_KSBA_VERSION) ) log_fatal (_("%s is too old (need %s, have %s)\n"), "libksba", NEED_KSBA_VERSION, ksba_check_version (NULL) ); diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c index 37283a1..aa228a7 100644 --- a/tools/gpg-check-pattern.c +++ b/tools/gpg-check-pattern.c @@ -171,13 +171,6 @@ main (int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - /* We need Libgcrypt for hashing. */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal ( _("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - setup_libgcrypt_logging (); gcry_control (GCRYCTL_INIT_SECMEM, 4096, 0); diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index 3732b39..5c1f0da 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -998,11 +998,6 @@ main (int argc, char **argv) log_set_file (logfile); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt", - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } setup_libgcrypt_logging (); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); ----------------------------------------------------------------------- Summary of changes: agent/gpg-agent.c | 8 -------- agent/protect-tool.c | 7 ------- common/init.c | 8 ++++++++ dirmngr/Makefile.am | 4 ++-- dirmngr/dirmngr.c | 4 ---- g10/gpg.c | 8 -------- g10/gpgv.c | 5 ----- g13/g13-syshelp.c | 5 ----- g13/g13.c | 5 ----- kbx/kbxutil.c | 8 -------- scd/scdaemon.c | 8 -------- sm/gpgsm.c | 3 --- tools/gpg-check-pattern.c | 7 ------- tools/symcryptrun.c | 5 ----- 14 files changed, 10 insertions(+), 75 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 12:34:41 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 09 Aug 2016 12:34:41 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-19-g61539ef 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 61539efc2bc4ba9a9faceaced12660d588c1be7a (commit) from 15d13272344fa0d8753a321c087b30a6d5115dfb (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 61539efc2bc4ba9a9faceaced12660d588c1be7a Author: Daniel Kahn Gillmor Date: Fri Aug 5 10:46:43 2016 -0400 gpg: Avoid publishing the GnuPG version by default * g10/gpg.c (main): initialize opt.emit_version to 0 * doc/gpg.texi: document different default for --emit-version -- The version of GnuPG in use is not particularly helpful. It is not cryptographically verifiable, and it doesn't distinguish between significant version differences like 2.0.x and 2.1.x. Additionally, it leaks metadata that can be used to distinguish users from one another, and can potentially be used to target specific attacks if there are known behaviors that differ between major versions. It's probably better to take the more parsimonious approach to metadata production by default. (backport of master commit c9387e41db7520d176edd3d6613b85875bdeb32c) Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpg.texi b/doc/gpg.texi index a41ab8e..12a6d60 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2338,9 +2338,9 @@ protected by the signature. @opindex emit-version Force inclusion of the version string in ASCII armored output. If given once only the name of the program and the major number is -emitted (default), given twice the minor is also emitted, given triple +emitted, given twice the minor is also emitted, given triple the micro is added, and given quad an operating system identification -is also emitted. @option{--no-emit-version} disables the version +is also emitted. @option{--no-emit-version} (default) disables the version line. @item --sig-notation @code{name=value} diff --git a/g10/gpg.c b/g10/gpg.c index 72d313b..236ea1e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1911,7 +1911,7 @@ main (int argc, char **argv ) opt.def_cert_expire="0"; set_homedir ( default_homedir () ); opt.passwd_repeat=1; - opt.emit_version = 1; /* Limit to the major number. */ + opt.emit_version = 0; #ifdef ENABLE_CARD_SUPPORT #if defined(_WIN32) || defined(__CYGWIN__) ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 ++-- g10/gpg.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 12:35:57 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 09 Aug 2016 12:35:57 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.30-11-gcbd0308 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 cbd0308bc70855a2dd34bda85b9b40a61199678c (commit) from caff669212d2465a3a387571305a7230d394c0e0 (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 cbd0308bc70855a2dd34bda85b9b40a61199678c Author: Daniel Kahn Gillmor Date: Fri Aug 5 10:47:51 2016 -0400 gpg: Avoid publishing the GnuPG version by default * g10/gpg.c (main): initialize opt.emit_version to 0 * doc/gpg.texi: document different default for --emit-version -- The version of GnuPG in use is not particularly helpful. It is not cryptographically verifiable, and it doesn't distinguish between significant version differences like 2.0.x and 2.1.x. Additionally, it leaks metadata that can be used to distinguish users from one another, and can potentially be used to target specific attacks if there are known behaviors that differ between major versions. It's probably better to take the more parsimonious approach to metadata production by default. (backport of master commit c9387e41db7520d176edd3d6613b85875bdeb32c) Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpg.texi b/doc/gpg.texi index 23636e9..cde27a5 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2504,9 +2504,9 @@ protected by the signature. @opindex emit-version Force inclusion of the version string in ASCII armored output. If given once only the name of the program and the major number is -emitted (default), given twice the minor is also emitted, given triple +emitted, given twice the minor is also emitted, given triple the micro is added, and given quad an operating system identification -is also emitted. @option{--no-emit-version} disables the version +is also emitted. @option{--no-emit-version} (default) disables the version line. @item --sig-notation @code{name=value} diff --git a/g10/gpg.c b/g10/gpg.c index 3a7dc38..a757fe3 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2018,7 +2018,7 @@ main (int argc, char **argv) opt.def_cert_expire="0"; set_homedir ( default_homedir () ); opt.passphrase_repeat=1; - opt.emit_version = 1; /* Limit to the major number. */ + opt.emit_version = 0; opt.list_options |= LIST_SHOW_UID_VALIDITY; opt.verify_options |= LIST_SHOW_UID_VALIDITY; ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 ++-- g10/gpg.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 14:24:31 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 09 Aug 2016 14:24:31 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-265-gf209ec8 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 f209ec8f581ae597b37f2e3a5e452e4b53b2d4c7 (commit) via 34b456c3fb9e59788b07a75441da482bb28bda87 (commit) via 17372393798ea5e2d6838f3dd1e001dd4a66c941 (commit) via bf776ce94cf454f1b3f1645b1cde09cd1c54324b (commit) via 3d2f027d0f40e7ec4ab48cee89ff0ee10b423566 (commit) from b5e16b036f0045524a583d8a366d8a3366fc0005 (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 f209ec8f581ae597b37f2e3a5e452e4b53b2d4c7 Author: Andre Heinecke Date: Tue Aug 9 14:10:15 2016 +0200 Qt: Add encryption test and refactor testsuite * lang/qt/tests/Makefile.am: Add t-encrypt and t-support. * lang/qt/tests/t-support.cpp, lang/qt/tests/t-support.c (QGpgMETest): New. Class to handle common cleanup / init. * lang/qt/tests/t-keylist.cpp, lang/qt/tests/t-keylocate.cpp, lang/qt/tests/t-ownertrust.cpp, lang/qt/tests/t-tofuinfo.cpp: Inherit QGpgMETest. * lang/qt/tests/t-encrypt.cpp: New. Test Symetric and Asymectric encryption. Mixed encryption test is disabled. diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 348c05b..13495a8 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -24,9 +24,11 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) EXTRA_DIST = initial.test -TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo +TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo \ + t-encrypt -moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc +moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ + t-encrypt.moc t-support.hmoc AM_LDFLAGS = -no-install @@ -46,16 +48,19 @@ check-local: ./pubring-stamp # add this dependency: initial.test : check-local -t_keylist_SOURCES = t-keylist.cpp -t_keylocate_SOURCES = t-keylocate.cpp -t_ownertrust_SOURCES = t-ownertrust.cpp -t_tofuinfo_SOURCES = t-tofuinfo.cpp t-support.h +support_src = t-support.h t-support.cpp + +t_keylist_SOURCES = t-keylist.cpp $(support_src) +t_keylocate_SOURCES = t-keylocate.cpp $(support_src) +t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src) +t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src) +t_encrypt_SOURCES = t-encrypt.cpp $(support_src) nodist_t_keylist_SOURCES = $(moc_files) BUILT_SOURCES = $(moc_files) -noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo +noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \ @@ -82,3 +87,6 @@ export GNUPGHOME := $(abs_builddir) .cpp.moc: $(MOC) `test -f '$<' || echo '$(srcdir)/'`$< -o $@ + +.h.hmoc: + $(MOC) `test -f '$<' || echo '$(srcdir)/'`$< -o $@ diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp new file mode 100644 index 0000000..b0b6994 --- /dev/null +++ b/lang/qt/tests/t-encrypt.cpp @@ -0,0 +1,194 @@ +/* t-encrypt.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ +#include +#include +#include +#include "keylistjob.h" +#include "encryptjob.h" +#include "qgpgmeencryptjob.h" +#include "encryptionresult.h" +#include "decryptionresult.h" +#include "qgpgmedecryptjob.h" +#include "qgpgmebackend.h" +#include "keylistresult.h" +#include "t-support.h" + +using namespace QGpgME; +using namespace GpgME; + +class EncryptionTest : public QGpgMETest +{ + Q_OBJECT + +private Q_SLOTS: + + void testSimpleEncryptDecrypt() + { + auto listjob = openpgp()->keyListJob(false, false, false); + std::vector keys; + auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa at example.net"), + false, keys); + Q_ASSERT(!keylistresult.error()); + Q_ASSERT(keys.size() == 1); + delete listjob; + + auto job = openpgp()->encryptJob(/*ASCII Armor */true, /* Textmode */ true); + Q_ASSERT(job); + QByteArray cipherText; + auto result = job->exec(keys, QStringLiteral("Hello World").toUtf8(), Context::AlwaysTrust, cipherText); + delete job; + Q_ASSERT(!result.error()); + const auto cipherString = QString::fromUtf8(cipherText); + Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----")); + + /* Now decrypt */ + auto ctx = Context::createForProtocol(OpenPGP); + ctx->setPassphraseProvider(new TestPassphraseProvider); + ctx->setPinentryMode(Context::PinentryLoopback); + auto decJob = new QGpgMEDecryptJob(ctx); + QByteArray plainText; + auto decResult = decJob->exec(cipherText, plainText); + Q_ASSERT(!result.error()); + Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello World")); + delete decJob; + } + + void testSymmetricEncryptDecrypt() + { + auto ctx = Context::createForProtocol(OpenPGP); + ctx->setPassphraseProvider(new TestPassphraseProvider); + ctx->setPinentryMode(Context::PinentryLoopback); + ctx->setArmor(true); + ctx->setTextMode(true); + auto job = new QGpgMEEncryptJob(ctx); + QByteArray cipherText; + auto result = job->exec(std::vector(), QStringLiteral("Hello symmetric World").toUtf8(), Context::AlwaysTrust, cipherText); + delete job; + Q_ASSERT(!result.error()); + const auto cipherString = QString::fromUtf8(cipherText); + Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----")); + + killAgent(mDir.path()); + + auto ctx2 = Context::createForProtocol(OpenPGP); + ctx2->setPassphraseProvider(new TestPassphraseProvider); + ctx2->setPinentryMode(Context::PinentryLoopback); + auto decJob = new QGpgMEDecryptJob(ctx2); + QByteArray plainText; + auto decResult = decJob->exec(cipherText, plainText); + Q_ASSERT(!result.error()); + Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World")); + delete decJob; + } + +private: + /* Loopback and passphrase provider don't work for mixed encryption. + * So this test is disabled until gnupg(?) is fixed for this. */ + void testMixedEncryptDecrypt() + { + auto listjob = openpgp()->keyListJob(false, false, false); + std::vector keys; + auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa at example.net"), + false, keys); + Q_ASSERT(!keylistresult.error()); + Q_ASSERT(keys.size() == 1); + delete listjob; + + auto ctx = Context::createForProtocol(OpenPGP); + ctx->setPassphraseProvider(new TestPassphraseProvider); + ctx->setPinentryMode(Context::PinentryLoopback); + ctx->setArmor(true); + ctx->setTextMode(true); + auto job = new QGpgMEEncryptJob(ctx); + QByteArray cipherText; + printf("Before exec, flags: %x\n", Context::Symmetric | Context::AlwaysTrust); + auto result = job->exec(keys, QStringLiteral("Hello symmetric World").toUtf8(), + static_cast(Context::Symmetric | Context::AlwaysTrust), + cipherText); + printf("After exec\n"); + delete job; + Q_ASSERT(!result.error()); + printf("Cipher:\n%s\n", cipherText.constData()); + const auto cipherString = QString::fromUtf8(cipherText); + Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----")); + + killAgent(mDir.path()); + + /* Now create a new homedir which with we test symetric decrypt. */ + QTemporaryDir tmp; + qputenv("GNUPGHOME", tmp.path().toUtf8()); + QFile agentConf(tmp.path() + QStringLiteral("/gpg-agent.conf")); + Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); + agentConf.write("allow-loopback-pinentry"); + agentConf.close(); + + auto ctx2 = Context::createForProtocol(OpenPGP); + ctx2->setPassphraseProvider(new TestPassphraseProvider); + ctx2->setPinentryMode(Context::PinentryLoopback); + ctx2->setTextMode(true); + auto decJob = new QGpgMEDecryptJob(ctx2); + QByteArray plainText; + auto decResult = decJob->exec(cipherText, plainText); + Q_ASSERT(!decResult.error()); + qDebug() << "Plain: " << plainText; + Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World")); + delete decJob; + + killAgent(tmp.path()); + qputenv("GNUPGHOME", mDir.path().toUtf8()); + } + +public Q_SLOT: + + void initTestCase() + { + QGpgMETest::initTestCase(); + const QString gpgHome = qgetenv("GNUPGHOME"); + qputenv("GNUPGHOME", mDir.path().toUtf8()); + Q_ASSERT(mDir.isValid()); + QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf")); + Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); + agentConf.write("allow-loopback-pinentry"); + agentConf.close(); + Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/pubring.gpg"), + mDir.path() + QStringLiteral("/pubring.gpg"))); + Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/secring.gpg"), + mDir.path() + QStringLiteral("/secring.gpg"))); + + } + +private: + QTemporaryDir mDir; +}; + +QTEST_MAIN(EncryptionTest) + +#include "t-encrypt.moc" diff --git a/lang/qt/tests/t-keylist.cpp b/lang/qt/tests/t-keylist.cpp index adc997a..2fbec28 100644 --- a/lang/qt/tests/t-keylist.cpp +++ b/lang/qt/tests/t-keylist.cpp @@ -37,10 +37,12 @@ #include "qgpgmebackend.h" #include "keylistresult.h" +#include "t-support.h" + using namespace QGpgME; using namespace GpgME; -class KeyListTest : public QObject +class KeyListTest : public QGpgMETest { Q_OBJECT @@ -48,7 +50,6 @@ Q_SIGNALS: void asyncDone(); private Q_SLOTS: - void testSingleKeyListSync() { KeyListJob *job = openpgp()->keyListJob(false, false, false); @@ -99,19 +100,9 @@ private Q_SLOTS: QSignalSpy spy (this, SIGNAL(asyncDone())); Q_ASSERT(spy.wait()); } - - void initTestCase() - { - const QString gpgHome = qgetenv("GNUPGHOME"); - QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set."); - } - - void cleanupTestCase() - { - QCoreApplication::sendPostedEvents(); - } }; QTEST_MAIN(KeyListTest) #include "t-keylist.moc" +#include "t-support.moc" diff --git a/lang/qt/tests/t-keylocate.cpp b/lang/qt/tests/t-keylocate.cpp index 5f52cc3..e75f24d 100644 --- a/lang/qt/tests/t-keylocate.cpp +++ b/lang/qt/tests/t-keylocate.cpp @@ -37,10 +37,12 @@ #include "keylistresult.h" #include "engineinfo.h" +#include "t-support.h" + using namespace QGpgME; using namespace GpgME; -class KeyLocateTest : public QObject +class KeyLocateTest : public QGpgMETest { Q_OBJECT @@ -119,16 +121,6 @@ private Q_SLOTS: Q_ASSERT(spy.wait()); } - void initTestCase() - { - const QString gpgHome = qgetenv("GNUPGHOME"); - QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set."); - } - - void cleanupTestCase() - { - QCoreApplication::sendPostedEvents(); - } private: QString mTestpattern; }; diff --git a/lang/qt/tests/t-ownertrust.cpp b/lang/qt/tests/t-ownertrust.cpp index 8784a79..b9efffd 100644 --- a/lang/qt/tests/t-ownertrust.cpp +++ b/lang/qt/tests/t-ownertrust.cpp @@ -37,10 +37,12 @@ #include "keylistresult.h" #include "changeownertrustjob.h" +#include "t-support.h" + using namespace QGpgME; using namespace GpgME; -class ChangeOwnerTrustTest: public QObject +class ChangeOwnerTrustTest: public QGpgMETest { Q_OBJECT @@ -98,17 +100,6 @@ private Q_SLOTS: key = keys.front(); Q_ASSERT (key.ownerTrust() == Key::Unknown); } - - void initTestCase() - { - const QString gpgHome = qgetenv("GNUPGHOME"); - QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set."); - } - - void cleanupTestCase() - { - QCoreApplication::sendPostedEvents(); - } }; QTEST_MAIN(ChangeOwnerTrustTest) diff --git a/lang/qt/tests/t-support.h b/lang/qt/tests/t-support.cpp similarity index 66% copy from lang/qt/tests/t-support.h copy to lang/qt/tests/t-support.cpp index 8755b99..202a251 100644 --- a/lang/qt/tests/t-support.h +++ b/lang/qt/tests/t-support.cpp @@ -1,4 +1,4 @@ -/* t-support.h +/* t-support.cpp This file is part of qgpgme, the Qt API binding for gpgme Copyright (c) 2016 Intevation GmbH @@ -29,19 +29,35 @@ your version. */ -#include "interfaces/passphraseprovider.h" -#include +#include "t-support.h" -namespace GpgME +#include + +void QGpgMETest::initTestCase() +{ + const QString gpgHome = qgetenv("GNUPGHOME"); + QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set."); +} + +void QGpgMETest::cleanupTestCase() { -class TestPassphraseProvider : public PassphraseProvider + QCoreApplication::sendPostedEvents(); + killAgent(); + printf("Killed agent\n"); +} +#include +void killAgent(const QString& dir) { -public: - char *getPassphrase(const char *useridHint, const char *description, - bool previousWasBad, bool &canceled) Q_DECL_OVERRIDE - { - return strdup("abc"); - } -}; - -} // namespace GpgME + QProcess proc; + proc.setProgram(QStringLiteral("gpg-connect-agent")); + QStringList arguments; + arguments << "-S " << dir + "/S.gpg-agent"; + proc.start(); + proc.waitForStarted(); + proc.write("KILLAGENT\n"); + proc.write("BYE\n"); + proc.closeWriteChannel(); + proc.waitForFinished(); +} + +#include "t-support.hmoc" diff --git a/lang/qt/tests/t-support.h b/lang/qt/tests/t-support.h index 8755b99..cf0cb26 100644 --- a/lang/qt/tests/t-support.h +++ b/lang/qt/tests/t-support.h @@ -28,9 +28,14 @@ you do not wish to do so, delete this exception statement from your version. */ +#ifndef T_SUPPORT_H +#define T_SUPPORT_H #include "interfaces/passphraseprovider.h" #include +#include +#include +#include namespace GpgME { @@ -43,5 +48,17 @@ public: return strdup("abc"); } }; - } // namespace GpgME + +void killAgent(const QString &dir = qgetenv("GNUPGHOME")); + +class QGpgMETest : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); +}; + +#endif // T_SUPPORT_H diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index f9634b2..8331092 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -55,7 +55,7 @@ static const char testMsg1[] = "=Crq6\n" "-----END PGP MESSAGE-----\n"; -class TofuInfoTest: public QObject +class TofuInfoTest: public QGpgMETest { Q_OBJECT @@ -216,8 +216,8 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: void initTestCase() { + QGpgMETest::initTestCase(); const QString gpgHome = qgetenv("GNUPGHOME"); - QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set."); qputenv("GNUPGHOME", mDir.path().toUtf8()); Q_ASSERT(mDir.isValid()); QFile conf(mDir.path() + QStringLiteral("/gpg.conf")); commit 34b456c3fb9e59788b07a75441da482bb28bda87 Author: Andre Heinecke Date: Tue Aug 9 13:10:08 2016 +0200 Qt: Add support for EncryptJobs with generic flags * lang/qt/src/encryptjob.h, lang/qt/src/signencryptjob.h, lang/qt/src/qgpgmeencryptjob.h, lang/qt/src/qgpgmeencryptjob.cpp, lang/qt/src/qgpgmesignencryptjob.cpp, lang/qt/src/qgpgmeencryptjob.cpp: Add start and exec overloads that accept generic EncryptFlags. -- While this technically is an ABI break (vtable change) there are no known classes outside qgpgme that inherit encryptjob or signencryptjob. And the new functions should be added to the bottom of the vtable. diff --git a/lang/qt/src/encryptjob.h b/lang/qt/src/encryptjob.h index 060ff8d..4ff9c82 100644 --- a/lang/qt/src/encryptjob.h +++ b/lang/qt/src/encryptjob.h @@ -39,6 +39,12 @@ #include #include +#ifdef BUILDING_QGPGME +# include "context.h" +#else +# include +#endif + class QByteArray; class QIODevice; @@ -103,13 +109,24 @@ public: virtual GpgME::EncryptionResult exec(const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) = 0; - /*! This is a hack to request BASE64 output (instead of whatever comes out normally). */ virtual void setOutputIsBase64Encoded(bool) = 0; + /** Like start but with an additional argument for EncryptionFlags for + * more flexibility. */ + virtual void start(const std::vector &recipients, + const std::shared_ptr &plainText, + const std::shared_ptr &cipherText = std::shared_ptr(), + const GpgME::Context::EncryptionFlags flags = GpgME::Context::None) = 0; + + /** Like exec but with an additional argument for EncryptionFlags for + * more flexibility. */ + virtual GpgME::EncryptionResult exec(const std::vector &recipients, + const QByteArray &plainText, + const GpgME::Context::EncryptionFlags flags, QByteArray &cipherText) = 0; Q_SIGNALS: void result(const GpgME::EncryptionResult &result, const QByteArray &cipherText, const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error()); }; diff --git a/lang/qt/src/qgpgmeencryptjob.cpp b/lang/qt/src/qgpgmeencryptjob.cpp index 8d0bfd4..82c8ed8 100644 --- a/lang/qt/src/qgpgmeencryptjob.cpp +++ b/lang/qt/src/qgpgmeencryptjob.cpp @@ -65,7 +65,7 @@ static QGpgMEEncryptJob::result_type encrypt(Context *ctx, QThread *thread, const std::vector &recipients, const std::weak_ptr &plainText_, const std::weak_ptr &cipherText_, - bool alwaysTrust, + const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded) { @@ -78,9 +78,6 @@ static QGpgMEEncryptJob::result_type encrypt(Context *ctx, QThread *thread, QGpgME::QIODeviceDataProvider in(plainText); const Data indata(&in); - const Context::EncryptionFlags eflags = - alwaysTrust ? Context::AlwaysTrust : Context::None; - if (!cipherText) { QGpgME::QByteArrayDataProvider out; Data outdata(&out); @@ -109,41 +106,54 @@ static QGpgMEEncryptJob::result_type encrypt(Context *ctx, QThread *thread, } -static QGpgMEEncryptJob::result_type encrypt_qba(Context *ctx, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, bool outputIsBsse64Encoded) +static QGpgMEEncryptJob::result_type encrypt_qba(Context *ctx, const std::vector &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded) { const std::shared_ptr buffer(new QBuffer); buffer->setData(plainText); if (!buffer->open(QIODevice::ReadOnly)) { assert(!"This should never happen: QBuffer::open() failed"); } - return encrypt(ctx, 0, recipients, buffer, std::shared_ptr(), alwaysTrust, outputIsBsse64Encoded); + return encrypt(ctx, 0, recipients, buffer, std::shared_ptr(), eflags, outputIsBsse64Encoded); } Error QGpgMEEncryptJob::start(const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust) { - run(std::bind(&encrypt_qba, std::placeholders::_1, recipients, plainText, alwaysTrust, mOutputIsBase64Encoded)); + run(std::bind(&encrypt_qba, std::placeholders::_1, recipients, plainText, + alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded)); return Error(); } -void QGpgMEEncryptJob::start(const std::vector &recipients, const std::shared_ptr &plainText, const std::shared_ptr &cipherText, bool alwaysTrust) +void QGpgMEEncryptJob::start(const std::vector &recipients, const std::shared_ptr &plainText, + const std::shared_ptr &cipherText, const Context::EncryptionFlags eflags) { run(std::bind(&encrypt, std::placeholders::_1, std::placeholders::_2, recipients, std::placeholders::_3, std::placeholders::_4, - alwaysTrust, + eflags, mOutputIsBase64Encoded), plainText, cipherText); } -EncryptionResult QGpgMEEncryptJob::exec(const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) +EncryptionResult QGpgMEEncryptJob::exec(const std::vector &recipients, const QByteArray &plainText, + const Context::EncryptionFlags eflags, QByteArray &cipherText) { - const result_type r = encrypt_qba(context(), recipients, plainText, alwaysTrust, mOutputIsBase64Encoded); + const result_type r = encrypt_qba(context(), recipients, plainText, eflags, mOutputIsBase64Encoded); cipherText = std::get<1>(r); resultHook(r); return mResult; } +void QGpgMEEncryptJob::start(const std::vector &recipients, const std::shared_ptr &plainText, const std::shared_ptr &cipherText, bool alwaysTrust) +{ + return start(recipients, plainText, cipherText, alwaysTrust ? Context::AlwaysTrust : Context::None); +} + +EncryptionResult QGpgMEEncryptJob::exec(const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) +{ + return exec(recipients, plainText, alwaysTrust ? Context::AlwaysTrust : Context::None, cipherText); +} + void QGpgMEEncryptJob::resultHook(const result_type &tuple) { mResult = std::get<0>(tuple); diff --git a/lang/qt/src/qgpgmeencryptjob.h b/lang/qt/src/qgpgmeencryptjob.h index d35a41b..42c1c78 100644 --- a/lang/qt/src/qgpgmeencryptjob.h +++ b/lang/qt/src/qgpgmeencryptjob.h @@ -82,6 +82,16 @@ public: GpgME::EncryptionResult exec(const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) Q_DECL_OVERRIDE; + /* from EncryptJob */ + void start(const std::vector &recipients, + const std::shared_ptr &plainText, + const std::shared_ptr &cipherText, + const GpgME::Context::EncryptionFlags flags) Q_DECL_OVERRIDE; + + /* from EncryptJob */ + GpgME::EncryptionResult exec(const std::vector &recipients, + const QByteArray &plainText, const GpgME::Context::EncryptionFlags flags, + QByteArray &cipherText) Q_DECL_OVERRIDE; /* from EncryptJob */ void setOutputIsBase64Encoded(bool on) Q_DECL_OVERRIDE; diff --git a/lang/qt/src/qgpgmesignencryptjob.cpp b/lang/qt/src/qgpgmesignencryptjob.cpp index d19ab0f..d2e45b1 100644 --- a/lang/qt/src/qgpgmesignencryptjob.cpp +++ b/lang/qt/src/qgpgmesignencryptjob.cpp @@ -62,7 +62,9 @@ void QGpgMESignEncryptJob::setOutputIsBase64Encoded(bool on) mOutputIsBase64Encoded = on; } -static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thread, const std::vector &signers, const std::vector &recipients, const std::weak_ptr &plainText_, const std::weak_ptr &cipherText_, bool alwaysTrust, bool outputIsBsse64Encoded) +static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thread, const std::vector &signers, + const std::vector &recipients, const std::weak_ptr &plainText_, + const std::weak_ptr &cipherText_, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded) { const std::shared_ptr &plainText = plainText_.lock(); const std::shared_ptr &cipherText = cipherText_.lock(); @@ -73,9 +75,6 @@ static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thr QGpgME::QIODeviceDataProvider in(plainText); const Data indata(&in); - const Context::EncryptionFlags eflags = - alwaysTrust ? Context::AlwaysTrust : Context::None; - ctx->clearSigningKeys(); Q_FOREACH (const Key &signer, signers) if (!signer.isNull()) @@ -111,35 +110,48 @@ static QGpgMESignEncryptJob::result_type sign_encrypt(Context *ctx, QThread *thr } -static QGpgMESignEncryptJob::result_type sign_encrypt_qba(Context *ctx, const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, bool outputIsBsse64Encoded) +static QGpgMESignEncryptJob::result_type sign_encrypt_qba(Context *ctx, const std::vector &signers, + const std::vector &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, bool outputIsBsse64Encoded) { const std::shared_ptr buffer(new QBuffer); buffer->setData(plainText); if (!buffer->open(QIODevice::ReadOnly)) { assert(!"This should never happen: QBuffer::open() failed"); } - return sign_encrypt(ctx, 0, signers, recipients, buffer, std::shared_ptr(), alwaysTrust, outputIsBsse64Encoded); + return sign_encrypt(ctx, 0, signers, recipients, buffer, std::shared_ptr(), eflags, outputIsBsse64Encoded); } Error QGpgMESignEncryptJob::start(const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust) { - run(std::bind(&sign_encrypt_qba, std::placeholders::_1, signers, recipients, plainText, alwaysTrust, mOutputIsBase64Encoded)); + run(std::bind(&sign_encrypt_qba, std::placeholders::_1, signers, recipients, plainText, alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded)); return Error(); } +void QGpgMESignEncryptJob::start(const std::vector &signers, const std::vector &recipients, + const std::shared_ptr &plainText, const std::shared_ptr &cipherText, const Context::EncryptionFlags eflags) +{ + run(std::bind(&sign_encrypt, std::placeholders::_1, std::placeholders::_2, signers, recipients, std::placeholders::_3, std::placeholders::_4, eflags, mOutputIsBase64Encoded), plainText, cipherText); +} + void QGpgMESignEncryptJob::start(const std::vector &signers, const std::vector &recipients, const std::shared_ptr &plainText, const std::shared_ptr &cipherText, bool alwaysTrust) { - run(std::bind(&sign_encrypt, std::placeholders::_1, std::placeholders::_2, signers, recipients, std::placeholders::_3, std::placeholders::_4, alwaysTrust, mOutputIsBase64Encoded), plainText, cipherText); + return start(signers, recipients, plainText, cipherText, alwaysTrust ? Context::AlwaysTrust : Context::None); } -std::pair QGpgMESignEncryptJob::exec(const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) +std::pair QGpgMESignEncryptJob::exec(const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, const Context::EncryptionFlags eflags, QByteArray &cipherText) { - const result_type r = sign_encrypt_qba(context(), signers, recipients, plainText, alwaysTrust, mOutputIsBase64Encoded); + const result_type r = sign_encrypt_qba(context(), signers, recipients, plainText, eflags, mOutputIsBase64Encoded); cipherText = std::get<2>(r); resultHook(r); return mResult; } +std::pair QGpgMESignEncryptJob::exec(const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) +{ + return exec(signers, recipients, plainText, alwaysTrust ? Context::AlwaysTrust : Context::None, cipherText); +} + + #if 0 TODO port? diff --git a/lang/qt/src/qgpgmesignencryptjob.h b/lang/qt/src/qgpgmesignencryptjob.h index 49177d3..e76c245 100644 --- a/lang/qt/src/qgpgmesignencryptjob.h +++ b/lang/qt/src/qgpgmesignencryptjob.h @@ -87,12 +87,24 @@ public: const std::shared_ptr &cipherText, bool alwaysTrust) Q_DECL_OVERRIDE; + void start(const std::vector &signers, + const std::vector &recipients, + const std::shared_ptr &plainText, + const std::shared_ptr &cipherText, + const GpgME::Context::EncryptionFlags flags) Q_DECL_OVERRIDE; + std::pair exec(const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust, QByteArray &cipherText) Q_DECL_OVERRIDE; + std::pair + exec(const std::vector &signers, + const std::vector &recipients, + const QByteArray &plainText, const GpgME::Context::EncryptionFlags flags, + QByteArray &cipherText) Q_DECL_OVERRIDE; + /* from SignEncryptJob */ void setOutputIsBase64Encoded(bool on) Q_DECL_OVERRIDE; diff --git a/lang/qt/src/signencryptjob.h b/lang/qt/src/signencryptjob.h index 4818d2a..b0aafe3 100644 --- a/lang/qt/src/signencryptjob.h +++ b/lang/qt/src/signencryptjob.h @@ -38,8 +38,10 @@ #ifdef BUILDING_QGPGME # include "global.h" +# include "context.h" #else # include +# include #endif #include @@ -123,6 +125,21 @@ public: */ virtual void setOutputIsBase64Encoded(bool) = 0; + /** Like start but with an additional argument for EncryptionFlags for + * more flexibility. */ + virtual void start(const std::vector &signers, + const std::vector &recipients, + const std::shared_ptr &plainText, + const std::shared_ptr &cipherText = std::shared_ptr(), + const GpgME::Context::EncryptionFlags flags = GpgME::Context::None) = 0; + + /** Like exec but with an additional argument for EncryptionFlags for + * more flexibility. */ + virtual std::pair + exec(const std::vector &signers, + const std::vector &recipients, + const QByteArray &plainText, + const GpgME::Context::EncryptionFlags flags, QByteArray &cipherText) = 0; Q_SIGNALS: void result(const GpgME::SigningResult &signingresult, const GpgME::EncryptionResult &encryptionresult, commit 17372393798ea5e2d6838f3dd1e001dd4a66c941 Author: Andre Heinecke Date: Tue Aug 9 13:07:30 2016 +0200 Cpp: Add support for all EncryptionFlags * lang/cpp/src/context.h (EncryptionFlags): Extend. * lang/cpp/src/context.cpp (encryptflags2encryptflags): Ditto. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 814e5a8..d63573f 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1094,6 +1094,18 @@ static gpgme_encrypt_flags_t encryptflags2encryptflags(Context::EncryptionFlags if (flags & Context::NoEncryptTo) { result |= GPGME_ENCRYPT_NO_ENCRYPT_TO; } + if (flags & Context::Prepare) { + result |= GPGME_ENCRYPT_PREPARE; + } + if (flags & Context::ExpectSign) { + result |= GPGME_ENCRYPT_EXPECT_SIGN; + } + if (flags & Context::NoCompress) { + result |= GPGME_ENCRYPT_NO_COMPRESS; + } + if (flags & Context::Symmetric) { + result |= GPGME_ENCRYPT_SYMMETRIC; + } return static_cast(result); } @@ -1395,6 +1407,11 @@ std::ostream &operator<<(std::ostream &os, Context::EncryptionFlags flags) os << "GpgME::Context::EncryptionFlags("; #define CHECK( x ) if ( !(flags & (Context::x)) ) {} else do { os << #x " "; } while (0) CHECK(AlwaysTrust); + CHECK(NoEncryptTo); + CHECK(Prepare); + CHECK(ExpectSign); + CHECK(NoCompress); + CHECK(Symmetric); #undef CHECK return os << ')'; } diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index c9c2af7..c7c0ecb 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -292,7 +292,15 @@ public: // Encryption // - enum EncryptionFlags { None = 0, AlwaysTrust = 1, NoEncryptTo = 2 }; + enum EncryptionFlags { + None = 0, + AlwaysTrust = 1, + NoEncryptTo = 2, + Prepare = 4, + ExpectSign = 8, + NoCompress = 16, + Symmetric = 32 + }; EncryptionResult encrypt(const std::vector &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags); GpgME::Error encryptSymmetrically(const Data &plainText, Data &cipherText); GpgME::Error startEncryption(const std::vector &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags); commit bf776ce94cf454f1b3f1645b1cde09cd1c54324b Author: Andre Heinecke Date: Tue Aug 9 12:56:01 2016 +0200 Cpp: Fix simple symmetric encryption * lang/cpp/src/context.cpp (Context::encrypt): If no recipients are provided encrypt with NULL and not an empty array. -- Sending an empty array leads to an invalid argument error. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 20d827e..814e5a8 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1113,7 +1113,8 @@ EncryptionResult Context::encrypt(const std::vector &recipients, const Data } } *keys_it++ = 0; - d->lasterr = gpgme_op_encrypt(d->ctx, keys, encryptflags2encryptflags(flags), + d->lasterr = gpgme_op_encrypt(d->ctx, recipients.empty() ? nullptr : keys, + encryptflags2encryptflags(flags), pdp ? pdp->data : 0, cdp ? cdp->data : 0); delete[] keys; return EncryptionResult(d->ctx, Error(d->lasterr)); commit 3d2f027d0f40e7ec4ab48cee89ff0ee10b423566 Author: Andre Heinecke Date: Tue Aug 9 11:40:29 2016 +0200 core: Add support for mixed symmetric and asym enc * src/gpgme.h.in (gpgme_encrypt_flags_t): New flag GPGME_ENCRYPT_SYMMETRIC. * src/engine-gpg.c (gpg_encrypt): Also add --symmetric if the flag is given. * NEWS: Mention new flag. * tests/run-encrypt.c (show_usage): Extend for --symmetric. (main): Handle --symmetric. (main): Set passphrase_cb in loopback mode. (main): Fix encrypt call if no recipients are given. * tests/gpg/t-encrypt-mixed.c: New. * tests/gpg/Makefile.am (c_tests): Add new test. * doc/gpgme.texi: Document new flag. diff --git a/NEWS b/NEWS index 09d0a1c..71c18a8 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] GPGME_DATA_TYPE_PGP_ENCRYPTED NEW. GPGME_DATA_TYPE_PGP_SIGNATURE NEW. GPGME_DATA_ENCODING_MIME NEW. + GPGME_ENCRYPT_SYMMETRIC NEW. Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0] diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 68f85ec..907099a 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -5398,6 +5398,12 @@ protocol to prepare an encryption (i.e. sending the @code{GPGME_ENCRYPT_EXPECT_SIGN} symbol the UI Server is advised to also expect a sign command. + at item GPGME_ENCRYPT_SYMMETRIC +The @code{GPGME_ENCRYPT_SYMMETRIC} symbol specifies that the +output should be additionally encrypted symmetically even +if recipients are provided. This feature is only supported for +for the OpenPGP crypto engine. + @end table If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 942711f..ae78d9d 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1718,9 +1718,12 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, { engine_gpg_t gpg = engine; gpgme_error_t err; - int symmetric = !recp; - err = add_arg (gpg, symmetric ? "--symmetric" : "--encrypt"); + if (recp) + err = add_arg (gpg, "--encrypt"); + + if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp)) + err = add_arg (gpg, "--symmetric"); if (!err && use_armor) err = add_arg (gpg, "--armor"); @@ -1732,7 +1735,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, && have_gpg_version (gpg, "2.1.14")) err = add_arg (gpg, "--mimemode"); - if (!symmetric) + if (recp) { /* If we know that all recipients are valid (full or ultimate trust) we can suppress further checks. */ diff --git a/src/gpgme.h.in b/src/gpgme.h.in index c05686d..56d15f4 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1392,7 +1392,8 @@ typedef enum GPGME_ENCRYPT_NO_ENCRYPT_TO = 2, GPGME_ENCRYPT_PREPARE = 4, GPGME_ENCRYPT_EXPECT_SIGN = 8, - GPGME_ENCRYPT_NO_COMPRESS = 16 + GPGME_ENCRYPT_NO_COMPRESS = 16, + GPGME_ENCRYPT_SYMMETRIC = 32 } gpgme_encrypt_flags_t; diff --git a/tests/gpg/Makefile.am b/tests/gpg/Makefile.am index 107397b..e1c033b 100644 --- a/tests/gpg/Makefile.am +++ b/tests/gpg/Makefile.am @@ -38,7 +38,7 @@ c_tests = \ t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers \ t-decrypt t-verify t-decrypt-verify t-sig-notation t-export \ t-import t-trustlist t-edit t-keylist t-keylist-sig t-wait \ - t-encrypt-large t-file-name t-gpgconf $(tests_unix) + t-encrypt-large t-file-name t-gpgconf t-encrypt-mixed $(tests_unix) TESTS = initial.test $(c_tests) final.test diff --git a/tests/gpg/t-encrypt-mixed.c b/tests/gpg/t-encrypt-mixed.c new file mode 100644 index 0000000..28d8aa3 --- /dev/null +++ b/tests/gpg/t-encrypt-mixed.c @@ -0,0 +1,126 @@ +/* t-encrypt-mixed.c - Regression test. + Copyright (C) 2016 Intevation GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify 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. + + GPGME 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 + 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. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "t-support.h" + +/* Tests mixed symmetric and asymetric decryption. Verifies + that an encrypted message can be decrypted without the + secret key but that the recipient is also set correctly. */ +int +main (int argc, char *argv[]) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t in, out; + gpgme_key_t key[2] = { NULL, NULL }; + gpgme_encrypt_result_t result; + gpgme_decrypt_result_t dec_result; + gpgme_recipient_t recipient; + const char *text = "Hallo Leute\n"; + char *text2; + size_t len; + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_armor (ctx, 1); + + err = gpgme_data_new_from_mem (&in, text, strlen (text), 0); + fail_if_err (err); + + err = gpgme_data_new (&out); + fail_if_err (err); + + /* A recipient for which we don't have a secret key */ + err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", + &key[0], 0); + fail_if_err (err); + + err = gpgme_op_encrypt (ctx, key, + GPGME_ENCRYPT_ALWAYS_TRUST | GPGME_ENCRYPT_SYMMETRIC, + in, out); + fail_if_err (err); + result = gpgme_op_encrypt_result (ctx); + if (result->invalid_recipients) + { + fprintf (stderr, "Invalid recipient encountered: %s\n", + result->invalid_recipients->fpr); + exit (1); + } + + print_data (out); + + /* Now try to decrypt */ + gpgme_data_seek (out, 0, SEEK_SET); + + gpgme_data_release (in); + err = gpgme_data_new (&in); + fail_if_err (err); + + err = gpgme_op_decrypt (ctx, out, in); + fail_if_err (err); + + fputs ("Begin Result Decryption:\n", stdout); + print_data (in); + fputs ("End Result.\n", stdout); + + dec_result = gpgme_op_decrypt_result (ctx); + if (dec_result->unsupported_algorithm || dec_result->wrong_key_usage) + { + fprintf (stderr, "%s:%d: Decryption failed\n", __FILE__, __LINE__); + exit (1); + } + + text2 = gpgme_data_release_and_get_mem (in, &len); + if (strncmp (text, text2, len)) + { + fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__); + exit (1); + } + + recipient = dec_result->recipients; + if (!recipient || recipient->next) + { + fprintf (stderr, "%s:%d: Invalid recipients \n", __FILE__, __LINE__); + exit (1); + } + + if (strncmp (recipient->keyid, "5381EA4EE29BA37F", 16)) + { + fprintf (stderr, "%s:%d: Not encrypted to recipient's subkey \n", __FILE__, __LINE__); + exit (1); + } + + gpgme_key_unref (key[0]); + gpgme_data_release (out); + gpgme_release (ctx); + return 0; +} diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c index a00f028..210f88a 100644 --- a/tests/run-encrypt.c +++ b/tests/run-encrypt.c @@ -70,6 +70,7 @@ show_usage (int ex) " --uiserver use the UI server\n" " --loopback use a loopback pinentry\n" " --key NAME encrypt to key NAME\n" + " --symmetric encrypt symmetric (OpenPGP only)\n" , stderr); exit (ex); } @@ -91,6 +92,7 @@ main (int argc, char **argv) gpgme_key_t keys[10+1]; int keycount = 0; int i; + gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST; if (argc) { argc--; argv++; } @@ -148,6 +150,11 @@ main (int argc, char **argv) use_loopback = 1; argc--; argv++; } + else if (!strcmp (*argv, "--symmetric")) + { + flags |= GPGME_ENCRYPT_SYMMETRIC; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); @@ -174,7 +181,10 @@ main (int argc, char **argv) if (print_status) gpgme_set_status_cb (ctx, status_cb, NULL); if (use_loopback) - gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK); + { + gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK); + gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); + } for (i=0; i < keycount; i++) { @@ -194,7 +204,7 @@ main (int argc, char **argv) err = gpgme_data_new (&out); fail_if_err (err); - err = gpgme_op_encrypt (ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + err = gpgme_op_encrypt (ctx, keycount ? keys : NULL, flags, in, out); result = gpgme_op_encrypt_result (ctx); if (result) print_result (result); ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/gpgme.texi | 6 + lang/cpp/src/context.cpp | 20 ++- lang/cpp/src/context.h | 10 +- lang/qt/src/encryptjob.h | 19 +- lang/qt/src/qgpgmeencryptjob.cpp | 32 ++-- lang/qt/src/qgpgmeencryptjob.h | 10 ++ lang/qt/src/qgpgmesignencryptjob.cpp | 32 ++-- lang/qt/src/qgpgmesignencryptjob.h | 12 ++ lang/qt/src/signencryptjob.h | 17 ++ lang/qt/tests/Makefile.am | 22 ++- lang/qt/tests/t-encrypt.cpp | 194 +++++++++++++++++++++ lang/qt/tests/t-keylist.cpp | 17 +- lang/qt/tests/t-keylocate.cpp | 14 +- lang/qt/tests/t-ownertrust.cpp | 15 +- .../{src/qgpgmedeletejob.h => tests/t-support.cpp} | 56 +++--- lang/qt/tests/t-support.h | 19 +- lang/qt/tests/t-tofuinfo.cpp | 4 +- src/engine-gpg.c | 9 +- src/gpgme.h.in | 3 +- tests/gpg/Makefile.am | 2 +- tests/gpg/t-encrypt-mixed.c | 126 +++++++++++++ tests/run-encrypt.c | 14 +- 23 files changed, 545 insertions(+), 109 deletions(-) create mode 100644 lang/qt/tests/t-encrypt.cpp copy lang/qt/{src/qgpgmedeletejob.h => tests/t-support.cpp} (66%) create mode 100644 tests/gpg/t-encrypt-mixed.c hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 17:47:59 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 09 Aug 2016 17:47:59 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-58-ge630f90 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 e630f904993725c54ec63be00369589b7b7234d2 (commit) via 16feb1e0ea9b5d3966f22f4ae047335b9d1b60e1 (commit) from 49829c29e541546084950b8a153067db371d101a (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 e630f904993725c54ec63be00369589b7b7234d2 Author: Werner Koch Date: Tue Aug 9 17:44:54 2016 +0200 agent: Fix regression in recent ssh changes. * agent/command-ssh.c (sexp_key_construct): Lowercase the algo name. -- We need to use a lowercase version of the algo in S-expression. Unfortunately Libgcrypt has no function for this, thus we need to malloc and first. Fixes-commit: ebf24e3 Signed-off-by: Werner Koch diff --git a/agent/command-ssh.c b/agent/command-ssh.c index b01cc06..2def342 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1685,7 +1685,7 @@ sexp_key_construct (gcry_sexp_t *r_sexp, void *formatbuf = NULL; void **arg_list = NULL; estream_t format = NULL; - + char *algo_name = NULL; if ((key_spec.flags & SPEC_FLAG_IS_EdDSA)) { @@ -1723,7 +1723,6 @@ sexp_key_construct (gcry_sexp_t *r_sexp, const char *elems; size_t elems_n; unsigned int i, j; - const char *algo_name; if (secret) elems = key_spec.elems_sexp_order; @@ -1750,7 +1749,13 @@ sexp_key_construct (gcry_sexp_t *r_sexp, es_fputs ("(%s(%s", format); arg_list[arg_idx++] = &key_identifier[secret]; - algo_name = gcry_pk_algo_name (key_spec.algo); + algo_name = xtrystrdup (gcry_pk_algo_name (key_spec.algo)); + if (!algo_name) + { + err = gpg_error_from_syserror (); + goto out; + } + strlwr (algo_name); arg_list[arg_idx++] = &algo_name; if (curve_name) { @@ -1798,6 +1803,7 @@ sexp_key_construct (gcry_sexp_t *r_sexp, es_fclose (format); xfree (arg_list); xfree (formatbuf); + xfree (algo_name); return err; } commit 16feb1e0ea9b5d3966f22f4ae047335b9d1b60e1 Author: Werner Koch Date: Tue Aug 9 16:22:24 2016 +0200 gpg: Extend the PROGRESS line to give the used unit. * g10/progress.c (write_status_progress): Print the units parameter. Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 02f9bad..0139fdb 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -929,7 +929,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: - 3 :: Ambigious specification - 4 :: Key is stored on a smartcard. -*** PROGRESS +*** PROGRESS [] Used by the primegen and Public key functions to indicate progress. is the character displayed with no --status-fd enabled, with the linefeed replaced by an 'X'. is the @@ -953,6 +953,9 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: the data of a smartcard. - card_busy :: A smartcard is still working + is sometines used to describe the units for and + . For example "B", "KiB", or "MiB". + *** BACKUP_KEY_CREATED A backup of a key identified by has been writte to the file ; is percent-escaped. diff --git a/g10/progress.c b/g10/progress.c index a1027b8..efc3b3a 100644 --- a/g10/progress.c +++ b/g10/progress.c @@ -75,7 +75,9 @@ static void write_status_progress (const char *what, unsigned long current, unsigned long total) { - char buffer[50]; + char buffer[60]; + char units[] = "BKMGTPEZY?"; + int unitidx = 0; /* Although we use an unsigned long for the values, 32 bit * applications using GPGME will use an "int" and thus are limited @@ -98,6 +100,7 @@ write_status_progress (const char *what, { total /= 1024; current /= 1024; + unitidx++; } } else @@ -105,11 +108,17 @@ write_status_progress (const char *what, while (current > 1024*1024) { current /= 1024; + unitidx++; } } - snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu", - what? what : "?", current, total); + if (unitidx > 9) + unitidx = 9; + + snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu %c%s", + what? what : "?", current, total, + units[unitidx], + unitidx? "iB" : ""); write_status_text (STATUS_PROGRESS, buffer); } ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 12 +++++++++--- doc/DETAILS | 5 ++++- g10/progress.c | 15 ++++++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 9 18:41:12 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 09 Aug 2016 18:41:12 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-266-g969f223 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 969f223d8de21d7c8b0f7646bbf8dbb5864e8d03 (commit) from f209ec8f581ae597b37f2e3a5e452e4b53b2d4c7 (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 969f223d8de21d7c8b0f7646bbf8dbb5864e8d03 Author: Andre Heinecke Date: Tue Aug 9 18:39:56 2016 +0200 Qt: Clean up debug output in tests * lang/qt/tests/t-support.cpp: Remove accidentally commited debug output. diff --git a/lang/qt/tests/t-support.cpp b/lang/qt/tests/t-support.cpp index 202a251..ffb0f9e 100644 --- a/lang/qt/tests/t-support.cpp +++ b/lang/qt/tests/t-support.cpp @@ -43,9 +43,8 @@ void QGpgMETest::cleanupTestCase() { QCoreApplication::sendPostedEvents(); killAgent(); - printf("Killed agent\n"); } -#include + void killAgent(const QString& dir) { QProcess proc; ----------------------------------------------------------------------- Summary of changes: lang/qt/tests/t-support.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 06:57:19 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 10 Aug 2016 06:57:19 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-59-gf14795d 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 f14795d57f6c81709e9225dd3c5dfd3495cf1b2b (commit) from e630f904993725c54ec63be00369589b7b7234d2 (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 f14795d57f6c81709e9225dd3c5dfd3495cf1b2b Author: NIIBE Yutaka Date: Wed Aug 10 13:51:14 2016 +0900 agent: SSH support fix. * agent/command-ssh.c (ssh_handler_request_identities): Keep error message same. -- Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 2def342..83a27ed 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2623,7 +2623,9 @@ ssh_handler_request_identities (ctrl_t ctrl, err = agent_public_key_from_file (ctrl, grip, &key_public); if (err) { - log_error ("failed to read the public key\n"); + log_error ("%s:%d: key '%s' skipped: %s\n", + cf->fname, cf->lnr, cf->item.hexgrip, + gpg_strerror (err)); continue; } ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 09:43:16 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 10 Aug 2016 09:43:16 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-61-ge13f1ea 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 e13f1ea8fff3964dc3008432f5c0f26aaa2eaa35 (commit) via b2b21580b68f3a9069562f99675b389a0d044713 (commit) from f14795d57f6c81709e9225dd3c5dfd3495cf1b2b (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 e13f1ea8fff3964dc3008432f5c0f26aaa2eaa35 Author: Justus Winter Date: Wed Aug 10 09:32:53 2016 +0200 tests: Run each test in a clean environment. * tests/openpgp/Makefile.am (TESTS_ENVIRONMENT): Drop obsolete variables, add 'srcdir', use absolute paths. (TESTS): Rename to 'XTESTS' to avoid emitting the automake test runner. Drop 'setup.scm' and 'finish.scm'. (xcheck): New target that runs 'run-tests.scm', our Scheme test suite runner. It will run each test in a clean environment, isolated from the other tests. (EXTRA_DIST): Adapt accordingly. * tests/openpgp/README: Likewise. Signed-off-by: Justus Winter diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 564439a..a43f23b 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -36,16 +36,15 @@ fake_pinentry_SOURCES = fake-pinentry.c TMP ?= /tmp -TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO= LC_ALL=C \ +TESTS_ENVIRONMENT = LC_ALL=C \ EXEEXT=$(EXEEXT) \ PATH=../gpgscm:$(PATH) \ TMP=$(TMP) \ + srcdir=$(abs_srcdir) \ objdir=$(abs_top_builddir) \ - GPGSCM_PATH=$(top_srcdir)/tests/gpgscm:$(top_srcdir)/tests/openpgp + GPGSCM_PATH=$(abs_top_srcdir)/tests/gpgscm:$(abs_top_srcdir)/tests/openpgp -# Note: setup.scm needs to be the first test to run and finish.scm -# the last one -TESTS = setup.scm \ +XTESTS = \ version.scm \ mds.scm \ decrypt.scm \ @@ -85,9 +84,20 @@ TESTS = setup.scm \ ssh.scm \ issue2015.scm \ issue2346.scm \ - issue2419.scm \ - finish.scm + issue2419.scm +# XXX: Currently, one cannot override automake's 'check' target. As a +# workaround, we avoid defining 'TESTS', thus automake will not emit +# the 'check' target. For extra robustness, we merely define a +# dependency on 'xcheck', so this hack should also work even if +# automake would emit the 'check' target, as adding dependencies to +# targets is okay. +check: xcheck + +.PHONY: xcheck +xcheck: + $(TESTS_ENVIRONMENT) $(abs_top_builddir)/tests/gpgscm/gpgscm \ + run-tests.scm $(XTESTS) TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \ @@ -158,7 +168,7 @@ sample_keys = samplekeys/README \ sample_msgs = samplemsgs/issue2419.asc -EXTRA_DIST = defs.inc defs.scm pinentry.sh $(TESTS) $(TEST_FILES) \ +EXTRA_DIST = defs.inc defs.scm pinentry.sh $(XTESTS) $(TEST_FILES) \ mkdemodirs signdemokey $(priv_keys) $(sample_keys) \ $(sample_msgs) ChangeLog-2011 run-tests.scm diff --git a/tests/openpgp/README b/tests/openpgp/README index 1f8654b..9b384be 100644 --- a/tests/openpgp/README +++ b/tests/openpgp/README @@ -8,7 +8,7 @@ On POSIX you can just use or - $ make -C tests/openpgp check TESTS="setup.scm your-test.scm finish.scm" + $ make -C tests/openpgp check XTESTS="setup.scm your-test.scm finish.scm" as before. ** using the Scheme driver commit b2b21580b68f3a9069562f99675b389a0d044713 Author: Justus Winter Date: Wed Aug 10 07:58:24 2016 +0200 tests: Make ssh test more robust. * tests/openpgp/ssh.scm: Drop the 'MD5:' which was not printed by previous ssh versions. Signed-off-by: Justus Winter diff --git a/tests/openpgp/ssh.scm b/tests/openpgp/ssh.scm index dfa1f52..1fe2e5d 100755 --- a/tests/openpgp/ssh.scm +++ b/tests/openpgp/ssh.scm @@ -33,10 +33,10 @@ (path-expand "ssh-add" (string-split (getenv "PATH") *pathsep*)))) (define keys - '(("dsa" "MD5:9a:e1:f1:5f:46:ea:a5:06:e1:e2:f8:38:8e:06:54:58") - ("rsa" "MD5:c9:85:b5:55:00:84:a9:82:5a:df:d6:62:1b:5a:28:22") - ("ecdsa" "MD5:93:37:30:a6:4e:e7:6a:22:79:77:8e:bf:ed:14:e9:8e") - ("ed25519" "MD5:08:df:be:af:d2:f5:32:20:3a:1c:56:06:be:31:0f:bf"))) + '(("dsa" "9a:e1:f1:5f:46:ea:a5:06:e1:e2:f8:38:8e:06:54:58") + ("rsa" "c9:85:b5:55:00:84:a9:82:5a:df:d6:62:1b:5a:28:22") + ("ecdsa" "93:37:30:a6:4e:e7:6a:22:79:77:8e:bf:ed:14:e9:8e") + ("ed25519" "08:df:be:af:d2:f5:32:20:3a:1c:56:06:be:31:0f:bf"))) (for-each-p' "Importing ssh keys..." @@ -62,5 +62,5 @@ (pipe:spawn `(,SSH-ADD -))) (unless (string-contains? (call-popen `(,SSH-ADD -l "-E" md5) "") - "MD5:c9:85:b5:55:00:84:a9:82:5a:df:d6:62:1b:5a:28:22") + "c9:85:b5:55:00:84:a9:82:5a:df:d6:62:1b:5a:28:22") (error "known private key not (re-)added to sshcontrol")) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/Makefile.am | 26 ++++++++++++++++++-------- tests/openpgp/README | 2 +- tests/openpgp/ssh.scm | 10 +++++----- 3 files changed, 24 insertions(+), 14 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 09:51:41 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 10 Aug 2016 09:51:41 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-267-g0c222e1 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 0c222e1b3cabe1a8b84a2877420cdd5df56171b5 (commit) from 969f223d8de21d7c8b0f7646bbf8dbb5864e8d03 (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 0c222e1b3cabe1a8b84a2877420cdd5df56171b5 Author: Andre Heinecke Date: Wed Aug 10 09:50:26 2016 +0200 Qt: Fix t-keylist moc include * lang/qt/tests/t-keylist.cpp: Don't include t-support.moc -- Accidental leftover from trying to generate t-support moc from another cpp file. This was solved instead by a new rule to generate moc files from the header. diff --git a/lang/qt/tests/t-keylist.cpp b/lang/qt/tests/t-keylist.cpp index 2fbec28..767c96b 100644 --- a/lang/qt/tests/t-keylist.cpp +++ b/lang/qt/tests/t-keylist.cpp @@ -105,4 +105,3 @@ private Q_SLOTS: QTEST_MAIN(KeyListTest) #include "t-keylist.moc" -#include "t-support.moc" ----------------------------------------------------------------------- Summary of changes: lang/qt/tests/t-keylist.cpp | 1 - 1 file changed, 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 10:28:09 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 10 Aug 2016 10:28:09 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-268-g2708873 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 270887309f4b673b13e58c29ea3989c56989590e (commit) from 0c222e1b3cabe1a8b84a2877420cdd5df56171b5 (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 270887309f4b673b13e58c29ea3989c56989590e Author: Andre Heinecke Date: Wed Aug 10 10:27:05 2016 +0200 core: Ensure err is initalized in gpg_encrypt * src/engine-gpg.c (gpg_encrypt): Initialize err. diff --git a/src/engine-gpg.c b/src/engine-gpg.c index ae78d9d..4fad977 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1717,7 +1717,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t ciph, int use_armor) { engine_gpg_t gpg = engine; - gpgme_error_t err; + gpgme_error_t err = 0; if (recp) err = add_arg (gpg, "--encrypt"); ----------------------------------------------------------------------- Summary of changes: src/engine-gpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 10:38:38 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 10 Aug 2016 10:38:38 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-269-g04f994d 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 04f994d5db6db0575dc73c2356c7d51424e2d9fe (commit) from 270887309f4b673b13e58c29ea3989c56989590e (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 04f994d5db6db0575dc73c2356c7d51424e2d9fe Author: Justus Winter Date: Wed Aug 10 10:37:31 2016 +0200 tests: Fix memory leak. * tests/gpg/t-encrypt-mixed.c (main): Free 'text2'. Signed-off-by: Justus Winter diff --git a/tests/gpg/t-encrypt-mixed.c b/tests/gpg/t-encrypt-mixed.c index 28d8aa3..6ad976a 100644 --- a/tests/gpg/t-encrypt-mixed.c +++ b/tests/gpg/t-encrypt-mixed.c @@ -120,6 +120,7 @@ main (int argc, char *argv[]) } gpgme_key_unref (key[0]); + free (text2); gpgme_data_release (out); gpgme_release (ctx); return 0; ----------------------------------------------------------------------- Summary of changes: tests/gpg/t-encrypt-mixed.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 12:08:17 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 10 Aug 2016 12:08:17 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-272-gd467018 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 d467018ce36f5be36751267c3b6079e8c1ee5d8a (commit) via a27d7755d071aad42efc2aa4ea3899ba7b17f8bf (commit) via 21d5e71d486da8e37cf53f2b968646b39a6daa72 (commit) from 04f994d5db6db0575dc73c2356c7d51424e2d9fe (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 d467018ce36f5be36751267c3b6079e8c1ee5d8a Author: Andre Heinecke Date: Wed Aug 10 12:06:39 2016 +0200 Qt: Remove unused variable * lang/qt/src/qgpgmerefreshkeysjob.cpp (slotStatus): Remove unused variable typ. diff --git a/lang/qt/src/qgpgmerefreshkeysjob.cpp b/lang/qt/src/qgpgmerefreshkeysjob.cpp index 53a9d2c..3d221f6 100644 --- a/lang/qt/src/qgpgmerefreshkeysjob.cpp +++ b/lang/qt/src/qgpgmerefreshkeysjob.cpp @@ -176,7 +176,7 @@ void QGpgME::QGpgMERefreshKeysJob::slotStatus(QProcess *proc, const QString &typ } const QString what = *++it; ok = false; - const int typ = (*++it).toInt(&ok); + (*++it).toInt(&ok); if (!ok) { qCDebug(GPGPME_BACKEND_LOG) << "expected number for \"type\", got something else"; return; commit a27d7755d071aad42efc2aa4ea3899ba7b17f8bf Author: Andre Heinecke Date: Wed Aug 10 12:05:32 2016 +0200 Qt: Create TestPassphraseProvider on stack * lang/qt/tests/t-encrypt.cpp, lang/qt/tests/t-tofuinfo.cpp: Create TestPassphraseProvider on stack. -- Context does not delete the provider. This fixes ASAN errors. diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp index b0b6994..c6fcaa2 100644 --- a/lang/qt/tests/t-encrypt.cpp +++ b/lang/qt/tests/t-encrypt.cpp @@ -71,7 +71,8 @@ private Q_SLOTS: /* Now decrypt */ auto ctx = Context::createForProtocol(OpenPGP); - ctx->setPassphraseProvider(new TestPassphraseProvider); + TestPassphraseProvider provider; + ctx->setPassphraseProvider(&provider); ctx->setPinentryMode(Context::PinentryLoopback); auto decJob = new QGpgMEDecryptJob(ctx); QByteArray plainText; @@ -84,7 +85,8 @@ private Q_SLOTS: void testSymmetricEncryptDecrypt() { auto ctx = Context::createForProtocol(OpenPGP); - ctx->setPassphraseProvider(new TestPassphraseProvider); + TestPassphraseProvider provider; + ctx->setPassphraseProvider(&provider); ctx->setPinentryMode(Context::PinentryLoopback); ctx->setArmor(true); ctx->setTextMode(true); @@ -99,7 +101,7 @@ private Q_SLOTS: killAgent(mDir.path()); auto ctx2 = Context::createForProtocol(OpenPGP); - ctx2->setPassphraseProvider(new TestPassphraseProvider); + ctx2->setPassphraseProvider(&provider); ctx2->setPinentryMode(Context::PinentryLoopback); auto decJob = new QGpgMEDecryptJob(ctx2); QByteArray plainText; diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index 8331092..3072f0f 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -73,7 +73,8 @@ class TofuInfoTest: public QGpgMETest void signAndVerify(const QString &what, const GpgME::Key &key, int expected) { Context *ctx = Context::createForProtocol(OpenPGP); - ctx->setPassphraseProvider(new TestPassphraseProvider); + TestPassphraseProvider provider; + ctx->setPassphraseProvider(&provider); ctx->setPinentryMode(Context::PinentryLoopback); auto *job = new QGpgMESignJob(ctx); commit 21d5e71d486da8e37cf53f2b968646b39a6daa72 Author: Andre Heinecke Date: Wed Aug 10 12:04:16 2016 +0200 Cpp: Clarify ownership of provider classes * lang/cpp/src/context.h: Note that the context does not take ownership of providers. diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index c7c0ecb..70ab079 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -102,9 +102,23 @@ public: void addKeyListMode(unsigned int keyListMode); unsigned int keyListMode() const; + /** Set the passphrase provider + * + * To avoid problems where a class using a context registers + * itself as the provider the Context does not take ownership + * of the provider and the caller must ensure that the provider + * is deleted if it is no longer needed. + */ void setPassphraseProvider(PassphraseProvider *provider); PassphraseProvider *passphraseProvider() const; + /** Set the progress provider + * + * To avoid problems where a class using a context registers + * itself as the provider the Context does not take ownership + * of the provider and the caller must ensure that the provider + * is deleted if it is no longer needed. + */ void setProgressProvider(ProgressProvider *provider); ProgressProvider *progressProvider() const; ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/context.h | 14 ++++++++++++++ lang/qt/src/qgpgmerefreshkeysjob.cpp | 2 +- lang/qt/tests/t-encrypt.cpp | 8 +++++--- lang/qt/tests/t-tofuinfo.cpp | 3 ++- 4 files changed, 22 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 12:09:52 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 10 Aug 2016 12:09:52 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-64-g194b1e9 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 194b1e979c7c547afd0dfea5b2496bdfa34b20f1 (commit) via d9240a3a4688c263632b4168ae2e04363bc91a3a (commit) via efe973dab7f69e2b1309446b2fbcd47ce0305399 (commit) from e13f1ea8fff3964dc3008432f5c0f26aaa2eaa35 (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 194b1e979c7c547afd0dfea5b2496bdfa34b20f1 Author: Justus Winter Date: Wed Aug 10 11:52:49 2016 +0200 tests: Fix distcheck. * tests/openpgp/Makefile.am (EXTRA_DIST): Explicitly add setup and teardown scripts now that they no longer are included in the list of tests. Signed-off-by: Justus Winter diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index a43f23b..da12cae 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -170,7 +170,8 @@ sample_msgs = samplemsgs/issue2419.asc EXTRA_DIST = defs.inc defs.scm pinentry.sh $(XTESTS) $(TEST_FILES) \ mkdemodirs signdemokey $(priv_keys) $(sample_keys) \ - $(sample_msgs) ChangeLog-2011 run-tests.scm + $(sample_msgs) ChangeLog-2011 run-tests.scm \ + setup.scm finish.scm CLEANFILES = prepared.stamp x y yy z out err $(data_files) \ plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \ commit d9240a3a4688c263632b4168ae2e04363bc91a3a Author: Justus Winter Date: Wed Aug 10 11:54:11 2016 +0200 tests: Improve temporary directory handling. * tests/gpgscm/ffi.c (ffi_init): Rename 'mkdtemp'. * tests/gpgscm/tests.scm (mkdtemp): New function that uses a sensible location and template if no arguments are given. (with-temporary-working-directory): Simplify accordingly. (make-temporary-file): Likewise. * tests/openpgp/run-tests.scm (run-tests-parallel-isolated): Likewise. (run-tests-sequential-isolated): Likewise. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index c37bf1d..57de286 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -1248,7 +1248,7 @@ ffi_init (scheme *sc, const char *argv0, int argc, const char **argv) ffi_define_function (sc, open); ffi_define_function (sc, fdopen); ffi_define_function (sc, close); - ffi_define_function (sc, mkdtemp); + ffi_define_function_name (sc, "_mkdtemp", mkdtemp); ffi_define_function (sc, unlink); ffi_define_function (sc, unlink_recursively); ffi_define_function (sc, rename); diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm index f97b22e..8283eba 100644 --- a/tests/gpgscm/tests.scm +++ b/tests/gpgscm/tests.scm @@ -247,10 +247,19 @@ (chdir ,cwd-sym) ,result-sym))) +;; Make a temporary directory. If arguments are given, they are +;; joined using path-join, and must end in a component ending in +;; "XXXXXX". If no arguments are given, a suitable location and +;; generic name is used. +(define (mkdtemp . components) + (_mkdtemp (if (null? components) + (path-join (getenv "TMP") "gpgscm-XXXXXX") + (apply path-join components)))) + (macro (with-temporary-working-directory form) (let ((result-sym (gensym)) (cwd-sym (gensym)) (tmp-sym (gensym))) `(let* ((,cwd-sym (getcwd)) - (,tmp-sym (mkdtemp (path-join (getenv "TMP") "gpgscm-XXXXXX"))) + (,tmp-sym (mkdtemp)) (_ (chdir ,tmp-sym)) (,result-sym (begin ,@(cdr form)))) (chdir ,cwd-sym) @@ -259,7 +268,7 @@ (define (make-temporary-file . args) (canonical-path (path-join - (mkdtemp (path-join (getenv "TMP") "gpgscm-XXXXXX")) + (mkdtemp) (if (null? args) "a" (car args))))) (define (remove-temporary-file filename) diff --git a/tests/openpgp/run-tests.scm b/tests/openpgp/run-tests.scm index 367c641..e3b6b6a 100644 --- a/tests/openpgp/run-tests.scm +++ b/tests/openpgp/run-tests.scm @@ -128,7 +128,7 @@ (unlink-recursively t::directory) (t::report)) results::procs) (exit (results::report))) - (let* ((wd (mkdtemp "gpgscm-XXXXXX")) + (let* ((wd (mkdtemp)) (test (car tests')) (test' (test::set-directory wd)) (setup' (setup::set-directory wd))) @@ -154,7 +154,7 @@ (unlink-recursively t::directory)) results::procs) (exit (results::report))) - (let* ((wd (mkdtemp "gpgscm-XXXXXX")) + (let* ((wd (mkdtemp)) (test (car tests')) (test' (test::set-directory wd)) (setup' (setup::set-directory wd))) commit efe973dab7f69e2b1309446b2fbcd47ce0305399 Author: Justus Winter Date: Wed Aug 10 11:50:12 2016 +0200 gpgscm: Make the name of foreign functions more unique. * tests/gpgscm/ffi-private.h (ffi_define_function_name): Add another underscore. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/ffi-private.h b/tests/gpgscm/ffi-private.h index 87f491f..0d58c41 100644 --- a/tests/gpgscm/ffi-private.h +++ b/tests/gpgscm/ffi-private.h @@ -93,7 +93,7 @@ pointer ffi_sprintf (scheme *sc, const char *format, ...) #define ffi_define_function_name(SC, NAME, F) \ do { \ - char *_fname = ffi_schemify_name ("_" #F, 0); \ + char *_fname = ffi_schemify_name ("__" #F, 0); \ scheme_define ((SC), \ (SC)->global_env, \ mk_symbol ((SC), _fname), \ ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/ffi-private.h | 2 +- tests/gpgscm/ffi.c | 2 +- tests/gpgscm/tests.scm | 13 +++++++++++-- tests/openpgp/Makefile.am | 3 ++- tests/openpgp/run-tests.scm | 4 ++-- 5 files changed, 17 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 14:15:29 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 10 Aug 2016 14:15:29 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-274-g09667a6 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 09667a6006986a782af98ca1de4d6521e1b8f353 (commit) via b602d8bc7bd726afb52dc60cc07e4609e88d4511 (commit) from d467018ce36f5be36751267c3b6079e8c1ee5d8a (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 09667a6006986a782af98ca1de4d6521e1b8f353 Author: Andre Heinecke Date: Wed Aug 10 14:12:33 2016 +0200 Cpp: Handle empty recipients consistently * lang/cpp/src/context.cpp (Context::getKeysFromRecipients): New helper. (Context::encrypt, Context::startEncryption, Context::signAndEncrypt) (Context::startCombinedSigningAndEncryption): Use new helper. * lang/cpp/src/context.h (Context::getKeysFromRecipients): Add as private helper. -- bf776ce was incomplete as the code to handle recpients was duplicated four times. This is now unified and constently uses a nullptr instead of an empty array. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index d63573f..1a2741e 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1109,26 +1109,36 @@ static gpgme_encrypt_flags_t encryptflags2encryptflags(Context::EncryptionFlags return static_cast(result); } -EncryptionResult Context::encrypt(const std::vector &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags) +gpgme_key_t *const Context::getKeysFromRecipients(const std::vector &recipients) { - d->lastop = Private::Encrypt; - if (flags & NoEncryptTo) { - return EncryptionResult(Error(d->lasterr = make_error(GPG_ERR_NOT_IMPLEMENTED))); + if (recipients.empty()) { + return nullptr; } - const Data::Private *const pdp = plainText.impl(); - Data::Private *const cdp = cipherText.impl(); - gpgme_key_t *const keys = new gpgme_key_t[ recipients.size() + 1 ]; - gpgme_key_t *keys_it = keys; + gpgme_key_t *ret = new gpgme_key_t[ recipients.size() + 1 ]; + gpgme_key_t *keys_it = ret; for (std::vector::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it) { if (it->impl()) { *keys_it++ = it->impl(); } } *keys_it++ = 0; - d->lasterr = gpgme_op_encrypt(d->ctx, recipients.empty() ? nullptr : keys, - encryptflags2encryptflags(flags), + return ret; +} + +EncryptionResult Context::encrypt(const std::vector &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags) +{ + d->lastop = Private::Encrypt; + if (flags & NoEncryptTo) { + return EncryptionResult(Error(d->lasterr = make_error(GPG_ERR_NOT_IMPLEMENTED))); + } + const Data::Private *const pdp = plainText.impl(); + Data::Private *const cdp = cipherText.impl(); + gpgme_key_t *const keys = getKeysFromRecipients(recipients); + d->lasterr = gpgme_op_encrypt(d->ctx, keys, encryptflags2encryptflags(flags), pdp ? pdp->data : 0, cdp ? cdp->data : 0); - delete[] keys; + if (keys) { + delete[] keys; + } return EncryptionResult(d->ctx, Error(d->lasterr)); } @@ -1149,17 +1159,12 @@ Error Context::startEncryption(const std::vector &recipients, const Data &p } const Data::Private *const pdp = plainText.impl(); Data::Private *const cdp = cipherText.impl(); - gpgme_key_t *const keys = new gpgme_key_t[ recipients.size() + 1 ]; - gpgme_key_t *keys_it = keys; - for (std::vector::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it) { - if (it->impl()) { - *keys_it++ = it->impl(); - } - } - *keys_it++ = 0; + gpgme_key_t *const keys = getKeysFromRecipients(recipients); d->lasterr = gpgme_op_encrypt_start(d->ctx, keys, encryptflags2encryptflags(flags), pdp ? pdp->data : 0, cdp ? cdp->data : 0); - delete[] keys; + if (keys) { + delete[] keys; + } return Error(d->lasterr); } @@ -1177,17 +1182,12 @@ std::pair Context::signAndEncrypt(const std::ve d->lastop = Private::SignAndEncrypt; const Data::Private *const pdp = plainText.impl(); Data::Private *const cdp = cipherText.impl(); - gpgme_key_t *const keys = new gpgme_key_t[ recipients.size() + 1 ]; - gpgme_key_t *keys_it = keys; - for (std::vector::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it) { - if (it->impl()) { - *keys_it++ = it->impl(); - } - } - *keys_it++ = 0; + gpgme_key_t *const keys = getKeysFromRecipients(recipients); d->lasterr = gpgme_op_encrypt_sign(d->ctx, keys, encryptflags2encryptflags(flags), pdp ? pdp->data : 0, cdp ? cdp->data : 0); - delete[] keys; + if (keys) { + delete[] keys; + } return std::make_pair(SigningResult(d->ctx, Error(d->lasterr)), EncryptionResult(d->ctx, Error(d->lasterr))); } @@ -1197,17 +1197,12 @@ Error Context::startCombinedSigningAndEncryption(const std::vector &recipie d->lastop = Private::SignAndEncrypt; const Data::Private *const pdp = plainText.impl(); Data::Private *const cdp = cipherText.impl(); - gpgme_key_t *const keys = new gpgme_key_t[ recipients.size() + 1 ]; - gpgme_key_t *keys_it = keys; - for (std::vector::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it) { - if (it->impl()) { - *keys_it++ = it->impl(); - } - } - *keys_it++ = 0; + gpgme_key_t *const keys = getKeysFromRecipients(recipients); d->lasterr = gpgme_op_encrypt_sign_start(d->ctx, keys, encryptflags2encryptflags(flags), pdp ? pdp->data : 0, cdp ? cdp->data : 0); - delete[] keys; + if (keys) { + delete[] keys; + } return Error(d->lasterr); } diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 70ab079..7d7f53a 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -369,6 +369,11 @@ public: return d; } private: + // Helper functions that need to be context because they rely + // on the "Friendlyness" of context to access the gpgme types. + gpgme_key_t *const getKeysFromRecipients(const std::vector &recipients); + +private: Private *const d; private: // disable... commit b602d8bc7bd726afb52dc60cc07e4609e88d4511 Author: Andre Heinecke Date: Wed Aug 10 14:01:38 2016 +0200 core: Handle ENCRYPT_SYMMETRIC also for sig & enc * src/engine-gpg.c (gpg_encrypt_sign): Handle ENCRYPT_SYMMETRIC flag. diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 4fad977..efab80a 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1782,10 +1782,13 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], gpgme_ctx_t ctx /* FIXME */) { engine_gpg_t gpg = engine; - gpgme_error_t err; - int symmetric = !recp; + gpgme_error_t err = 0; + + if (recp) + err = add_arg (gpg, "--encrypt"); - err = add_arg (gpg, symmetric ? "--symmetric" : "--encrypt"); + if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp)) + err = add_arg (gpg, "--symmetric"); if (!err) err = add_arg (gpg, "--sign"); @@ -1799,7 +1802,7 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], && have_gpg_version (gpg, "2.1.14")) err = add_arg (gpg, "--mimemode"); - if (!symmetric) + if (recp) { /* If we know that all recipients are valid (full or ultimate trust) we can suppress further checks. */ ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/context.cpp | 71 ++++++++++++++++++++++-------------------------- lang/cpp/src/context.h | 5 ++++ src/engine-gpg.c | 11 +++++--- 3 files changed, 45 insertions(+), 42 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 15:38:29 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 10 Aug 2016 15:38:29 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-275-ga916818 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 a9168185ba97aa1d827315cd8017899bf904aded (commit) from 09667a6006986a782af98ca1de4d6521e1b8f353 (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 a9168185ba97aa1d827315cd8017899bf904aded Author: Werner Koch Date: Wed Aug 10 15:31:25 2016 +0200 core: Do not identify PNG files as PGP signatures. * src/data-identify.c (next_openpgp_packet): Blacklist PNG files. -- GnuPG-bug-id: 2314 Signed-off-by: Werner Koch diff --git a/src/data-identify.c b/src/data-identify.c index 88a472f..1edfb9b 100644 --- a/src/data-identify.c +++ b/src/data-identify.c @@ -95,6 +95,11 @@ next_openpgp_packet (unsigned char const **bufptr, size_t *buflen, if (!len) return gpg_error (GPG_ERR_NO_DATA); + /* First some blacklisting. */ + if (len >= 4 && !memcmp (buf, "\x89PNG", 4)) + return gpg_error (GPG_ERR_INV_PACKET); /* This is a PNG file. */ + + /* Start parsing. */ ctb = *buf++; len--; if ( !(ctb & 0x80) ) return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */ ----------------------------------------------------------------------- Summary of changes: src/data-identify.c | 5 +++++ 1 file changed, 5 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 16:35:49 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 10 Aug 2016 16:35:49 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-277-gb7d99e0 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 b7d99e02188b7907b09fec3032fc1fd82fc2668a (commit) via 48691db97b759d67aa7b49c36bb704b5806ade2e (commit) from a9168185ba97aa1d827315cd8017899bf904aded (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 b7d99e02188b7907b09fec3032fc1fd82fc2668a Author: Werner Koch Date: Wed Aug 10 16:33:20 2016 +0200 doc: Get rid of version.texi * configure.ac (CC_FOR_BUILD): New. * doc/mkdefsinc.c: New. Taken from GnuPG and modified for gpgme. * doc/Makefile.am (EXTRA_DIST): Add defsincdate and mkdefsinc.c (BUILT_SOURCES): new. (gpgme.texi): New dependency. (mkdefsinc, defsincdate, defs.inc): New rules. (dist-hook): New. * doc/gpgme.texi: Include defs.inc. Remove version.texi. -- GnuPG-bug-id: 2352 That new system should also yield more approriate date infos for the manual. diff --git a/configure.ac b/configure.ac index 105f80e..9eb55bb 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,22 @@ VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_version_major \ mym4_version_minor mym4_version_micro) AC_SUBST(VERSION_NUMBER) +# We need to compile and run a program on the build machine. A +# comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in +# the AC archive is broken for autoconf 2.57. Given that there is no +# newer version of that macro, we assume that it is also broken for +# autoconf 2.61 and thus we use a simple but usually sufficient +# approach. +AC_MSG_CHECKING(for cc for build) +if test "$cross_compiling" = "yes"; then + CC_FOR_BUILD="${CC_FOR_BUILD-cc}" +else + CC_FOR_BUILD="${CC_FOR_BUILD-$CC}" +fi +AC_MSG_RESULT($CC_FOR_BUILD) +AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) + + # Don't default to build static libs. LT_PREREQ([2.2.6]) LT_INIT([win32-dll disable-static]) diff --git a/doc/Makefile.am b/doc/Makefile.am index 2df35b4..905f953 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -20,12 +20,38 @@ ## Process this file with automake to produce Makefile.in DISTCLEANFILES = gpgme.tmp +CLEANFILES = mkdefsinc defs.inc + +EXTRA_DIST = module-overview.sk HACKING DCO ChangeLog-2011 \ + mkdefsinc.c defsincdate + +BUILT_SOURCES = defsincdate defs.inc -EXTRA_DIST = module-overview.sk HACKING DCO ChangeLog-2011 info_TEXINFOS = gpgme.texi gpgme_TEXINFOS = uiserver.texi lesser.texi gpl.texi +gpgme.texi : defs.inc + +mkdefsinc: mkdefsinc.c Makefile ../config.h + $(CC_FOR_BUILD) -I. -I.. -I$(srcdir) $(AM_CPPFLAGS) \ + -o $@ $(srcdir)/mkdefsinc.c + +dist-hook: defsincdate + +defsincdate: $(gpgme_TEXINFOS) + : >defsincdate ; \ + if test -e $(top_srcdir)/.git; then \ + (cd $(srcdir) && git log -1 --format='%ct' -- \ + $(info_TEXINFOS) $(gpgme_TEXINFOS) 2>/dev/null) >>defsincdate; \ + fi + +defs.inc: defsincdate Makefile mkdefsinc + incd="`test -f defsincdate || echo '$(srcdir)/'`defsincdate"; \ + ./mkdefsinc -C $(srcdir) --date "`cat $$incd 2>/dev/null`" \ + $(info_TEXINFOS) $(gpgme_TEXINFOS) >$@ + + online: gpgme.html gpgme.pdf set -e; \ echo "Uploading current manuals to www.gnupg.org ..."; \ diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 907099a..2bbed28 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -1,6 +1,7 @@ \input texinfo @c -*- mode: texinfo; coding: utf-8; -*- @documentencoding UTF-8 @setfilename gpgme.info + at include defs.inc @settitle The `GnuPG Made Easy' Reference Manual @dircategory GNU Libraries @@ -30,8 +31,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @end copying - at include version.texi - @c Macros used by the description of the UI server protocol @macro clnt @sc{c:} @c diff --git a/doc/mkdefsinc.c b/doc/mkdefsinc.c new file mode 100644 index 0000000..0f30d93 --- /dev/null +++ b/doc/mkdefsinc.c @@ -0,0 +1,310 @@ +/* mkdefsinc.c - Tool to create defs.inc + * Copyright (C) 2015 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* This tool needs to be build with command line supplied -D options + for the various directory variables. It is easier to do this in + build file than to use fragile make rules and a template file. */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PGM "mkdefsinc" + +/* We include config.h after all include files because the config.h + values are not valid for the build platform but we need some values + nevertheless. */ +#include "config.h" + + +static int verbose; + + +/* The usual free wrapper. */ +static void +xfree (void *a) +{ + if (a) + free (a); +} + + +static char * +xmalloc (size_t n) +{ + char *p; + + p = malloc (n); + if (!p) + { + fputs (PGM ": out of core\n", stderr); + exit (1); + } + return p; +} + + +static char * +xstrdup (const char *string) +{ + char *p; + + p = xmalloc (strlen (string)+1); + strcpy (p, string); + return p; +} + + +/* Return a malloced string with the last modification date of the + FILES. Returns NULL on error. */ +static char * +get_date_from_files (char **files) +{ + const char *file; + const char *usedfile = NULL; + struct stat sb; + struct tm *tp; + int errors = 0; + time_t stamp = 0; + char *result; + + for (; (file = *files); files++) + { + if (!*file || !strcmp (file, ".") || !strcmp (file, "..")) + continue; + if (stat (file, &sb)) + { + fprintf (stderr, PGM ": stat failed for '%s': %s\n", + file, strerror (errno)); + errors = 1; + continue; + } + if (sb.st_mtime > stamp) + { + stamp = sb.st_mtime; + usedfile = file; + } + } + if (errors) + exit (1); + + if (usedfile) + fprintf (stderr, PGM ": taking date from '%s'\n", usedfile); + + tp = gmtime (&stamp); + if (!tp) + return NULL; + result = xmalloc (4+1+2+1+2+1); + snprintf (result, 4+1+2+1+2+1, "%04d-%02d-%02d", + tp->tm_year + 1900, tp->tm_mon+1, tp->tm_mday); + return result; +} + + +/* We need to escape file names for Texinfo. */ +static void +print_filename (const char *prefix, const char *name) +{ + const char *s; + + fputs (prefix, stdout); + for (s=name; *s; s++) + switch (*s) + { + case '@': fputs ("@atchar{}", stdout); break; + case '{': fputs ("@lbracechar{}", stdout); break; + case '}': fputs ("@rbracechar{}", stdout); break; + case ',': fputs ("@comma{}", stdout); break; + case '\\':fputs ("@backslashchar{}", stdout); break; + case '#': fputs ("@hashchar{}", stdout); break; + default: putchar (*s); break; + } + putchar('\n'); +} + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + char *opt_date = NULL; + int monthoff; + char *p, *pend; + size_t n; + + /* Option parsing. */ + if (argc) + { + argc--; argv++; + } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + fputs ("Usage: " PGM " [OPTION] [FILES]\n" + "Create defs.inc file.\nOptions:\n" + " -C DIR Change to DIR before doing anything\n" + " --date STRING Take publication date from STRING\n" + " --verbose Enable extra informational output\n" + " --help Display this help and exit\n" + , stdout); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "-C")) + { + argc--; argv++; + if (argc) + { + if (chdir (*argv)) + { + fprintf (stderr, PGM ": chdir to '%s' failed: %s\n", + *argv, strerror (errno)); + exit (1); + } + argc--; argv++; + } + } + else if (!strcmp (*argv, "--date")) + { + argc--; argv++; + if (argc) + { + opt_date = xstrdup (*argv); + argc--; argv++; + } + } + else if (!strncmp (*argv, "--", 2)) + { + fprintf (stderr, PGM ": unknown option '%s'\n", *argv); + exit (1); + } + } + + if (opt_date && *opt_date) + { + time_t stamp; + struct tm *tp; + + if (*opt_date == '2' && strlen (opt_date) >= 10 + && opt_date[4] == '-' && opt_date[7] == '-') + { + opt_date[10] = 0; + } + else if ((stamp = strtoul (opt_date, NULL, 10)) > 0 + && (tp = gmtime (&stamp))) + { + p = xmalloc (4+1+2+1+2+1); + snprintf (p, 4+1+2+1+2+1, "%04d-%02d-%02d", + tp->tm_year + 1900, tp->tm_mon+1, tp->tm_mday); + xfree (opt_date); + opt_date = p; + } + else + { + fprintf (stderr, PGM ": bad date '%s'\n", opt_date); + exit (1); + } + } + else + { + xfree (opt_date); + opt_date = argc? get_date_from_files (argv) : NULL; + } + if (!opt_date) + { + opt_date = xstrdup ("unknown"); + monthoff = 0; + } + else + { + const char *month = "?"; + + switch (atoi (opt_date+5)) + { + case 1: month = "January"; break; + case 2: month = "February"; break; + case 3: month = "March"; break; + case 4: month = "April"; break; + case 5: month = "May"; break; + case 6: month = "June"; break; + case 7: month = "July"; break; + case 8: month = "August"; break; + case 9: month = "September"; break; + case 10: month = "October"; break; + case 11: month = "November"; break; + case 12: month = "December"; break; + } + n = strlen (opt_date) + strlen (month) + 2 + 1; + p = xmalloc (n); + snprintf (p, n, "%d %n%s %d", + atoi (opt_date+8), &monthoff, month, atoi (opt_date)); + xfree (opt_date); + opt_date = p; + } + + + fputs ("@c defs.inc -*- texinfo -*-\n" + "@c Common and build specific constants for the manuals.\n" + "@c This file has been created by " PGM ".\n\n", stdout); + + fputs ("@ifclear defsincincluded\n" + "@set defsincincluded 1\n\n", stdout); + + + fputs ("\n at c Flags\n\n", stdout); + + fputs ("\n at c Directories\n\n", stdout); + + /* print_filename ("@set BINDIR ", GNUPG_BINDIR ); */ + + fputs ("\n at c Version information a la version.texi\n\n", stdout); + + printf ("@set UPDATED %s\n", opt_date); + printf ("@set UPDATED-MONTH %s\n", opt_date + monthoff); + printf ("@set EDITION %s\n", PACKAGE_VERSION); + printf ("@set VERSION %s\n", PACKAGE_VERSION); + + fputs ("\n at c Macros\n\n", stdout); + + /* Trailer. */ + fputs ("\n" + "@end ifclear\n" + "\n" + "@c Loc" "al Variables:\n" + "@c buffer-read-only: t\n" + "@c End:\n", stdout); + + if (ferror (stdout)) + { + fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno)); + return 1; + } + + return 0; +} commit 48691db97b759d67aa7b49c36bb704b5806ade2e Author: Werner Koch Date: Wed Aug 10 16:28:36 2016 +0200 build: Declare all languages for make dist. * lang/Makefile.am (DIST_SUBDIRS): New. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 6a7df24..105f80e 100644 --- a/configure.ac +++ b/configure.ac @@ -249,6 +249,9 @@ if test x$fixed_search_path != x ; then [Locate binaries only via this PATH]) fi + +# Note: You need to declare all possible langauges also in +# lang/Makefile.am's DIST_SUBDIRS. AC_ARG_ENABLE([languages], AC_HELP_STRING([--enable-languages=languages], [enable only specific language bindings]), diff --git a/lang/Makefile.am b/lang/Makefile.am index bb75cf0..fd3ce4e 100644 --- a/lang/Makefile.am +++ b/lang/Makefile.am @@ -18,5 +18,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA SUBDIRS = $(ENABLED_LANGUAGES) +DIST_SUBDIRS = cl cpp qt python EXTRA_DIST = README ----------------------------------------------------------------------- Summary of changes: configure.ac | 19 ++++ doc/Makefile.am | 28 ++++- doc/gpgme.texi | 3 +- doc/mkdefsinc.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lang/Makefile.am | 1 + 5 files changed, 358 insertions(+), 3 deletions(-) create mode 100644 doc/mkdefsinc.c hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 16:51:35 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 10 Aug 2016 16:51:35 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-65-ga27410a 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 a27410a251cd25ca96cd6743969c4db0a0fd553f (commit) from 194b1e979c7c547afd0dfea5b2496bdfa34b20f1 (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 a27410a251cd25ca96cd6743969c4db0a0fd553f Author: Justus Winter Date: Wed Aug 10 16:41:22 2016 +0200 g10: Fix opening of trust database. * g10/tdbio.c (tdbio_set_dbname): This function explicitly checks for the file size, but handled the case of a zero-sized file incorrectly by returning success. Fix this by initializing the database in that case. * tests/openpgp/Makefile.am (XTESTS): Add new test. * tests/openpgp/issue2417.scm: New file. GnuPG-bug-id: 2417 Signed-off-by: Justus Winter diff --git a/g10/tdbio.c b/g10/tdbio.c index e27788e..02fa91e 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -685,7 +685,7 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) take_write_lock (); - if (access (fname, R_OK)) + if (access (fname, R_OK) || stat (fname, &statbuf) || statbuf.st_size == 0) { FILE *fp; TRUSTREC rec; @@ -699,7 +699,7 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) else gpg_err_set_errno (EIO); #endif /*HAVE_W32CE_SYSTEM*/ - if (errno != ENOENT) + if (errno && errno != ENOENT) log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno)); oldmask = umask (077); diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index da12cae..5d8acbf 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -84,6 +84,7 @@ XTESTS = \ ssh.scm \ issue2015.scm \ issue2346.scm \ + issue2417.scm \ issue2419.scm # XXX: Currently, one cannot override automake's 'check' target. As a diff --git a/tests/openpgp/issue2417.scm b/tests/openpgp/issue2417.scm new file mode 100755 index 0000000..32840f2 --- /dev/null +++ b/tests/openpgp/issue2417.scm @@ -0,0 +1,39 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see . + +(load (with-path "defs.scm")) + +(define (touch file-name) + (close (open file-name (logior O_WRONLY O_BINARY O_CREAT) #o600))) + +(info "Checking robustness wrt empty databases in gnupghome (issue2417)...") + +(lettmp + ;; Prepare some random key to import later. + (keyfile) + (pipe:do + (pipe:gpg '(--export alpha)) + (pipe:write-to keyfile (logior O_WRONLY O_BINARY O_CREAT) #o600)) + + (with-temporary-working-directory + (setenv "GNUPGHOME" "." #t) + (touch "trustdb.gpg") + (touch "pubring.gpg") + (touch "pubring.kbx") + (call-check `(,(tool 'GPG) --import ,keyfile)))) ----------------------------------------------------------------------- Summary of changes: g10/tdbio.c | 4 ++-- tests/openpgp/Makefile.am | 1 + tests/openpgp/{issue2419.scm => issue2417.scm} | 23 +++++++++++++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) copy tests/openpgp/{issue2419.scm => issue2417.scm} (59%) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 17:01:39 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 10 Aug 2016 17:01:39 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-66-g5b59999 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 5b59999ce0dd1650ebe47a74a30ded6af00eeed3 (commit) from a27410a251cd25ca96cd6743969c4db0a0fd553f (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 5b59999ce0dd1650ebe47a74a30ded6af00eeed3 Author: Werner Koch Date: Fri Aug 5 14:40:36 2016 +0200 gpg: Remove tofu database format "split". * g10/options.h (struct opt): Remove field tofu_db_format. * g10/gpg.h (server_control_s): Add fields tofu.batch_update_ref and tofu.batch_update_started. * g10/gpg.c (parse_tofu_db_format): Remove. (main): Make option --tofu-db-format obsolete. * g10/tofu.c: Major rework. Remove the pretty complicated and slower split format and with that all the caching. Use the dbs struct directly. Move global vars for batch update into CTRL. Change calling conventions of some function to take CTRL or DBS pointers instead of the former low-level database pointer. -- The split database format might have been nice for use with Unison but it bypasses the concept of a relational database by doing parts of this itself and also risking deadlocks. Working with the Tofu database for debugging or experiments is also not possible with parts of the database logic implemented in gpg. The Tofu support is quite new and we can assume that it is not in real use now. Thus we better remove that now so that we do not need to maintain it for all future. Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 0139fdb..794026b 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1144,6 +1144,55 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: stored in the version info record. +* Database scheme for the TOFU info + +#+begin_src sql +-- +-- The VERSION table holds the version of our TOFU data structures. +-- +CREATE TABLE version ( + version integer -- As of now this is always 1 +); + +-- +-- The BINDINGS table associates mail addresses with keys. +-- +CREATE TABLE bindings ( + oid integer primary key autoincrement, + fingerprint text, -- The key's fingerprint in hex + email text, -- The normalized mail address destilled from user_id + user_id text, -- The unmodified user id + time integer, -- The time this binding was first observed. + policy boolean check + (policy in (1, 2, 3, 4, 5)), -- The trust policy with the values: + -- 1 := Auto + -- 2 := Good + -- 3 := Unknown + -- 4 := Bad + -- 5 := Ask + conflict string, -- NULL or a hex formatted fingerprint. + unique (fingerprint, email) +); + +CREATE INDEX bindings_fingerprint_email on bindings (fingerprint, email); +CREATE INDEX bindings_email on bindings (email); + +-- +-- The SIGNATURES table records all data signatures we verified +-- +CREATE TABLE signatures ( + binding integer not null, -- Link to bindings table, + -- references bindings.oid. + sig_digest text, -- The digest of the signed message. + origin text, -- String describing who initially fed + -- the signature to gpg (e.g. "email:claws"). + sig_time integer, -- Timestamp from the signature. + time integer, -- Time this record was created. + primary key (binding, sig_digest, origin) +); +#+end_src + + * GNU extensions to the S2K algorithm 1 octet - S2K Usage: either 254 or 255. @@ -1169,6 +1218,9 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: * Keyserver helper message format + *This information is obsolete* + (Keyserver helpers have been replaced by dirmngr) + The keyserver may be contacted by a Unix Domain socket or via TCP. The format of a request is: diff --git a/doc/gpg.texi b/doc/gpg.texi index ffbc269..944734b 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1840,25 +1840,6 @@ key signer (defaults to 3) The default TOFU policy (defaults to @code{auto}). For more information about the meaning of this option, @xref{trust-model-tofu}. - at item --tofu-db-format @code{auto|split|flat} - at opindex tofu-default-policy -The format for the TOFU DB. - -The split file format splits the data across many DBs under the - at code{tofu.d} directory (one per email address and one per key). This -makes it easier to automatically synchronize the data using a tool -such as Unison (@url{https://www.cis.upenn.edu/~bcpierce/unison/}), -since the individual files change rarely. - -The flat file format keeps all of the data in the single file - at code{tofu.db}. This format results in better performance. - -If set to auto (which is the default), GnuPG will first check for the -existence of @code{tofu.d} and @code{tofu.db}. If one of these -exists, the corresponding format is used. If neither or both of these -exist, then GnuPG defaults to the @code{split} format. In the latter -case, a warning is emitted. - @item --max-cert-depth @code{n} @opindex max-cert-depth Maximum depth of a certification chain (default is 5). diff --git a/g10/gpg.c b/g10/gpg.c index 91f3472..adc32f0 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -709,7 +709,6 @@ static ARGPARSE_OPTS opts[] = { #endif ARGPARSE_s_s (oTrustModel, "trust-model", "@"), ARGPARSE_s_s (oTOFUDefaultPolicy, "tofu-default-policy", "@"), - ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"), ARGPARSE_s_s (oSetFilename, "set-filename", "@"), ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"), ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"), @@ -851,6 +850,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (opcscDriver, "pcsc-driver", "@"), ARGPARSE_s_n (oDisableCCID, "disable-ccid", "@"), ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"), + ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"), /* Dummy options. */ ARGPARSE_s_n (oNoop, "sk-comments", "@"), @@ -2020,32 +2020,6 @@ parse_tofu_policy (const char *policystr) g10_exit (1); } -static int -parse_tofu_db_format (const char *db_format) -{ -#ifdef USE_TOFU - if (ascii_strcasecmp (db_format, "auto") == 0) - return TOFU_DB_AUTO; - else if (ascii_strcasecmp (db_format, "split") == 0) - return TOFU_DB_SPLIT; - else if (ascii_strcasecmp (db_format, "flat") == 0) - return TOFU_DB_FLAT; - else if (ascii_strcasecmp (db_format, "help") == 0) - { - log_info ("available TOFU DB fomats: auto, split, flat\n"); - g10_exit (1); - } - else -#endif /*USE_TOFU*/ - { - log_error (_("unknown TOFU DB format '%s'\n"), db_format); - if (!opt.quiet) - log_info (_("(use \"help\" to list choices)\n")); - g10_exit (1); - } -} - - /* This function called to initialized a new control object. It is assumed that this object has been zeroed out before calling this function. */ @@ -2252,7 +2226,6 @@ main (int argc, char **argv) opt.trust_model = TM_AUTO; #endif opt.tofu_default_policy = TOFU_POLICY_AUTO; - opt.tofu_db_format = TOFU_DB_AUTO; opt.mangle_dos_filenames = 0; opt.min_cert_level = 2; set_screen_dimensions (); @@ -2692,7 +2665,7 @@ main (int argc, char **argv) opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str); break; case oTOFUDBFormat: - opt.tofu_db_format = parse_tofu_db_format (pargs.r.ret_str); + obsolete_option (configname, configlineno, "tofu-db-format"); break; case oForceOwnertrust: diff --git a/g10/gpg.h b/g10/gpg.h index c0f0a2d..1aaff2f 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -82,6 +82,8 @@ struct server_control_s /* Local data for tofu.c */ struct { tofu_dbs_t dbs; + int batch_update_ref; + time_t batch_update_started; } tofu; }; diff --git a/g10/gpgv.c b/g10/gpgv.c index 729fcf8..fd1090e 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -680,11 +680,13 @@ tofu_policy_str (enum tofu_policy policy) } void -tofu_begin_batch_update (void) +tofu_begin_batch_update (ctrl_t ctrl) { + (void)ctrl; } void -tofu_end_batch_update (void) +tofu_end_batch_update (ctrl_t ctrl) { + (void)ctrl; } diff --git a/g10/keylist.c b/g10/keylist.c index 60b8f23..59344b2 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -134,7 +134,7 @@ public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode) check_trustdb_stale (ctrl); #ifdef USE_TOFU - tofu_begin_batch_update (); + tofu_begin_batch_update (ctrl); #endif if (locate_mode) @@ -145,7 +145,7 @@ public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode) list_one (ctrl, list, 0, opt.with_secret); #ifdef USE_TOFU - tofu_end_batch_update (); + tofu_end_batch_update (ctrl); #endif } diff --git a/g10/options.h b/g10/options.h index ccd8acb..d1c3634 100644 --- a/g10/options.h +++ b/g10/options.h @@ -116,17 +116,13 @@ struct int skip_verify; int skip_hidden_recipients; - /* TM_CLASSIC must be zero to accommodate trustdbs generated before + /* TM_CLASSIC must be zero to accommodate trustdbsg generated before we started storing the trust model inside the trustdb. */ enum { TM_CLASSIC=0, TM_PGP=1, TM_EXTERNAL=2, TM_ALWAYS, TM_DIRECT, TM_AUTO, TM_TOFU, TM_TOFU_PGP } trust_model; - enum - { - TOFU_DB_AUTO=0, TOFU_DB_SPLIT, TOFU_DB_FLAT - } tofu_db_format; enum tofu_policy tofu_default_policy; int force_ownertrust; enum diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 6cf43a3..c5f2f79 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -493,11 +493,13 @@ tofu_policy_str (enum tofu_policy policy) } void -tofu_begin_batch_update (void) +tofu_begin_batch_update (ctrl_t ctrl) { + (void)ctrl; } void -tofu_end_batch_update (void) +tofu_end_batch_update (ctrl_t ctrl) { + (void)ctrl; } diff --git a/g10/tofu.c b/g10/tofu.c index a2732ff..ef14e85 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -55,46 +55,14 @@ #define FULL_TRUST_THRESHOLD 100 -#define DEBUG_TOFU_CACHE 0 -#if DEBUG_TOFU_CACHE -static int prepares_saved; -static int queries; -#endif - -/* The TOFU data can be saved in two different formats: either in a - single combined database (opt.tofu_db_format == TOFU_DB_FLAT) or in - a split file format (opt.tofu_db_format == TOFU_DB_SPLIT). In the - split format, there is one database per normalized email address - (DB_EMAIL) and one per key (DB_KEY). */ -enum db_type - { - DB_COMBINED, - DB_EMAIL, - DB_KEY - }; - -/* A list of open DBs. - - In the flat format, this consists of a single element with the type - DB_COMBINED and whose name is the empty string. - - In the split format, the first element is a dummy element (DB is - NULL) whose type is DB_COMBINED and whose name is the empty string. - Any following elements describe either DB_EMAIL or DB_KEY DBs. In - theis case, NAME is either the normalized email address or the - fingerprint. +/* An struct with data pertaining to the tofu DB. To initialize this data structure, call opendbs(). Cleanup is done when the CTRL object is released. To get a handle to a database, use the getdb() function. This will either return an existing handle or open a new DB connection, as appropriate. */ -struct db +struct tofu_dbs_s { - struct db *next; - struct db **prevp; - - enum db_type type; - sqlite3 *db; struct @@ -116,34 +84,9 @@ struct db sqlite3_stmt *register_insert; } s; -#if DEBUG_TOFU_CACHE - int hits; -#endif - int batch_update; - - /* If TYPE is DB_COMBINED, this is "". Otherwise, it is either the - fingerprint (type == DB_KEY) or the normalized email address - (type == DB_EMAIL). */ - char name[1]; }; -static struct db *db_cache; -static int db_cache_count; -#define DB_CACHE_ENTRIES 16 - -static void tofu_cache_dump (struct db *db) GPGRT_ATTR_USED; - -static void -tofu_cache_dump (struct db *db) -{ - log_info ("Connection %p:\n", db); - for (; db; db = db->next) - log_info (" %s: %sbatch mode\n", db->name, db->batch_update ? "" : "NOT "); - log_info ("Cache:\n"); - for (db = db_cache; db; db = db->next) - log_info (" %s: %sbatch mode\n", db->name, db->batch_update ? "" : "NOT "); -} #define STRINGIFY(s) STRINGIFY2(s) #define STRINGIFY2(s) #s @@ -167,8 +110,11 @@ tofu_cache_dump (struct db *db) # define TIME_AGO_UNIT_LARGE (30 * 24 * 60 * 60) #endif - +/* Local prototypes. */ +static gpg_error_t end_transaction (ctrl_t ctrl, int only_batch); + + const char * tofu_policy_str (enum tofu_policy policy) { @@ -213,83 +159,63 @@ tofu_policy_to_trust_level (enum tofu_policy policy) return 0; } } - -static int batch_update; -static time_t batch_update_started; -static gpg_error_t end_transaction (struct db *db, int only_batch); + /* Start a transaction on DB. */ static gpg_error_t -begin_transaction (struct db *db, int only_batch) +begin_transaction (ctrl_t ctrl, int only_batch) { + tofu_dbs_t dbs = ctrl->tofu.dbs; int rc; char *err = NULL; - if (batch_update && batch_update_started != gnupg_get_time ()) - /* We've been in batch update mode for a while (on average, more - than 500 ms). To prevent starving other gpg processes, we drop - and retake the batch lock. + log_assert (dbs); - Note: if we wanted higher resolution, we could use - npth_clock_gettime. */ + if (ctrl->tofu.batch_update_ref + && ctrl->tofu.batch_update_started != gnupg_get_time ()) { - struct db *t; - - for (t = db_cache; t; t = t->next) - if (t->batch_update) - end_transaction (t, 1); - for (t = db; t; t = t->next) - if (t->batch_update) - end_transaction (t, 1); + /* We've been in batch update mode for a while (on average, more + * than 500 ms). To prevent starving other gpg processes, we + * drop and retake the batch lock. + * + * Note: if we wanted higher resolution, we could use + * npth_clock_gettime. */ + if (dbs->batch_update) + end_transaction (ctrl, 1); - batch_update_started = gnupg_get_time (); + ctrl->tofu.batch_update_started = gnupg_get_time (); /* Yield to allow another process a chance to run. */ gpgrt_yield (); } - /* XXX: In split mode, this can end in deadlock. - - Consider: we have two gpg processes running simultaneously and - they each want to lock DB A and B, but in different orders. This - will be automatically resolved by causing one of them to return - EBUSY and aborting. - - A more intelligent approach would be to commit and retake the - batch transaction. This requires a list of all DBs that are - currently in batch mode. */ - - if (batch_update && ! db->batch_update) + if (ctrl->tofu.batch_update_ref && !dbs->batch_update) { - rc = gpgsql_stepx (db->db, &db->s.savepoint_batch, + rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch, NULL, NULL, &err, "savepoint batch;", SQLITE_ARG_END); if (rc) { log_error (_("error beginning transaction on TOFU database: %s\n"), err); - print_further_info ("batch, database '%s'", - *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } - db->batch_update = 1; + dbs->batch_update = 1; } if (only_batch) return 0; - rc = gpgsql_stepx (db->db, &db->s.savepoint_inner, + rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_inner, NULL, NULL, &err, "savepoint inner;", SQLITE_ARG_END); if (rc) { log_error (_("error beginning transaction on TOFU database: %s\n"), err); - print_further_info ("inner, database '%s'", - *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -297,34 +223,34 @@ begin_transaction (struct db *db, int only_batch) return 0; } + /* Commit a transaction. If ONLY_BATCH is 1, then this only ends the - batch transaction if we have left batch mode. If ONLY_BATCH is 2, - this ends any open batch transaction even if we are still in batch - mode. */ + * batch transaction if we have left batch mode. If ONLY_BATCH is 2, + * this ends any open batch transaction even if we are still in batch + * mode. */ static gpg_error_t -end_transaction (struct db *db, int only_batch) +end_transaction (ctrl_t ctrl, int only_batch) { + tofu_dbs_t dbs = ctrl->tofu.dbs; int rc; char *err = NULL; - if (!db) + if (!dbs) return 0; /* Shortcut to allow for easier cleanup code. */ - if ((! batch_update || only_batch == 2) && db->batch_update) - /* The batch transaction is still in open, but we left batch - mode. */ + if ((!ctrl->tofu.batch_update_ref || only_batch == 2) && dbs->batch_update) { - db->batch_update = 0; + /* The batch transaction is still in open, but we left batch + * mode. */ + dbs->batch_update = 0; - rc = gpgsql_stepx (db->db, &db->s.savepoint_batch_commit, + rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch_commit, NULL, NULL, &err, "release batch;", SQLITE_ARG_END); if (rc) { log_error (_("error committing transaction on TOFU database: %s\n"), err); - print_further_info ("batch, database '%s'", - *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -337,15 +263,13 @@ end_transaction (struct db *db, int only_batch) if (only_batch) return 0; - rc = gpgsql_stepx (db->db, &db->s.savepoint_inner_commit, + rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_inner_commit, NULL, NULL, &err, "release inner;", SQLITE_ARG_END); if (rc) { log_error (_("error committing transaction on TOFU database: %s\n"), err); - print_further_info ("inner, database '%s'", - *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -353,29 +277,33 @@ end_transaction (struct db *db, int only_batch) return 0; } + static gpg_error_t -rollback_transaction (struct db *db) +rollback_transaction (ctrl_t ctrl) { + tofu_dbs_t dbs = ctrl->tofu.dbs; int rc; char *err = NULL; - if (!db) + if (!dbs) return 0; /* Shortcut to allow for easier cleanup code. */ - if (db->batch_update) - /* Just undo the most recent update; don't revert any progress - made by the batch transaction. */ - rc = sqlite3_exec (db->db, "rollback to inner;", NULL, NULL, &err); + if (dbs->batch_update) + { + /* Just undo the most recent update; don't revert any progress + made by the batch transaction. */ + rc = sqlite3_exec (dbs->db, "rollback to inner;", NULL, NULL, &err); + } else - /* Rollback the whole she-bang. */ - rc = sqlite3_exec (db->db, "rollback;", NULL, NULL, &err); + { + /* Rollback the whole she-bang. */ + rc = sqlite3_exec (dbs->db, "rollback;", NULL, NULL, &err); + } if (rc) { log_error (_("error rolling back transaction on TOFU database: %s\n"), err); - print_further_info ("inner, database '%s'", - *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -384,27 +312,22 @@ rollback_transaction (struct db *db) } void -tofu_begin_batch_update (void) +tofu_begin_batch_update (ctrl_t ctrl) { - if (! batch_update) - batch_update_started = gnupg_get_time (); + if (!ctrl->tofu.batch_update_ref) + ctrl->tofu.batch_update_started = gnupg_get_time (); - batch_update ++; + ctrl->tofu.batch_update_ref ++; } void -tofu_end_batch_update (void) +tofu_end_batch_update (ctrl_t ctrl) { - log_assert (batch_update > 0); - batch_update --; + log_assert (ctrl->tofu.batch_update_ref > 0); + ctrl->tofu.batch_update_ref --; - if (batch_update == 0) - { - struct db *db; - - for (db = db_cache; db; db = db->next) - end_transaction (db, 1); - } + if (!ctrl->tofu.batch_update_ref) + end_transaction (ctrl, 1); } @@ -523,7 +446,7 @@ version_check_cb (void *cookie, int argc, char **argv, char **azColName) Return 0 if the database is okay and 1 otherwise. */ static int -initdb (sqlite3 *db, enum db_type type) +initdb (sqlite3 *db) { char *err = NULL; int rc; @@ -639,8 +562,7 @@ initdb (sqlite3 *db, enum db_type type) * the old binding's policy to ask if it was auto. So that we * know why this occurred, we also set conflict to 0xbaddecaf. */ - if (type == DB_EMAIL || type == DB_COMBINED) - rc = gpgsql_exec_printf + rc = gpgsql_exec_printf (db, NULL, NULL, &err, "create table bindings\n" " (oid INTEGER PRIMARY KEY AUTOINCREMENT,\n" @@ -653,20 +575,6 @@ initdb (sqlite3 *db, enum db_type type) "create index bindings_email on bindings (email);\n", TOFU_POLICY_AUTO, TOFU_POLICY_GOOD, TOFU_POLICY_UNKNOWN, TOFU_POLICY_BAD, TOFU_POLICY_ASK); - else - /* In the split DB case, the fingerprint DB only contains a subset - of the fields. This reduces the amount of duplicated data. - - Note: since the data is split on the email address, there is no - need to index the email column. */ - rc = gpgsql_exec_printf - (db, NULL, NULL, &err, - "create table bindings\n" - " (oid INTEGER PRIMARY KEY AUTOINCREMENT,\n" - " fingerprint TEXT, email TEXT, user_id,\n" - " unique (fingerprint, email));\n" - "create index bindings_fingerprint\n" - " on bindings (fingerprint);\n"); if (rc) { log_error (_("error initializing TOFU database: %s\n"), err); @@ -675,35 +583,32 @@ initdb (sqlite3 *db, enum db_type type) goto out; } - if (type != DB_KEY) - { - /* The signatures that we have observed. - - BINDING refers to a record in the bindings table, which - describes the binding (i.e., this is a foreign key that - references bindings.oid). - - SIG_DIGEST is the digest stored in the signature. - - SIG_TIME is the timestamp stored in the signature. - - ORIGIN is a free-form string that describes who fed this - signature to GnuPG (e.g., email:claws). - - TIME is the time this signature was registered. */ - rc = sqlite3_exec (db, + /* The signatures that we have observed. + * + * BINDING refers to a record in the bindings table, which + * describes the binding (i.e., this is a foreign key that + * references bindings.oid). + * + * SIG_DIGEST is the digest stored in the signature. + * + * SIG_TIME is the timestamp stored in the signature. + * + * ORIGIN is a free-form string that describes who fed this + * signature to GnuPG (e.g., email:claws). + * + * TIME is the time this signature was registered. */ + rc = sqlite3_exec (db, "create table signatures " " (binding INTEGER NOT NULL, sig_digest TEXT," " origin TEXT, sig_time INTEGER, time INTEGER," " primary key (binding, sig_digest, origin));", NULL, NULL, &err); - if (rc) - { - log_error (_("error initializing TOFU database: %s\n"), err); - print_further_info ("create signatures"); - sqlite3_free (err); - goto out; - } + if (rc) + { + log_error (_("error initializing TOFU database: %s\n"), err); + print_further_info ("create signatures"); + sqlite3_free (err); + goto out; } out: @@ -732,408 +637,79 @@ initdb (sqlite3 *db, enum db_type type) } } -/* Open and initialize a low-level TOFU database. Returns NULL on - failure. This function should not normally be directly called to - get a database handle. Instead, use getdb(). */ -static sqlite3 * -opendb (char *filename, enum db_type type) + +/* Create a new DB handle. Returns NULL on error. */ +/* FIXME: Change to return an error code for better reporting by the + caller. */ +static tofu_dbs_t +opendbs (ctrl_t ctrl) { + char *filename; sqlite3 *db; - int filename_free = 0; int rc; - if (opt.tofu_db_format == TOFU_DB_FLAT) + if (!ctrl->tofu.dbs) { - log_assert (! filename); - log_assert (type == DB_COMBINED); - filename = make_filename (gnupg_homedir (), "tofu.db", NULL); - filename_free = 1; - } - else - log_assert (type == DB_EMAIL || type == DB_KEY); - - log_assert (filename); - - rc = sqlite3_open (filename, &db); - if (rc) - { - log_error (_("error opening TOFU database '%s': %s\n"), - filename, sqlite3_errmsg (db)); - /* Even if an error occurs, DB is guaranteed to be valid. */ - sqlite3_close (db); - db = NULL; - } - - /* If a DB is locked wait up to 5 seconds for the lock to be cleared - before failing. */ - if (db) - sqlite3_busy_timeout (db, 5 * 1000); - - if (filename_free) - xfree (filename); - - if (db && initdb (db, type)) - { - sqlite3_close (db); - db = NULL; - } - - return db; -} - -/* Definition of the Tofu dabase meta handle. */ -struct tofu_dbs_s -{ - struct db *db; -}; - -static void -unlink_db (struct db *db) -{ - *db->prevp = db->next; - if (db->next) - db->next->prevp = db->prevp; -} - -static void -link_db (struct db **head, struct db *db) -{ - db->next = *head; - if (db->next) - db->next->prevp = &db->next; - db->prevp = head; - *head = db; -} - -/* Return a database handle. describes the required - database. If there is a cached handle in DBS, that handle is - returned. Otherwise, the database is opened and cached in DBS. - - NAME is the name of the DB and may not be NULL. - TYPE must be either DB_MAIL or DB_KEY. In the combined format, the - combined DB is always returned. */ -static struct db * -getdb (tofu_dbs_t dbs, const char *name, enum db_type type) -{ - struct db *t = NULL; - char *name_sanitized = NULL; - int count; - char *filename = NULL; - int need_link = 1; - sqlite3 *sqlitedb = NULL; - gpg_error_t rc; - - log_assert (dbs); - log_assert (name); - log_assert (type == DB_EMAIL || type == DB_KEY); - - if (opt.tofu_db_format == TOFU_DB_FLAT) - /* When using the flat format, we only have a single DB, the - combined DB. */ - { - if (dbs->db) + rc = sqlite3_open (filename, &db); + if (rc) { - log_assert (dbs->db->type == DB_COMBINED); - log_assert (! dbs->db->next); - return dbs->db; + log_error (_("error opening TOFU database '%s': %s\n"), + filename, sqlite3_errmsg (db)); + /* Even if an error occurs, DB is guaranteed to be valid. */ + sqlite3_close (db); + db = NULL; } + xfree (filename); - type = DB_COMBINED; - } - - if (type != DB_COMBINED) - /* Only allow alpha-numeric characters in the name. */ - { - int i; + /* If a DB is locked wait up to 5 seconds for the lock to be cleared + before failing. */ + if (db) + sqlite3_busy_timeout (db, 5 * 1000); - name_sanitized = xstrdup (name); - for (i = 0; name[i]; i ++) + if (db && initdb (db)) { - char c = name_sanitized[i]; - if (! (('a' <= c && c <= 'z') - || ('A' <= c && c <= 'Z') - || ('0' <= c && c <= '9'))) - name_sanitized[i] = '_'; + sqlite3_close (db); + db = NULL; } - } - - /* See if the DB is cached. */ - for (t = dbs->db; t; t = t->next) - if (t->type == type - && (type == DB_COMBINED || strcmp (t->name, name_sanitized) == 0)) - { - need_link = 0; - goto out; - } - - for (t = db_cache, count = 0; t; t = t->next, count ++) - if (type == t->type - && (type == DB_COMBINED || strcmp (t->name, name_sanitized) == 0)) - { - unlink_db (t); - db_cache_count --; - goto out; - } - - log_assert (db_cache_count == count); - - if (type == DB_COMBINED) - filename = NULL; - else - { - /* Open the DB. The filename has the form: - - tofu.d/TYPE/PREFIX/NAME.db - - We use a short prefix to try to avoid having many files in a - single directory. */ - { - char *type_str = type == DB_EMAIL ? "email" : "key"; - char prefix[3] = { name_sanitized[0], name_sanitized[1], 0 }; - char *name_db; - - /* Make the directory. */ - rc = gnupg_mkdir_p (gnupg_homedir (), "tofu.d", type_str, prefix, NULL); - if (rc) - { - name_db = xstrconcat (gnupg_homedir (), "tofu.d", - type_str, prefix, NULL); - log_error (_("can't create directory '%s': %s\n"), - name_db, gpg_strerror (rc)); - xfree (name_db); - goto out; - } - - name_db = xstrconcat (name_sanitized, ".db", NULL); - filename = make_filename - (gnupg_homedir (), "tofu.d", type_str, prefix, name_db, NULL); - xfree (name_db); - } - } - - sqlitedb = opendb (filename, type); - if (! sqlitedb) - goto out; - - t = xmalloc_clear (sizeof (struct db) - + (name_sanitized ? strlen (name_sanitized) : 0)); - t->type = type; - t->db = sqlitedb; - if (name_sanitized) - strcpy (t->name, name_sanitized); - - out: - if (t && need_link) - link_db (&dbs->db, t); - -#if DEBUG_TOFU_CACHE - if (t) - t->hits ++; -#endif - - xfree (filename); - xfree (name_sanitized); - return t; -} - -static void -closedb (struct db *db) -{ - sqlite3_stmt **statements; - if (opt.tofu_db_format == TOFU_DB_FLAT) - /* If we are using the flat format, then there is only ever the - combined DB. */ - log_assert (! db->next); - - if (db->type == DB_COMBINED) - { - log_assert (opt.tofu_db_format == TOFU_DB_FLAT); - log_assert (! db->name[0]); + if (db) + { + ctrl->tofu.dbs = xmalloc_clear (sizeof *ctrl->tofu.dbs); + ctrl->tofu.dbs->db = db; + } } else - { - log_assert (opt.tofu_db_format == TOFU_DB_SPLIT); - log_assert (db->type != DB_COMBINED); - log_assert (db->name[0]); - } - - if (db->batch_update) - end_transaction (db, 2); - - for (statements = (void *) &db->s; - (void *) statements < (void *) &(&db->s)[1]; - statements ++) - sqlite3_finalize (*statements); - - sqlite3_close (db->db); - -#if DEBUG_TOFU_CACHE - log_debug ("Freeing db. Used %d times.\n", db->hits); -#endif - - xfree (db); -} - - -/* Create a new DB meta-handle. Returns NULL on error. */ -/* FIXME: Change to return an error code for better reporting by the - caller. */ -static tofu_dbs_t -opendbs (ctrl_t ctrl) -{ - if (ctrl->tofu.dbs) - return ctrl->tofu.dbs; - - if (opt.tofu_db_format == TOFU_DB_AUTO) - { - char *filename = make_filename (gnupg_homedir (), "tofu.db", NULL); - struct stat s; - int have_tofu_db = 0; - int have_tofu_d = 0; - - if (stat (filename, &s) == 0) - { - have_tofu_db = 1; - if (DBG_TRUST) - log_debug ("%s exists.\n", filename); - } - else - { - if (DBG_TRUST) - log_debug ("%s does not exist.\n", filename); - } - - /* We now have tofu.d. */ - filename[strlen (filename) - 1] = '\0'; - if (stat (filename, &s) == 0) - { - have_tofu_d = 1; - if (DBG_TRUST) - log_debug ("%s exists.\n", filename); - } - else - { - if (DBG_TRUST) - log_debug ("%s does not exist.\n", filename); - } - - xfree (filename); - - if (have_tofu_db && have_tofu_d) - { - log_info (_("Warning: Home directory contains both tofu.db" - " and tofu.d.\n")); - log_info (_("Using split format for TOFU database\n")); - opt.tofu_db_format = TOFU_DB_SPLIT; - } - else if (have_tofu_db) - { - opt.tofu_db_format = TOFU_DB_FLAT; - if (DBG_TRUST) - log_debug ("Using flat format for TOFU database.\n"); - } - else if (have_tofu_d) - { - opt.tofu_db_format = TOFU_DB_SPLIT; - if (DBG_TRUST) - log_debug ("Using split format for TOFU database.\n"); - } - else - { - opt.tofu_db_format = TOFU_DB_FLAT; - if (DBG_TRUST) - log_debug ("Using flat format for TOFU database.\n"); - } - } + log_assert (ctrl->tofu.dbs->db); - ctrl->tofu.dbs = xmalloc_clear (sizeof (struct tofu_dbs_s)); return ctrl->tofu.dbs; } -/* Release all of the resources associated with a DB meta-handle. */ +/* Release all of the resources associated with the DB handle. */ void tofu_closedbs (ctrl_t ctrl) { - tofu_dbs_t dbs = ctrl->tofu.dbs; + tofu_dbs_t dbs; + sqlite3_stmt **statements; + dbs = ctrl->tofu.dbs; if (!dbs) return; /* Not initialized. */ - if (dbs->db && dbs->db->type == DB_COMBINED) - { - log_assert (!dbs->db->next); - closedb (dbs->db); - } - else if (dbs->db) - { - struct db *old_head = db_cache; - struct db *db; - int count; - - /* Find the last DB. */ - for (db = dbs->db, count = 1; db->next; db = db->next, count ++) - { - /* When we leave batch mode we leave batch mode on any - cached connections. */ - if (! batch_update) - log_assert (! db->batch_update); - } - if (! batch_update) - log_assert (! db->batch_update); + if (dbs->batch_update) + end_transaction (ctrl, 2); - /* Join the two lists. */ - db->next = db_cache; - if (db_cache) - db_cache->prevp = &db->next; - - /* Update the (new) first element. */ - db_cache = dbs->db; - dbs->db->prevp = &db_cache; - - db_cache_count += count; - - /* Make sure that we don't have too many DBs on DB_CACHE. If - so, free some. */ - if (db_cache_count > DB_CACHE_ENTRIES) - { - /* We need to find the (DB_CACHE_ENTRIES + 1)th entry. It - is easy to skip the first COUNT entries since we still - have a handle on the old head. */ - int skip = DB_CACHE_ENTRIES - count; - if (skip < 0) - for (old_head = db_cache, skip = DB_CACHE_ENTRIES; - skip > 0; - old_head = old_head->next, skip--) - { /* Do nothing. */ } - else - while (-- skip > 0) - old_head = old_head->next; - - *old_head->prevp = NULL; - - while (old_head) - { - db = old_head->next; - closedb (old_head); - old_head = db; - db_cache_count --; - } - - log_assert (db_cache_count == DB_CACHE_ENTRIES); - } - } + /* Arghh, that is asurprising use of the struct. */ + for (statements = (void *) &dbs->s; + (void *) statements < (void *) &(&dbs->s)[1]; + statements ++) + sqlite3_finalize (*statements); - xfree (ctrl->tofu.dbs); + sqlite3_close (dbs->db); + xfree (dbs); ctrl->tofu.dbs = NULL; - -#if DEBUG_TOFU_CACHE - log_debug ("Queries: %d (prepares saved: %d)\n", - queries, prepares_saved); -#endif } @@ -1171,7 +747,6 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, const char *user_id, enum tofu_policy policy, int show_old) { char *fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); - struct db *db_email = NULL, *db_key = NULL; gpg_error_t rc; char *err = NULL; /* policy_old needs to be a long and not an enum tofu_policy, @@ -1186,44 +761,14 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, || policy == TOFU_POLICY_ASK)) log_bug ("%s: Bad value for policy (%d)!\n", __func__, policy); - db_email = getdb (dbs, email, DB_EMAIL); - if (! db_email) - { - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (opt.tofu_db_format == TOFU_DB_SPLIT) - /* In the split format, we need to update two DBs. To keep them - consistent, we start a transaction on each. Note: this is the - only place where we start two transaction and we always start - transaction on the DB_KEY DB first, thus deadlock is not - possible. */ - /* We only need a transaction for the split format. */ - { - db_key = getdb (dbs, fingerprint, DB_KEY); - if (! db_key) - { - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - rc = begin_transaction (db_email, 0); - if (rc) - goto leave; - - rc = begin_transaction (db_key, 0); - if (rc) - goto out_revert_one; - } if (show_old) - /* Get the old policy. Since this is just for informational - purposes, there is no need to start a transaction or to die if - there is a failure. */ { + /* Get the old policy. Since this is just for informational + * purposes, there is no need to start a transaction or to die + * if there is a failure. */ rc = gpgsql_stepx - (db_email->db, &db_email->s.record_binding_get_old_policy, + (dbs->db, &dbs->s.record_binding_get_old_policy, get_single_long_cb2, &policy_old, &err, "select policy from bindings where fingerprint = ? and email = ?", SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, @@ -1252,17 +797,20 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, } if (policy_old == policy) - /* Nothing to do. */ - goto out; + { + rc = 0; + goto leave; /* Nothing to do. */ + } if (opt.dry_run) { log_info ("TOFU database update skipped due to --dry-run\n"); - goto out; + rc = 0; + goto leave; } rc = gpgsql_stepx - (db_email->db, &db_email->s.record_binding_update, NULL, NULL, &err, + (dbs->db, &dbs->s.record_binding_update, NULL, NULL, &err, "insert or replace into bindings\n" " (oid, fingerprint, email, user_id, time, policy)\n" " values (\n" @@ -1281,64 +829,11 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, print_further_info (" insert bindings <%s, %s> = %s", fingerprint, email, tofu_policy_str (policy)); sqlite3_free (err); - goto out; - } - - if (db_key) - /* We also need to update the key DB. */ - { - log_assert (opt.tofu_db_format == TOFU_DB_SPLIT); - - rc = gpgsql_stepx - (db_key->db, &db_key->s.record_binding_update2, NULL, NULL, &err, - "insert or replace into bindings\n" - " (oid, fingerprint, email, user_id)\n" - " values (\n" - /* If we don't explicitly reuse the OID, then SQLite will - reallocate a new one. We just need to search for the OID - based on the fingerprint and email since they are unique. */ - " (select oid from bindings where fingerprint = ? and email = ?),\n" - " ?, ?, ?);", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_STRING, user_id, SQLITE_ARG_END); - if (rc) - { - log_error (_("error updating TOFU database: %s\n"), err); - print_further_info ("insert bindings <%s, %s>", - fingerprint, email); - sqlite3_free (err); - goto out; - } - } - else - log_assert (opt.tofu_db_format == TOFU_DB_FLAT); - - out: - if (opt.tofu_db_format == TOFU_DB_SPLIT) - /* We only need a transaction for the split format. */ - { - gpg_error_t rc2; - - if (rc) - rc2 = rollback_transaction (db_key); - else - rc2 = end_transaction (db_key, 0); - if (rc2) - sqlite3_free (err); - - out_revert_one: - if (rc) - rc2 = rollback_transaction (db_email); - else - rc2 = end_transaction (db_email, 0); - if (rc2) - sqlite3_free (err); + goto leave; } leave: xfree (fingerprint_pp); - return rc; } @@ -1507,22 +1002,17 @@ static enum tofu_policy get_policy (tofu_dbs_t dbs, const char *fingerprint, const char *email, char **conflict) { - struct db *db; int rc; char *err = NULL; strlist_t strlist = NULL; enum tofu_policy policy = _tofu_GET_POLICY_ERROR; long along; - db = getdb (dbs, email, DB_EMAIL); - if (! db) - return _tofu_GET_POLICY_ERROR; - /* Check if the binding is known (TOFU_POLICY_NONE cannot appear in the DB. Thus, if POLICY is still TOFU_POLICY_NONE after executing the query, then the result set was empty.) */ - rc = gpgsql_stepx (db->db, &db->s.get_policy_select_policy_and_conflict, + rc = gpgsql_stepx (dbs->db, &dbs->s.get_policy_select_policy_and_conflict, strings_collect_cb2, &strlist, &err, "select policy, conflict from bindings\n" " where fingerprint = ? and email = ?", @@ -1681,7 +1171,6 @@ format_conflict_msg_part1 (int policy, const char *conflict, */ static void ask_about_binding (tofu_dbs_t dbs, - struct db *db, enum tofu_policy *policy, int *trust_level, int bindings_with_this_email_count, @@ -1699,7 +1188,6 @@ ask_about_binding (tofu_dbs_t dbs, struct signature_stats *stats_iter = NULL; char *prompt; char *choices; - struct db *db_key; fp = es_fopenmem (0, "rw,samethread"); if (!fp) @@ -1716,30 +1204,16 @@ ask_about_binding (tofu_dbs_t dbs, /* Find other user ids associated with this key and whether the * bindings are marked as good or bad. */ - if (opt.tofu_db_format == TOFU_DB_SPLIT) - { - /* In the split format, we need to search in the fingerprint DB - * for all the emails associated with this key, not the email DB. */ - db_key = getdb (dbs, fingerprint, DB_KEY); - } - else - db_key = db; - - if (db_key) + rc = gpgsql_stepx + (dbs->db, &dbs->s.get_trust_gather_other_user_ids, + strings_collect_cb2, &other_user_ids, &sqerr, + "select user_id, policy from bindings where fingerprint = ?;", + SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END); + if (rc) { - rc = gpgsql_stepx - (db_key->db, &db_key->s.get_trust_gather_other_user_ids, - strings_collect_cb2, &other_user_ids, &sqerr, - opt.tofu_db_format == TOFU_DB_SPLIT - ? "select user_id, email from bindings where fingerprint = ?;" - : "select user_id, policy from bindings where fingerprint = ?;", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END); - if (rc) - { - log_error (_("error gathering other user IDs: %s\n"), sqerr); - sqlite3_free (sqerr); - sqerr = NULL; - } + log_error (_("error gathering other user IDs: %s\n"), sqerr); + sqlite3_free (sqerr); + sqerr = NULL; } if (other_user_ids) @@ -1759,10 +1233,7 @@ ask_about_binding (tofu_dbs_t dbs, strlist_iter = strlist_iter->next; other_thing = strlist_iter->d; - if (opt.tofu_db_format == TOFU_DB_SPLIT) - other_policy = get_policy (dbs, fingerprint, other_thing, NULL); - else - other_policy = atoi (other_thing); + other_policy = atoi (other_thing); es_fprintf (fp, " %s (", other_user_id); es_fprintf (fp, _("policy: %s"), tofu_policy_str (other_policy)); @@ -1778,7 +1249,7 @@ ask_about_binding (tofu_dbs_t dbs, embedded in the signature (column 'sig_time') or the time that we first verified the signature (column 'time'). */ rc = gpgsql_stepx - (db->db, &db->s.get_trust_gather_other_keys, + (dbs->db, &dbs->s.get_trust_gather_other_keys, signature_stats_collect_cb, &stats, &sqerr, "select fingerprint, policy, time_ago, count(*)\n" " from (select bindings.*,\n" @@ -2028,7 +1499,6 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, const char *fingerprint, const char *email, const char *user_id, int may_ask) { - struct db *db; enum tofu_policy policy; char *conflict = NULL; int rc; @@ -2051,10 +1521,6 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, && _tofu_GET_TRUST_ERROR != TRUST_FULLY && _tofu_GET_TRUST_ERROR != TRUST_ULTIMATE); - db = getdb (dbs, email, DB_EMAIL); - if (! db) - return _tofu_GET_TRUST_ERROR; - policy = get_policy (dbs, fingerprint, email, &conflict); if (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_NONE) { /* See if the key is ultimately trusted. If so, we're done. */ @@ -2149,7 +1615,7 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, * also be returned. Thus, if the result set is empty, then this is * a new binding. */ rc = gpgsql_stepx - (db->db, &db->s.get_trust_bindings_with_this_email, + (dbs->db, &dbs->s.get_trust_bindings_with_this_email, strings_collect_cb2, &bindings_with_this_email, &sqerr, "select distinct fingerprint from bindings where email = ?;", SQLITE_ARG_STRING, email, SQLITE_ARG_END); @@ -2221,7 +1687,7 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, } /* If we get here, we need to ask the user about the binding. */ - ask_about_binding (dbs, db, + ask_about_binding (dbs, &policy, &trust_level, bindings_with_this_email_count, @@ -2239,7 +1705,7 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, /* If we weren't allowed to ask, also update this key as conflicting with itself. */ rc = gpgsql_exec_printf - (db->db, NULL, NULL, &sqerr, + (dbs->db, NULL, NULL, &sqerr, "update bindings set policy = %d, conflict = %Q" " where email = %Q" " and (policy = %d or (policy = %d and fingerprint = %Q));", @@ -2249,7 +1715,7 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, else { rc = gpgsql_exec_printf - (db->db, NULL, NULL, &sqerr, + (dbs->db, NULL, NULL, &sqerr, "update bindings set policy = %d, conflict = %Q" " where email = %Q and fingerprint != %Q and policy = %d;", TOFU_POLICY_ASK, fingerprint, email, fingerprint, @@ -2445,20 +1911,15 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, const char *email, const char *user_id, const char *sig_exclude) { - struct db *db; char *fingerprint_pp; int rc; strlist_t strlist = NULL; char *err = NULL; - db = getdb (dbs, email, DB_EMAIL); - if (! db) - return; - fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); rc = gpgsql_exec_printf - (db->db, strings_collect_cb, &strlist, &err, + (dbs->db, strings_collect_cb, &strlist, &err, "select count (*), strftime('%%s','now') - min (signatures.time),\n" " strftime('%%s','now') - max (signatures.time)\n" " from signatures\n" @@ -2687,7 +2148,6 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, time_t sig_time, const char *origin, int may_ask) { tofu_dbs_t dbs; - struct db *db; char *fingerprint = NULL; char *email = NULL; char *err = NULL; @@ -2731,25 +2191,16 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, goto die; } - /* Save the observed signature in the DB. */ - db = getdb (dbs, email, DB_EMAIL); - if (! db) - { - log_error (_("error opening TOFU database: %s\n"), - gpg_strerror (GPG_ERR_GENERAL)); - goto die; - } - /* We do a query and then an insert. Make sure they are atomic by wrapping them in a transaction. */ - rc = begin_transaction (db, 0); + rc = begin_transaction (ctrl, 0); if (rc) goto die; /* If we've already seen this signature before, then don't add it again. */ rc = gpgsql_stepx - (db->db, &db->s.register_already_seen, + (dbs->db, &dbs->s.register_already_seen, get_single_unsigned_long_cb2, &c, &err, "select count (*)\n" " from signatures left join bindings\n" @@ -2799,7 +2250,7 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, log_assert (c == 0); rc = gpgsql_stepx - (db->db, &db->s.register_insert, NULL, NULL, &err, + (dbs->db, &dbs->s.register_insert, NULL, NULL, &err, "insert into signatures\n" " (binding, sig_digest, origin, sig_time, time)\n" " values\n" @@ -2821,9 +2272,9 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, /* It only matters whether we abort or commit the transaction (so long as we do something) if we execute the insert. */ if (rc) - rc = rollback_transaction (db); + rc = rollback_transaction (ctrl); else - rc = end_transaction (db, 0); + rc = end_transaction (ctrl, 0); if (rc) { sqlite3_free (err); diff --git a/g10/tofu.h b/g10/tofu.h index d3448b9..e3ec819 100644 --- a/g10/tofu.h +++ b/g10/tofu.h @@ -112,8 +112,8 @@ gpg_error_t tofu_get_policy (ctrl_t ctrl, /* When doing a lot of DB activities (in particular, when listing keys), this causes the DB to enter batch mode, which can significantly speed up operations. */ -void tofu_begin_batch_update (void); -void tofu_end_batch_update (void); +void tofu_begin_batch_update (ctrl_t ctrl); +void tofu_end_batch_update (ctrl_t ctrl); /* Release all of the resources associated with a DB meta-handle. */ void tofu_closedbs (ctrl_t ctrl); diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm index 38b6a0f..2b302ba 100755 --- a/tests/openpgp/tofu.scm +++ b/tests/openpgp/tofu.scm @@ -164,4 +164,4 @@ (checkpolicy "BC15C85A" format "ask") (checkpolicy "2183839A" format "bad") (checkpolicy "EE37CF96" format "ask")) - '("split" "flat")) + '("flat")) ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 52 +++ doc/gpg.texi | 19 -- g10/gpg.c | 31 +- g10/gpg.h | 2 + g10/gpgv.c | 6 +- g10/keylist.c | 4 +- g10/options.h | 6 +- g10/test-stubs.c | 6 +- g10/tofu.c | 869 +++++++++---------------------------------------- g10/tofu.h | 4 +- tests/openpgp/tofu.scm | 2 +- 11 files changed, 230 insertions(+), 771 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 17:58:24 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 10 Aug 2016 17:58:24 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-67-ga6acf1f 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 a6acf1f6b39c5a607f61f643a5d21309ba58685d (commit) from 5b59999ce0dd1650ebe47a74a30ded6af00eeed3 (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 a6acf1f6b39c5a607f61f643a5d21309ba58685d Author: Justus Winter Date: Wed Aug 10 17:57:32 2016 +0200 tests: Fix distcheck. * tests/openpgp/issue2417.scm: Copy configuration. Signed-off-by: Justus Winter diff --git a/tests/openpgp/issue2417.scm b/tests/openpgp/issue2417.scm index 32840f2..9079323 100755 --- a/tests/openpgp/issue2417.scm +++ b/tests/openpgp/issue2417.scm @@ -19,6 +19,8 @@ (load (with-path "defs.scm")) +(define old-home (getenv "GNUPGHOME")) + (define (touch file-name) (close (open file-name (logior O_WRONLY O_BINARY O_CREAT) #o600))) @@ -32,6 +34,8 @@ (pipe:write-to keyfile (logior O_WRONLY O_BINARY O_CREAT) #o600)) (with-temporary-working-directory + (file-copy (path-join old-home "gpg.conf") "gpg.conf") + (file-copy (path-join old-home "gpg-agent.conf") "gpg-agent.conf") (setenv "GNUPGHOME" "." #t) (touch "trustdb.gpg") (touch "pubring.gpg") ----------------------------------------------------------------------- Summary of changes: tests/openpgp/issue2417.scm | 4 ++++ 1 file changed, 4 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 10 19:57:18 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 10 Aug 2016 19:57:18 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-69-ged5c1b0 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 ed5c1b0b8a4790c4fb36a3129387f7c2ef5db302 (commit) via f2ea7e539c9a22081e3159dcbca84f57f30724ca (commit) from a6acf1f6b39c5a607f61f643a5d21309ba58685d (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 ed5c1b0b8a4790c4fb36a3129387f7c2ef5db302 Author: Werner Koch Date: Wed Aug 10 19:51:54 2016 +0200 gpg: Print the signer's UID during verification. * g10/parse-packet.c (parse_signature): Sanitize the value stored in SIGNERS_UID. * g10/mainproc.c (issuer_fpr_string): New. (check_sig_and_print): Print the signers' UID. Print the issuer fingerprint in --rfc4880bis mode. -- Signed-off-by: Werner Koch diff --git a/g10/mainproc.c b/g10/mainproc.c index e50e212..3d3f88b 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1552,6 +1552,21 @@ akl_has_wkd_method (void) } +/* Return the ISSUER fingerprint string in human readbale format if + * available. Caller must release the string. */ +static char * +issuer_fpr_string (PKT_signature *sig) +{ + const byte *p; + size_t n; + + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_ISSUER_FPR, &n); + if (p && n == 21 && p[0] == 4) + return bin2hex (p+1, n-1, NULL); + return NULL; +} + + static void print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un, PKT_signature *sig, int rc) @@ -1589,6 +1604,7 @@ check_sig_and_print (CTX c, kbnode_t node) int is_expkey = 0; int is_revkey = 0; char pkstrbuf[PUBKEY_STRING_SIZE]; + char *issuer_fpr; *pkstrbuf = 0; @@ -1715,17 +1731,29 @@ 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) + if (opt.flags.rfc4880bis && (issuer_fpr = issuer_fpr_string (sig))) + { + log_info (_("Signature made %s\n"), asctimestamp(sig->timestamp)); + log_info (_(" using %s key %s\n"), + astr? astr: "?", issuer_fpr); + + xfree (issuer_fpr); + } + else if (!keystrlen () || keystrlen () > 8) { log_info (_("Signature made %s\n"), asctimestamp(sig->timestamp)); log_info (_(" using %s key %s\n"), astr? astr: "?", keystr(sig->keyid)); } - else + else /* Legacy format. */ log_info (_("Signature made %s using %s key ID %s\n"), asctimestamp(sig->timestamp), astr? astr: "?", keystr(sig->keyid)); + /* In verbose mode print the signers UID. */ + if (sig->signers_uid) + log_info (_(" issuer \"%s\"\n"), sig->signers_uid); + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); /* If the key isn't found, check for a preferred keyserver. */ diff --git a/g10/packet.h b/g10/packet.h index 08e2cb7..9c9e909 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -231,7 +231,8 @@ typedef struct pka_info_t *pka_info; /* Malloced PKA data or NULL if not available. See also flags.pka_tried. */ char *signers_uid; /* Malloced value of the SIGNERS_UID - * subpacket. */ + * subpacket or NULL. This string has + * already been sanitized. */ subpktarea_t *hashed; /* All subpackets with hashed data (v4 only). */ subpktarea_t *unhashed; /* Ditto for unhashed data. */ /* First 2 bytes of the digest. (Serialized. Note: this is not diff --git a/g10/parse-packet.c b/g10/parse-packet.c index ec8a641..9a733b5 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1936,15 +1936,12 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIGNERS_UID, &len); if (p && len) { - sig->signers_uid = xtrymalloc (len+1); + sig->signers_uid = try_make_printable_string (p, len, 0); if (!sig->signers_uid) { rc = gpg_error_from_syserror (); goto leave; } - /* Note that we don't care about binary zeroes in the value. */ - memcpy (sig->signers_uid, p, len); - sig->signers_uid[len] = 0; } p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_NOTATION, NULL); commit f2ea7e539c9a22081e3159dcbca84f57f30724ca Author: Werner Koch Date: Wed Aug 10 19:04:43 2016 +0200 common: New function try_make_printable_string. * common/stringhelp.c (sanitize_buffer): Remove. Move code to ... * common/miscellaneous.c (try_make_printable_string): new. (make_printable_string): Call try_make_printable_string. Signed-off-by: Werner Koch diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 8d9a7aa..1327649 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -246,13 +246,77 @@ print_hexstring (FILE *fp, const void *buffer, size_t length, int reserved) #undef tohex } + +/* Create a string from the buffer P_ARG of length N which is suitable + * for printing. Caller must release the created string using xfree. + * On error ERRNO is set and NULL returned. Errors are only possible + * due to malloc failure. */ char * -make_printable_string (const void *p, size_t n, int delim ) +try_make_printable_string (const void *p_arg, size_t n, int delim) { - return sanitize_buffer (p, n, delim); + const unsigned char *p = p_arg; + size_t save_n, buflen; + const unsigned char *save_p; + char *buffer, *d; + + /* First count length. */ + for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) + { + if ( *p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) + { + if ( *p=='\n' || *p=='\r' || *p=='\f' + || *p=='\v' || *p=='\b' || !*p ) + buflen += 2; + else + buflen += 5; + } + else + buflen++; + } + p = save_p; + n = save_n; + /* And now make the string */ + d = buffer = xtrymalloc (buflen); + for ( ; n; n--, p++ ) + { + if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) { + *d++ = '\\'; + if( *p == '\n' ) + *d++ = 'n'; + else if( *p == '\r' ) + *d++ = 'r'; + else if( *p == '\f' ) + *d++ = 'f'; + else if( *p == '\v' ) + *d++ = 'v'; + else if( *p == '\b' ) + *d++ = 'b'; + else if( !*p ) + *d++ = '0'; + else { + sprintf(d, "x%02x", *p ); + d += 3; + } + } + else + *d++ = *p; + } + *d = 0; + return buffer; } +/* Same as try_make_printable_string but terminates the process on + * memory shortage. */ +char * +make_printable_string (const void *p, size_t n, int delim ) +{ + char *string = try_make_printable_string (p, n, delim); + if (!string) + xoutofcore (); + return string; +} + /* * Check if the file is compressed. diff --git a/common/stringhelp.c b/common/stringhelp.c index 95912e0..990fc35 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -687,65 +687,6 @@ hextobyte (const char *s) return c; } - -/* Create a string from the buffer P_ARG of length N which is suitable - for printing. Caller must release the created string using xfree. - This function terminates the process on memory shortage. */ -char * -sanitize_buffer (const void *p_arg, size_t n, int delim) -{ - const unsigned char *p = p_arg; - size_t save_n, buflen; - const unsigned char *save_p; - char *buffer, *d; - - /* First count length. */ - for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) - { - if ( *p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) - { - if ( *p=='\n' || *p=='\r' || *p=='\f' - || *p=='\v' || *p=='\b' || !*p ) - buflen += 2; - else - buflen += 5; - } - else - buflen++; - } - p = save_p; - n = save_n; - /* And now make the string */ - d = buffer = xmalloc( buflen ); - for ( ; n; n--, p++ ) - { - if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) { - *d++ = '\\'; - if( *p == '\n' ) - *d++ = 'n'; - else if( *p == '\r' ) - *d++ = 'r'; - else if( *p == '\f' ) - *d++ = 'f'; - else if( *p == '\v' ) - *d++ = 'v'; - else if( *p == '\b' ) - *d++ = 'b'; - else if( !*p ) - *d++ = '0'; - else { - sprintf(d, "x%02x", *p ); - d += 3; - } - } - else - *d++ = *p; - } - *d = 0; - return buffer; -} - - /* Given a string containing an UTF-8 encoded text, return the number of characters in this string. It differs from strlen in that it only counts complete UTF-8 characters. SIZE is the maximum length diff --git a/common/stringhelp.h b/common/stringhelp.h index b6f4167..adf2f20 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -61,9 +61,6 @@ int compare_filenames( const char *a, const char *b ); int hextobyte (const char *s); -char *sanitize_buffer (const void *p, size_t n, int delim); - - size_t utf8_charcount (const char *s, int len); diff --git a/common/util.h b/common/util.h index 3f2d174..6680414 100644 --- a/common/util.h +++ b/common/util.h @@ -287,6 +287,7 @@ void print_utf8_buffer2 (estream_t fp, const void *p, size_t n, int delim); void print_utf8_buffer (estream_t fp, const void *p, size_t n); void print_hexstring (FILE *fp, const void *buffer, size_t length, int reserved); +char *try_make_printable_string (const void *p, size_t n, int delim); char *make_printable_string (const void *p, size_t n, int delim); int is_file_compressed (const char *s, int *ret_rc); ----------------------------------------------------------------------- Summary of changes: common/miscellaneous.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-- common/stringhelp.c | 59 ------------------------------------------- common/stringhelp.h | 3 --- common/util.h | 1 + g10/mainproc.c | 32 ++++++++++++++++++++++-- g10/packet.h | 3 ++- g10/parse-packet.c | 5 +--- 7 files changed, 100 insertions(+), 71 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 11 13:28:25 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Thu, 11 Aug 2016 13:28:25 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-72-g72fa314 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 72fa314b71e4ce8780f59b16d32cabf5d4bd5451 (commit) via 14479e2515439c73e385f37e8c2b3fc517b038b9 (commit) via 9e6503b7ce019aa417099ded1dda87b68c33f912 (commit) from ed5c1b0b8a4790c4fb36a3129387f7c2ef5db302 (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 72fa314b71e4ce8780f59b16d32cabf5d4bd5451 Author: Justus Winter Date: Thu Aug 11 13:03:16 2016 +0200 common: Remove compatibility code. * common/Makefile.am: Drop deleted files. * common/w32-afunix.c: Delete file. * common/w32-afunix.h: Likewise. GnuPG-bug-id: 2408 Signed-off-by: Justus Winter diff --git a/common/Makefile.am b/common/Makefile.am index 2a24c57..422fcf6 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -95,7 +95,7 @@ common_sources = \ recsel.c recsel.h if HAVE_W32_SYSTEM -common_sources += w32-reg.c w32-afunix.c w32-afunix.h +common_sources += w32-reg.c endif # To make the code easier to read we have split home some code into diff --git a/common/w32-afunix.c b/common/w32-afunix.c deleted file mode 100644 index 4432219..0000000 --- a/common/w32-afunix.c +++ /dev/null @@ -1,148 +0,0 @@ -/* w32-afunix.c - AF_UNIX emulation for Windows (Client only). - * Copyright (C) 2004, 2006 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 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. - * - * 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 copies of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, see . - */ - -/* Use of this code is deprecated - you better use the socket wrappers - from libassuan. */ - -#ifdef _WIN32 -#include -#include -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include - -#include "w32-afunix.h" - - - -/* The buffer for NONCE needs to be at least 16 bytes. Returns 0 on - success. */ -static int -read_port_and_nonce (const char *fname, unsigned short *port, char *nonce) -{ - FILE *fp; - char buffer[50], *p; - size_t nread; - int aval; - - fp = fopen (fname, "rb"); - if (!fp) - return -1; - nread = fread (buffer, 1, sizeof buffer - 1, fp); - fclose (fp); - if (!nread) - { - gpg_err_set_errno (EIO); - return -1; - } - buffer[nread] = 0; - aval = atoi (buffer); - if (aval < 1 || aval > 65535) - { - gpg_err_set_errno (EINVAL); - return -1; - } - *port = (unsigned int)aval; - for (p=buffer; nread && *p != '\n'; p++, nread--) - ; - if (*p != '\n' || nread != 17) - { - gpg_err_set_errno (EINVAL); - return -1; - } - p++; nread--; - memcpy (nonce, p, 16); - return 0; -} - - - -int -_w32_close (int fd) -{ - int rc = closesocket (fd); - if (rc && WSAGetLastError () == WSAENOTSOCK) - rc = close (fd); - return rc; -} - - -int -_w32_sock_new (int domain, int type, int proto) -{ - if (domain == AF_UNIX || domain == AF_LOCAL) - domain = AF_INET; - return socket (domain, type, proto); -} - - -int -_w32_sock_connect (int sockfd, struct sockaddr *addr, int addrlen) -{ - struct sockaddr_in myaddr; - struct sockaddr_un *unaddr; - unsigned short port; - char nonce[16]; - int ret; - - (void)addrlen; - - unaddr = (struct sockaddr_un *)addr; - if (read_port_and_nonce (unaddr->sun_path, &port, nonce)) - return -1; - - myaddr.sin_family = AF_INET; - myaddr.sin_port = htons (port); - myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - /* Set return values. */ - unaddr->sun_family = myaddr.sin_family; - unaddr->sun_port = myaddr.sin_port; - unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; - - ret = connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr); - if (!ret) - { - /* Send the nonce. */ - ret = send (sockfd, nonce, 16, 0); - if (ret >= 0 && ret != 16) - { - gpg_err_set_errno (EIO); - ret = -1; - } - } - return ret; -} - - -#endif /*_WIN32*/ diff --git a/common/w32-afunix.h b/common/w32-afunix.h deleted file mode 100644 index 7025a49..0000000 --- a/common/w32-afunix.h +++ /dev/null @@ -1,63 +0,0 @@ -/* w32-afunix.h - AF_UNIX emulation for Windows - * Copyright (C) 2004, 2006 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 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. - * - * 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 copies of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, see . - */ - -#ifdef _WIN32 -#ifndef W32AFUNIX_DEFS_H -#define W32AFUNIX_DEFS_H - -#include -#include -#include -#include - -/* We can easiliy replace this code by the socket wrappers from libassuan. */ -#warning Remove this code; it is only used on w32 by symcryptrun. - -#define DIRSEP_C '\\' - -#define AF_LOCAL AF_UNIX -/* We need to prefix the structure with a sockaddr_in header so we can - use it later for sendto and recvfrom. */ -struct sockaddr_un -{ - short sun_family; - unsigned short sun_port; - struct in_addr sun_addr; - char sun_path[108-2-4]; /* Path name. */ -}; - - -int _w32_close (int fd); -int _w32_sock_new (int domain, int type, int proto); -int _w32_sock_connect (int sockfd, struct sockaddr *addr, int addrlen); - - -#endif /*W32AFUNIX_DEFS_H*/ -#endif /*_WIN32*/ commit 14479e2515439c73e385f37e8c2b3fc517b038b9 Author: Justus Winter Date: Thu Aug 11 12:26:09 2016 +0200 common: Rework the simple password query module. * common/simple-pwquery.c (writen, readline): Drop. (agent_send_option, agent_send_all_options, agent_open): Just use libassuan. (simple_pw_set_socket): Simplify. (default_inq_cb): New function. (simple_pwquery, simple_query): Just use libassuan. * agent/Makefile.am (gpg_preset_passphrase_LDADD): Add libassuan. * tools/Makefile.am (symcryptrun_LDADD): Likewise. Signed-off-by: Justus Winter diff --git a/agent/Makefile.am b/agent/Makefile.am index 4be9090..1970088 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -85,7 +85,7 @@ gpg_preset_passphrase_SOURCES = \ # Needs $(NETLIBS) for libsimple-pwquery.la. gpg_preset_passphrase_LDADD = \ - $(pwquery_libs) $(common_libs) \ + $(pwquery_libs) $(common_libs) $(LIBASSUAN_LIBS) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index bd40fdf..240451b 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -17,10 +17,10 @@ * along with this program; if not, see . */ -/* This module is intended as a standalone client implementation to - gpg-agent's GET_PASSPHRASE command. In particular it does not use - the Assuan library and can only cope with an already running - gpg-agent. Some stuff is configurable in the header file. */ +/* This module is intended as a simple client implementation to + gpg-agent's GET_PASSPHRASE command. It can only cope with an + already running gpg-agent. Some stuff is configurable in the + header file. */ #ifdef HAVE_CONFIG_H #include @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef HAVE_W32_SYSTEM #include #else @@ -42,9 +43,8 @@ #define GNUPG_COMMON_NEED_AFLOCAL #include "../common/mischelp.h" -#ifdef HAVE_W32_SYSTEM -#include "../common/w32-afunix.h" -#endif +#include "sysutils.h" +#include "membuf.h" #define SIMPLE_PWQUERY_IMPLEMENTATION 1 @@ -96,88 +96,11 @@ my_stpcpy(char *a,const char *b) #endif - -/* Write NBYTES of BUF to file descriptor FD. */ -static int -writen (int fd, const void *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - - while (nleft > 0) - { -#ifdef HAVE_W32_SYSTEM - nwritten = send (fd, buf, nleft, 0); -#else - nwritten = write (fd, buf, nleft); -#endif - if (nwritten < 0) - { - if (errno == EINTR) - nwritten = 0; - else { -#ifdef SPWQ_USE_LOGGING - log_error ("write failed: %s\n", strerror (errno)); -#endif - return SPWQ_IO_ERROR; - } - } - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } - - return 0; -} - - -/* Read an entire line and return number of bytes read. */ -static int -readline (int fd, char *buf, size_t buflen) -{ - size_t nleft = buflen; - char *p; - int nread = 0; - - while (nleft > 0) - { -#ifdef HAVE_W32_SYSTEM - int n = recv (fd, buf, nleft, 0); -#else - int n = read (fd, buf, nleft); -#endif - if (n < 0) - { - if (errno == EINTR) - continue; - return -(SPWQ_IO_ERROR); - } - else if (!n) - { - return -(SPWQ_PROTOCOL_ERROR); /* incomplete line */ - } - p = buf; - nleft -= n; - buf += n; - nread += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - break; /* At least one full line available - that's enough. - This function is just a simple implementation, so - it is okay to forget about pending bytes. */ - } - } - - return nread; -} - - /* Send an option to the agent */ static int -agent_send_option (int fd, const char *name, const char *value) +agent_send_option (assuan_context_t ctx, const char *name, const char *value) { + int err; char buf[200]; int nread; char *line; @@ -188,28 +111,17 @@ agent_send_option (int fd, const char *name, const char *value) return SPWQ_OUT_OF_CORE; strcpy (stpcpy (stpcpy (stpcpy ( stpcpy (line, "OPTION "), name), "="), value), "\n"); - i = writen (fd, line, strlen (line)); - spwq_free (line); - if (i) - return i; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 0) - return -nread; - if (nread < 3) - return SPWQ_PROTOCOL_ERROR; - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - return 0; /* okay */ + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return SPWQ_ERR_RESPONSE; + spwq_free (line); + return err; } /* Send all available options to the agent. */ static int -agent_send_all_options (int fd) +agent_send_all_options (assuan_context_t ctx) { char *dft_display = NULL; char *dft_ttyname = NULL; @@ -221,7 +133,7 @@ agent_send_all_options (int fd) dft_display = getenv ("DISPLAY"); if (dft_display) { - if ((rc = agent_send_option (fd, "display", dft_display))) + if ((rc = agent_send_option (ctx, "display", dft_display))) return rc; } @@ -232,14 +144,14 @@ agent_send_all_options (int fd) #endif if (dft_ttyname && *dft_ttyname) { - if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) + if ((rc=agent_send_option (ctx, "ttyname", dft_ttyname))) return rc; } dft_ttytype = getenv ("TERM"); if (dft_ttyname && dft_ttytype) { - if ((rc = agent_send_option (fd, "ttytype", dft_ttytype))) + if ((rc = agent_send_option (ctx, "ttytype", dft_ttytype))) return rc; } @@ -260,7 +172,7 @@ agent_send_all_options (int fd) } dft_lc = setlocale (LC_CTYPE, ""); if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-ctype", dft_lc); + rc = agent_send_option (ctx, "lc-ctype", dft_lc); if (old_lc) { setlocale (LC_CTYPE, old_lc); @@ -282,7 +194,7 @@ agent_send_all_options (int fd) } dft_lc = setlocale (LC_MESSAGES, ""); if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-messages", dft_lc); + rc = agent_send_option (ctx, "lc-messages", dft_lc); if (old_lc) { setlocale (LC_MESSAGES, old_lc); @@ -300,7 +212,7 @@ agent_send_all_options (int fd) { /* We ignore errors here because older gpg-agents don't support this option. */ - agent_send_option (fd, "xauthority", dft_xauthority); + agent_send_option (ctx, "xauthority", dft_xauthority); } /* Send the PINENTRY_USER_DATA variable. */ @@ -309,9 +221,14 @@ agent_send_all_options (int fd) { /* We ignore errors here because older gpg-agents don't support this option. */ - agent_send_option (fd, "pinentry-user-data", dft_pinentry_user_data); + agent_send_option (ctx, "pinentry-user-data", dft_pinentry_user_data); } + /* Tell the agent that we support Pinentry notifications. No + error checking so that it will work with older agents. */ + assuan_transact (ctx, "OPTION allow-pinentry-notify", + NULL, NULL, NULL, NULL, NULL, NULL); + return 0; } @@ -321,7 +238,7 @@ agent_send_all_options (int fd) the file descriptor for the connection. Return -1 in case of error. */ static int -agent_open (int *rfd) +agent_open (assuan_context_t *ctx) { int rc; int fd; @@ -331,7 +248,6 @@ agent_open (int *rfd) char line[200]; int nread; - *rfd = -1; infostr = default_gpg_agent_info; if ( !infostr || !*infostr ) { @@ -340,81 +256,35 @@ agent_open (int *rfd) #endif return SPWQ_NO_AGENT; } - p = spwq_malloc (strlen (infostr)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, infostr); - infostr = p; - - if ( !(p = strchr ( infostr, PATHSEP_C)) || p == infostr - || (p-infostr)+1 >= sizeof client_addr.sun_path ) - { - spwq_free (infostr); - return SPWQ_NO_AGENT; - } - *p++ = 0; - - while (*p && *p != PATHSEP_C) - p++; -#ifdef HAVE_W32_SYSTEM - fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0); -#else - fd = socket (AF_UNIX, SOCK_STREAM, 0); -#endif - if (fd == -1) - { -#ifdef SPWQ_USE_LOGGING - log_error ("can't create socket: %s\n", strerror(errno) ); -#endif - spwq_free (infostr); - return SPWQ_SYS_ERROR; - } - - memset (&client_addr, 0, sizeof client_addr); - client_addr.sun_family = AF_UNIX; - strcpy (client_addr.sun_path, infostr); - spwq_free (infostr); - len = SUN_LEN (&client_addr); + rc = assuan_new (ctx); + if (rc) + return rc; -#ifdef HAVE_W32_SYSTEM - rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len ); -#else - rc = connect (fd, (struct sockaddr*)&client_addr, len ); -#endif - if (rc == -1) + rc = assuan_socket_connect (*ctx, infostr, 0, 0); + if (rc) { #ifdef SPWQ_USE_LOGGING log_error (_("can't connect to '%s': %s\n"), - client_addr.sun_path, strerror (errno)); + infostr, gpg_strerror (rc)); #endif - close (fd ); - return SPWQ_IO_ERROR; + goto errout; } - nread = readline (fd, line, DIM(line)); - if (nread < 3 || !(line[0] == 'O' && line[1] == 'K' - && (line[2] == '\n' || line[2] == ' ')) ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("communication problem with gpg-agent\n")); -#endif - close (fd ); - return SPWQ_PROTOCOL_ERROR; - } - - rc = agent_send_all_options (fd); + rc = agent_send_all_options (*ctx); if (rc) { #ifdef SPWQ_USE_LOGGING log_error (_("problem setting the gpg-agent options\n")); #endif - close (fd); - return rc; + goto errout; } - *rfd = fd; return 0; + + errout: + assuan_release (*ctx); + *ctx = NULL; } @@ -451,17 +321,37 @@ int simple_pw_set_socket (const char *name) { spwq_free (default_gpg_agent_info); + default_gpg_agent_info = NULL; if (name) { - default_gpg_agent_info = spwq_malloc (strlen (name) + 4 + 1); + default_gpg_agent_info = spwq_malloc (strlen (name) + 1); if (!default_gpg_agent_info) return SPWQ_OUT_OF_CORE; - /* We don't know the PID thus we use 0. */ - strcpy (stpcpy (default_gpg_agent_info, name), - PATHSEP_S "0" PATHSEP_S "1"); + strcpy (default_gpg_agent_info, name); + } + + return 0; +} + + +/* This is the default inquiry callback. It merely handles the + Pinentry notification. */ +static gpg_error_t +default_inq_cb (void *opaque, const char *line) +{ + (void)opaque; + + if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17])) + { + gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10)); + /* We do not return errors to avoid breaking other code. */ } else - default_gpg_agent_info = NULL; + { +#ifdef SPWQ_USE_LOGGING + log_debug ("ignoring gpg-agent inquiry '%s'\n", line); +#endif + } return 0; } @@ -483,14 +373,15 @@ simple_pwquery (const char *cacheid, int opt_check, int *errorcode) { - int fd = -1; + assuan_context_t ctx; + membuf_t data; int nread; char *result = NULL; char *pw = NULL; char *p; int rc, i; - rc = agent_open (&fd); + rc = agent_open (&ctx); if (rc) goto leave; @@ -530,73 +421,43 @@ simple_pwquery (const char *cacheid, *p++ = ' '; p = copy_and_escape (p, description); *p++ = '\n'; - rc = writen (fd, line, p - line); + + init_membuf_secure (&data, 64); + + rc = assuan_transact (ctx, line, put_membuf_cb, &data, + default_inq_cb, NULL, NULL, NULL); spwq_free (line); - if (rc) - goto leave; - } - /* get response */ - pw = spwq_secure_malloc (500); - nread = readline (fd, pw, 499); - if (nread < 0) - { - rc = -nread; - goto leave; - } - if (nread < 3) - { - rc = SPWQ_PROTOCOL_ERROR; - goto leave; - } + /* Older Pinentries return the old assuan error code for canceled + which gets translated by libassuan to GPG_ERR_ASS_CANCELED and + not to the code for a user cancel. Fix this here. */ + if (rc && gpg_err_source (rc) + && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); - if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') - { /* we got a passphrase - convert it back from hex */ - size_t pwlen = 0; + if (rc) + { + void *p; + size_t n; - for (i=3; i < nread && hexdigitp (pw+i); i+=2) - pw[pwlen++] = xtoi_2 (pw+i); - pw[pwlen] = 0; /* make a C String */ - result = pw; - pw = NULL; - } - else if ((nread > 7 && !memcmp (pw, "ERR 111", 7) - && (pw[7] == ' ' || pw[7] == '\n') ) - || ((nread > 4 && !memcmp (pw, "ERR ", 4) - && (strtoul (pw+4, NULL, 0) & 0xffff) == 99)) ) - { - /* 111 is the old Assuan code for canceled which might still - be in use by old installations. 99 is GPG_ERR_CANCELED as - used by modern gpg-agents; 0xffff is used to mask out the - error source. */ -#ifdef SPWQ_USE_LOGGING - log_info (_("canceled by user\n") ); -#endif - *errorcode = 0; /* Special error code to indicate Cancel. */ - } - else if (nread > 4 && !memcmp (pw, "ERR ", 4)) - { - switch ( (strtoul (pw+4, NULL, 0) & 0xffff) ) - { - case 85: rc = SPWQ_NO_PIN_ENTRY; break; - default: rc = SPWQ_GENERAL_ERROR; break; - } - } - else - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem with the agent\n")); -#endif - rc = SPWQ_ERR_RESPONSE; - } + p = get_membuf (&data, &n); + if (p) + wipememory (p, n); + spwq_free (p); + } + else + { + put_membuf (&data, "", 1); + result = get_membuf (&data, NULL); + if (pw == NULL) + rc = gpg_error_from_syserror (); + } + } leave: if (errorcode) *errorcode = rc; - if (fd != -1) - close (fd); - if (pw) - spwq_secure_free (pw); + assuan_release (ctx); return result; } @@ -628,96 +489,17 @@ simple_pwclear (const char *cacheid) int simple_query (const char *query) { - int fd = -1; - int nread; + assuan_context_t ctx; char response[500]; int have = 0; int rc; - rc = agent_open (&fd); - if (rc) - goto leave; - - rc = writen (fd, query, strlen (query)); + rc = agent_open (&ctx); if (rc) - goto leave; - - while (1) - { - if (! have || ! strchr (response, '\n')) - /* get response */ - { - nread = readline (fd, &response[have], - sizeof (response) - 1 /* NUL */ - have); - if (nread < 0) - { - rc = -nread; - goto leave; - } - have += nread; - if (have < 3) - { - rc = SPWQ_PROTOCOL_ERROR; - goto leave; - } - response[have] = 0; - } - - if (response[0] == 'O' && response[1] == 'K') - /* OK, do nothing. */; - else if ((nread > 7 && !memcmp (response, "ERR 111", 7) - && (response[7] == ' ' || response[7] == '\n') ) - || ((nread > 4 && !memcmp (response, "ERR ", 4) - && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) - { - /* 111 is the old Assuan code for canceled which might still - be in use by old installations. 99 is GPG_ERR_CANCELED as - used by modern gpg-agents; 0xffff is used to mask out the - error source. */ -#ifdef SPWQ_USE_LOGGING - log_info (_("canceled by user\n") ); -#endif - } - else if (response[0] == 'S' && response[1] == ' ') - { - char *nextline; - int consumed; - - nextline = strchr (response, '\n'); - if (! nextline) - /* Point to the NUL. */ - nextline = &response[have]; - else - /* Move past the \n. */ - nextline ++; - - consumed = (size_t) nextline - (size_t) response; + return rc; - /* Skip any additional newlines. */ - while (consumed < have && response[consumed] == '\n') - consumed ++; + rc = assuan_transact (ctx, query, NULL, NULL, NULL, NULL, NULL, NULL); - have -= consumed; - - if (have) - memmove (response, &response[consumed], have + 1); - - continue; - } - else - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem with the agent (unexpected response \"%s\")\n"), - response); -#endif - rc = SPWQ_ERR_RESPONSE; - } - - break; - } - - leave: - if (fd != -1) - close (fd); + assuan_release (ctx); return rc; } diff --git a/tools/Makefile.am b/tools/Makefile.am index bc159d9..12e5815 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -113,7 +113,7 @@ gpgparsemail_LDADD = symcryptrun_SOURCES = symcryptrun.c symcryptrun_LDADD = $(LIBUTIL_LIBS) $(common_libs) $(pwquery_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) \ - $(LIBICONV) $(NETLIBS) $(W32SOCKLIBS) + $(LIBICONV) $(NETLIBS) $(W32SOCKLIBS) $(LIBASSUAN_LIBS) watchgnupg_SOURCES = watchgnupg.c watchgnupg_LDADD = $(NETLIBS) commit 9e6503b7ce019aa417099ded1dda87b68c33f912 Author: Justus Winter Date: Thu Aug 11 09:52:08 2016 +0200 common: Remove simple password query error codes. * common/simple-pwquery.h: Remove mapping function. Move all definitions of status codes... * common/simple-pwquery.c: ... here, and define them to meaningful gpg error values. * agent/preset-passphrase.c (preset_passphrase): Use error code as-is. (forget_passphrase): Likewise. * tools/symcryptrun.c (confucius_get_pass): Likewise. Signed-off-by: Justus Winter diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c index 549ecc3..485ca7b 100644 --- a/agent/preset-passphrase.c +++ b/agent/preset-passphrase.c @@ -111,10 +111,6 @@ my_strusage (int level) -/* Include the implementation of map_spwq_error. */ -MAP_SPWQ_ERROR_IMPL - - static void preset_passphrase (const char *keygrip) { @@ -170,7 +166,7 @@ preset_passphrase (const char *keygrip) if (!opt_passphrase) wipememory (passphrase, sizeof (passphrase)); - rc = map_spwq_error (simple_query (line)); + rc = simple_query (line); if (rc) { log_error ("caching passphrase failed: %s\n", gpg_strerror (rc)); @@ -192,7 +188,7 @@ forget_passphrase (const char *keygrip) if (rc < 0) rc = gpg_error_from_syserror (); else - rc = map_spwq_error (simple_query (line)); + rc = simple_query (line); if (rc) { log_error ("clearing passphrase failed: %s\n", gpg_strerror (rc)); diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 708b157..bd40fdf 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -50,6 +50,15 @@ #define SIMPLE_PWQUERY_IMPLEMENTATION 1 #include "simple-pwquery.h" +#define SPWQ_OUT_OF_CORE gpg_error_from_errno (ENOMEM) +#define SPWQ_IO_ERROR gpg_error_from_errno (EIO) +#define SPWQ_PROTOCOL_ERROR gpg_error (GPG_ERR_PROTOCOL_VIOLATION) +#define SPWQ_ERR_RESPONSE gpg_error (GPG_ERR_INV_RESPONSE) +#define SPWQ_NO_AGENT gpg_error (GPG_ERR_NO_AGENT) +#define SPWQ_SYS_ERROR gpg_error_from_syserror () +#define SPWQ_GENERAL_ERROR gpg_error (GPG_ERR_GENERAL) +#define SPWQ_NO_PIN_ENTRY gpg_error (GPG_ERR_NO_PIN_ENTRY) + #ifndef _ #define _(a) (a) #endif diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h index 5ae696a..2b87b11 100644 --- a/common/simple-pwquery.h +++ b/common/simple-pwquery.h @@ -67,47 +67,4 @@ int simple_query (const char *query); to be called before any other function. Returns 0 on success. */ int simple_pw_set_socket (const char *name); -#define SPWQ_OUT_OF_CORE 1 -#define SPWQ_IO_ERROR 2 -#define SPWQ_PROTOCOL_ERROR 3 -#define SPWQ_ERR_RESPONSE 4 -#define SPWQ_NO_AGENT 5 -#define SPWQ_SYS_ERROR 6 -#define SPWQ_GENERAL_ERROR 7 -#define SPWQ_NO_PIN_ENTRY 8 - - -/* We often need to map error codes to gpg-error style error codes. - To have a consistent mapping this macro may be used to implemt the - mapping function. */ -#define MAP_SPWQ_ERROR_IMPL \ - static gpg_error_t \ - map_spwq_error (int err) \ - { \ - switch (err) \ - { \ - case 0: \ - return 0; \ - case SPWQ_OUT_OF_CORE: \ - return gpg_error_from_errno (ENOMEM); \ - case SPWQ_IO_ERROR: \ - return gpg_error_from_errno (EIO); \ - case SPWQ_PROTOCOL_ERROR: \ - return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); \ - case SPWQ_ERR_RESPONSE: \ - return gpg_error (GPG_ERR_INV_RESPONSE); \ - case SPWQ_NO_AGENT: \ - return gpg_error (GPG_ERR_NO_AGENT); \ - case SPWQ_SYS_ERROR: \ - return gpg_error_from_syserror (); \ - case SPWQ_NO_PIN_ENTRY: \ - return gpg_error (GPG_ERR_NO_PIN_ENTRY); \ - case SPWQ_GENERAL_ERROR: \ - default: \ - return gpg_error (GPG_ERR_GENERAL); \ - } \ - } -/* End of MAP_SPWQ_ERROR_IMPL. */ - - #endif /*SIMPLE_PWQUERY_H*/ diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index 5c1f0da..b6dc843 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -238,9 +238,6 @@ my_strusage (int level) __result; })) #endif -/* Include the implementation of map_spwq_error. */ -MAP_SPWQ_ERROR_IMPL - /* Unlink a file, and shred it if SHRED is true. */ int remove_file (char *name, int shred) @@ -441,7 +438,6 @@ confucius_get_pass (const char *cacheid, int again, int *canceled) pw = simple_pwquery (cacheid, again ? _("does not match - try again"):NULL, _("Passphrase:"), NULL, 0, &err); - err = map_spwq_error (err); i18n_switchback (orig_codeset); if (!pw) ----------------------------------------------------------------------- Summary of changes: agent/Makefile.am | 2 +- agent/preset-passphrase.c | 8 +- common/Makefile.am | 2 +- common/simple-pwquery.c | 429 ++++++++++++---------------------------------- common/simple-pwquery.h | 43 ----- common/w32-afunix.c | 148 ---------------- common/w32-afunix.h | 63 ------- tools/Makefile.am | 2 +- tools/symcryptrun.c | 4 - 9 files changed, 115 insertions(+), 586 deletions(-) delete mode 100644 common/w32-afunix.c delete mode 100644 common/w32-afunix.h hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 11 15:48:21 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Aug 2016 15:48:21 +0200 Subject: [git] GpgEX - branch, master, updated. gpgex-1.0.4-4-g3dddfb2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnupG extension for the Windows Explorer". The branch, master has been updated via 3dddfb2546b839e104286767f504e456ae91df45 (commit) from 5c19ffe9d71d6e6763d6e47a67f1ca0a1651e39f (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 3dddfb2546b839e104286767f504e456ae91df45 Author: Andre Heinecke Date: Thu Aug 11 15:45:49 2016 +0200 Fix loop logic error in new server name detection * src/client.cc (default_uiserver_cmdline): Iterate over server_names array and not over the first server name itself. diff --git a/src/client.cc b/src/client.cc index 6f27175..ccfa0ac 100644 --- a/src/client.cc +++ b/src/client.cc @@ -108,7 +108,7 @@ default_uiserver_cmdline (void) } #else /*!ENABLE_GPA_ONLY*/ { - const char *dir, *tmp; + const char *dir, **tmp; char *uiserver, *p; int extra_arglen = 9; const char * server_names[] = {"kleopatra.exe", @@ -163,16 +163,16 @@ default_uiserver_cmdline (void) return name; } /* Fallbacks */ - for (tmp = *server_names; *tmp; tmp++) + for (tmp = server_names; *tmp; tmp++) { if (name) { free (name); } - name = (char*) malloc (strlen (dir) + strlen (tmp) + extra_arglen + 2); + name = (char*) malloc (strlen (dir) + strlen (*tmp) + extra_arglen + 2); if (!name) return NULL; - strcpy (stpcpy (stpcpy (name, dir), "\\"), tmp); + strcpy (stpcpy (stpcpy (name, dir), "\\"), *tmp); for (p = name; *p; p++) if (*p == '/') *p = '\\'; ----------------------------------------------------------------------- Summary of changes: src/client.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- GnupG extension for the Windows Explorer http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 11 16:00:29 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Aug 2016 16:00:29 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-1.4.0-4-gc8cdb4c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via c8cdb4c9a9bb590b8785b483cf71657e20e0b92d (commit) from 643575f38f545456afc456e1045b914d3d06bbb8 (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 c8cdb4c9a9bb590b8785b483cf71657e20e0b92d Author: Andre Heinecke Date: Thu Aug 11 15:59:57 2016 +0200 Fix loop logic error in new server name detection * src/engine-assuan.c (get_uiserver_name): Fix name loop. diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 32dbae8..c60713b 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -353,7 +353,7 @@ get_uiserver_name (void) "gpa.exe", "bin\\gpa.exe", NULL}; - const char *tmp = NULL; + const char **tmp = NULL; dir = get_gpg4win_dir (); if (!dir) @@ -384,14 +384,14 @@ get_uiserver_name (void) return name; } /* Fallbacks */ - for (tmp = *server_names; *tmp; tmp++) + for (tmp = server_names; *tmp; tmp++) { if (name) { xfree (name); } - name = xmalloc (strlen (dir) + strlen (tmp) + extra_arglen + 2); - strcpy (stpcpy (stpcpy (name, dir), "\\"), tmp); + name = xmalloc (strlen (dir) + strlen (*tmp) + extra_arglen + 2); + strcpy (stpcpy (stpcpy (name, dir), "\\"), *tmp); for (p = name; *p; p++) if (*p == '/') *p = '\\'; ----------------------------------------------------------------------- Summary of changes: src/engine-assuan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 11 18:00:17 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Aug 2016 18:00:17 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-280-g105f544 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 105f5446e69db00291164397cf0d8e68374cf420 (commit) via 59e2251a083b0ed61b3ab6d47015cef7cc6ceb05 (commit) via 8c5abc8d932affab4bc79a85e3f98f6f6b982ae8 (commit) from b7d99e02188b7907b09fec3032fc1fd82fc2668a (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 105f5446e69db00291164397cf0d8e68374cf420 Author: Andre Heinecke Date: Thu Aug 11 17:57:14 2016 +0200 Qt: Add DefaultKeyGenerationJob * lang/qt/src/defaultkeygenerationjob.cpp, lang/qt/src/defaultkeygenerationjob.h: New. * lang/qt/src/Makefile.am: Update accordingly. -- The defaultkeygenerationjob makes it easier to just generate a key in the future this should probably use quick-gen key but since this is not exposed in gpgme we hardcode the defaults and do it with the params file. This is also the first job that uses a new and better architecture without backend abstraction and the pimpl pattern instead of a specialized subclass. This is an adoption of kde's libkleo commit f49b7157 Thanks dvratil at kde.org diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 59d8abc..840557e 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -33,7 +33,8 @@ qgpgme_sources = \ qgpgmesecretkeyexportjob.cpp qgpgmesignencryptjob.cpp \ qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \ qgpgmeverifyopaquejob.cpp threadedjobmixin.cpp \ - qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp + qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp \ + defaultkeygenerationjob.cpp # If you add one here make sure that you also add one in camelcase qgpgme_headers= \ @@ -66,7 +67,8 @@ qgpgme_headers= \ keygenerationjob.h \ keylistjob.h \ listallkeysjob.h \ - verifydetachedjob.h + verifydetachedjob.h \ + defaultkeygenerationjob.h camelcase_headers= \ AddUserIDJob \ @@ -97,7 +99,8 @@ camelcase_headers= \ KeyListJob \ ListAllKeysJob \ VerifyDetachedJob \ - KeyForMailboxJob + KeyForMailboxJob \ + DefaultKeyGenerationJob private_qgpgme_headers = \ qgpgme_export.h \ @@ -180,7 +183,8 @@ qgpgme_moc_sources = \ verifydetachedjob.moc \ verifyopaquejob.moc \ keyformailboxjob.moc \ - qgpgmekeyformailboxjob.moc + qgpgmekeyformailboxjob.moc \ + defaultkeygenerationjob.moc qgpgmeincludedir = $(includedir)/qgpgme qgpgmeinclude_HEADERS = $(qgpgme_headers) diff --git a/lang/qt/src/defaultkeygenerationjob.cpp b/lang/qt/src/defaultkeygenerationjob.cpp new file mode 100644 index 0000000..727eabb --- /dev/null +++ b/lang/qt/src/defaultkeygenerationjob.cpp @@ -0,0 +1,123 @@ +/* defaultkeygenerationjob.cpp + + Copyright (c) 2016 Klar?lvdalens Datakonsult AB + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "defaultkeygenerationjob.h" +#include "protocol.h" +#include "keygenerationjob.h" + +#include +#include + +using namespace QGpgME; + +namespace QGpgME { + +class DefaultKeyGenerationJob::Private +{ +public: + Private() + {} + + ~Private() + { + if (job) { + job->deleteLater(); + } + } + + QPointer job; +}; +} + + +DefaultKeyGenerationJob::DefaultKeyGenerationJob(QObject* parent) + : Job(parent) + , d(new DefaultKeyGenerationJob::Private()) +{ +} + +DefaultKeyGenerationJob::~DefaultKeyGenerationJob() +{ + delete d; +} + +QString DefaultKeyGenerationJob::auditLogAsHtml() const +{ + return d->job ? d->job->auditLogAsHtml() : QString(); +} + +GpgME::Error DefaultKeyGenerationJob::auditLogError() const +{ + return d->job ? d->job->auditLogError() : GpgME::Error(); +} + +void DefaultKeyGenerationJob::slotCancel() +{ + if (d->job) { + d->job->slotCancel(); + } +} + +GpgME::Error DefaultKeyGenerationJob::start(const QString &email, const QString &name) +{ + const QString args = QStringLiteral("\n" + "%ask-passphrase\n" + "key-type: RSA\n" + "key-length: 2048\n" + "key-usage: sign\n" + "subkey-type: RSA\n" + "subkey-length: 2048\n" + "subkey-usage: encrypt\n" + "name-email: %1\n" + "name-real: %2\n" + "").arg(email, name); + + d->job = openpgp()->keyGenerationJob(); + d->job->installEventFilter(this); + connect(d->job, &KeyGenerationJob::result, + this, &DefaultKeyGenerationJob::result); + connect(d->job, &KeyGenerationJob::done, + this, &DefaultKeyGenerationJob::done); + connect(d->job, &KeyGenerationJob::done, + this, &QObject::deleteLater); + return d->job->start(args); +} + +bool DefaultKeyGenerationJob::eventFilter(QObject *watched, QEvent *event) +{ + // Intercept the KeyGenerationJob's deferred delete event. We want the job + // to live at least as long as we do so we can delegate calls to it. We will + // delete the job manually afterwards. + if (watched == d->job && event->type() == QEvent::DeferredDelete) { + return true; + } + + return Job::eventFilter(watched, event); +} diff --git a/lang/qt/src/defaultkeygenerationjob.h b/lang/qt/src/defaultkeygenerationjob.h new file mode 100644 index 0000000..5b7334c --- /dev/null +++ b/lang/qt/src/defaultkeygenerationjob.h @@ -0,0 +1,76 @@ +/* defaultkeygenerationjob.h + + Copyright (c) 2016 Klar?lvdalens Datakonsult AB + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ +#ifndef QGPGME_DEFAULTKEYGENERATION_H +#define QGPGME_DEFAULTKEYGENERATION_H + +#include "job.h" + +#include "qgpgme_export.h" + +namespace GpgME { +class KeyGenerationResult; +} + +namespace QGpgME{ + +/** + * Generates a PGP RSA/2048 bit key pair for given name and email address. + */ +class QGPGME_EXPORT DefaultKeyGenerationJob : public Job +{ + Q_OBJECT +public: + explicit DefaultKeyGenerationJob(QObject *parent = Q_NULLPTR); + ~DefaultKeyGenerationJob(); + + GpgME::Error start(const QString &email, const QString &name); + + QString auditLogAsHtml() const Q_DECL_OVERRIDE; + GpgME::Error auditLogError() const Q_DECL_OVERRIDE; + + +public Q_SLOTS: + void slotCancel() Q_DECL_OVERRIDE; + +Q_SIGNALS: + void result(const GpgME::KeyGenerationResult &result, const QByteArray &pubkeyData, + const QString &auditLogAsHtml, const GpgME::Error &auditLogError); + +protected: + bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; + +private: + class Private; + Private * const d; +}; + +} + +#endif commit 59e2251a083b0ed61b3ab6d47015cef7cc6ceb05 Author: Andre Heinecke Date: Thu Aug 11 17:38:36 2016 +0200 Qt: Ensure all public classes are exported * src/abstractimportjob.h, src/cryptoconfig.h, src/deletejob.h, src/exportjob.h, src/importfromkeyserverjob.h, src/importjob.h, src/keygenerationjob.h, src/keylistjob.h, src/listallkeysjob.h, src/refreshkeysjob.h, src/signencryptjob.h, src/specialjob.h, src/verifydetachedjob.h: Export classes. -- This is an adoption of kde's libkleo commit: d6a71a4e Thanks dvratil at kde.org diff --git a/lang/qt/src/abstractimportjob.h b/lang/qt/src/abstractimportjob.h index 33f6a2a..572f203 100644 --- a/lang/qt/src/abstractimportjob.h +++ b/lang/qt/src/abstractimportjob.h @@ -36,6 +36,8 @@ #include "job.h" +#include "qgpgme_export.h" + namespace GpgME { class Error; @@ -45,7 +47,7 @@ class ImportResult; namespace QGpgME { -class AbstractImportJob : public Job +class QGPGME_EXPORT AbstractImportJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/cryptoconfig.h b/lang/qt/src/cryptoconfig.h index 858dbb7..c3f0c7e 100644 --- a/lang/qt/src/cryptoconfig.h +++ b/lang/qt/src/cryptoconfig.h @@ -34,6 +34,7 @@ #ifndef CRYPTOCONFIG_H #define CRYPTOCONFIG_H +#include "qgpgme_export.h" #ifdef __cplusplus /* we read this file from a C compiler, and are only interested in the * enums... */ @@ -50,7 +51,7 @@ namespace QGpgME /** * Description of a single option */ -class CryptoConfigEntry +class QGPGME_EXPORT CryptoConfigEntry { public: @@ -252,7 +253,7 @@ public: /** * Group containing a set of config options */ -class CryptoConfigGroup +class QGPGME_EXPORT CryptoConfigGroup { public: @@ -301,7 +302,7 @@ public: /** * Crypto config for one component (e.g. gpg-agent, dirmngr etc.) */ -class CryptoConfigComponent +class QGPGME_EXPORT CryptoConfigComponent { public: @@ -341,7 +342,7 @@ public: /** * Main interface to crypto configuration. */ -class CryptoConfig +class QGPGME_EXPORT CryptoConfig { public: diff --git a/lang/qt/src/deletejob.h b/lang/qt/src/deletejob.h index 1f4e8cf..f8479b1 100644 --- a/lang/qt/src/deletejob.h +++ b/lang/qt/src/deletejob.h @@ -34,6 +34,7 @@ #ifndef __KLEO_DELETEJOB_H__ #define __KLEO_DELETEJOB_H__ +#include "qgpgme_export.h" #include "job.h" namespace GpgME @@ -58,7 +59,7 @@ namespace QGpgME After result() is emitted, the DeleteJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class DeleteJob : public Job +class QGPGME_EXPORT DeleteJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/exportjob.h b/lang/qt/src/exportjob.h index df21f03..583d4c0 100644 --- a/lang/qt/src/exportjob.h +++ b/lang/qt/src/exportjob.h @@ -34,6 +34,7 @@ #ifndef __QGPGME_EXPORTJOB_H__ #define __QGPGME_EXPORTJOB_H__ +#include "qgpgme_export.h" #include "job.h" #include @@ -61,7 +62,7 @@ namespace QGpgME After result() is emitted, the ExportJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class ExportJob : public Job +class QGPGME_EXPORT ExportJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/importfromkeyserverjob.h b/lang/qt/src/importfromkeyserverjob.h index 7ab13cb..f548ea7 100644 --- a/lang/qt/src/importfromkeyserverjob.h +++ b/lang/qt/src/importfromkeyserverjob.h @@ -35,6 +35,7 @@ #define __KLEO_IMPORTFROMKEYSERVERJOB_H__ #include "abstractimportjob.h" +#include "qgpgme_export.h" namespace GpgME { @@ -61,7 +62,7 @@ namespace QGpgME After result() is emitted, the ImportJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class ImportFromKeyserverJob : public AbstractImportJob +class QGPGME_EXPORT ImportFromKeyserverJob : public AbstractImportJob { Q_OBJECT protected: diff --git a/lang/qt/src/importjob.h b/lang/qt/src/importjob.h index d9f60d1..5c7b24d 100644 --- a/lang/qt/src/importjob.h +++ b/lang/qt/src/importjob.h @@ -35,6 +35,7 @@ #define __KLEO_IMPORTJOB_H__ #include "abstractimportjob.h" +#include "qgpgme_export.h" #include @@ -60,7 +61,7 @@ namespace QGpgME After result() is emitted, the ImportJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class ImportJob : public AbstractImportJob +class QGPGME_EXPORT ImportJob : public AbstractImportJob { Q_OBJECT protected: diff --git a/lang/qt/src/keygenerationjob.h b/lang/qt/src/keygenerationjob.h index 90f29bf..a0beeac 100644 --- a/lang/qt/src/keygenerationjob.h +++ b/lang/qt/src/keygenerationjob.h @@ -35,6 +35,7 @@ #define __KLEO_KEYGENERATIONJOB_H__ #include "job.h" +#include "qgpgme_export.h" #include @@ -60,7 +61,7 @@ namespace QGpgME After result() is emitted, the KeyGenerationJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class KeyGenerationJob : public Job +class QGPGME_EXPORT KeyGenerationJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/keylistjob.h b/lang/qt/src/keylistjob.h index 6e62c4f..fc7a048 100644 --- a/lang/qt/src/keylistjob.h +++ b/lang/qt/src/keylistjob.h @@ -35,6 +35,7 @@ #define __KLEO_KEYLISTJOB_H__ #include "job.h" +#include "qgpgme_export.h" #ifdef BUILDING_QGPGME # include "key.h" @@ -70,7 +71,7 @@ namespace QGpgME KeyListJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class KeyListJob : public Job +class QGPGME_EXPORT KeyListJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/listallkeysjob.h b/lang/qt/src/listallkeysjob.h index 9d4711d..4fbb469 100644 --- a/lang/qt/src/listallkeysjob.h +++ b/lang/qt/src/listallkeysjob.h @@ -35,6 +35,7 @@ #define __KLEO_LISTALLKEYSJOB_H__ #include "job.h" +#include "qgpgme_export.h" #ifdef BUILDING_QGPGME # include "key.h" @@ -69,7 +70,7 @@ namespace QGpgME This is potentially much faster than a KeyListJob with empty pattern. */ -class ListAllKeysJob : public Job +class QGPGME_EXPORT ListAllKeysJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/refreshkeysjob.h b/lang/qt/src/refreshkeysjob.h index d0bc51f..a97de80 100644 --- a/lang/qt/src/refreshkeysjob.h +++ b/lang/qt/src/refreshkeysjob.h @@ -35,6 +35,7 @@ #define __KLEO_REFRESHKEYSJOB_H__ #include "job.h" +#include "qgpgme_export.h" #include @@ -62,7 +63,7 @@ namespace QGpgME After result() is emitted, the KeyListJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class RefreshKeysJob : public Job +class QGPGME_EXPORT RefreshKeysJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/signencryptjob.h b/lang/qt/src/signencryptjob.h index b0aafe3..4e07744 100644 --- a/lang/qt/src/signencryptjob.h +++ b/lang/qt/src/signencryptjob.h @@ -35,6 +35,7 @@ #define __KLEO_SIGNENCRYPTJOB_H__ #include "job.h" +#include "qgpgme_export.h" #ifdef BUILDING_QGPGME # include "global.h" @@ -75,7 +76,7 @@ namespace QGpgME After result() is emitted, the SignEncryptJob will schedule it's own destruction by calling QObject::deleteLater(). */ -class SignEncryptJob : public Job +class QGPGME_EXPORT SignEncryptJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/specialjob.h b/lang/qt/src/specialjob.h index 788371e..2c80f20 100644 --- a/lang/qt/src/specialjob.h +++ b/lang/qt/src/specialjob.h @@ -35,6 +35,7 @@ #define __KLEO_SPECIALJOB_H__ #include "job.h" +#include "qgpgme_export.h" namespace GpgME { @@ -65,7 +66,7 @@ namespace QGpgME through the read-only result property, the latter of which needs to be defined in each SpecialJob subclass. */ -class SpecialJob : public Job +class QGPGME_EXPORT SpecialJob : public Job { Q_OBJECT protected: diff --git a/lang/qt/src/verifydetachedjob.h b/lang/qt/src/verifydetachedjob.h index 0cb92e6..b339a8c 100644 --- a/lang/qt/src/verifydetachedjob.h +++ b/lang/qt/src/verifydetachedjob.h @@ -35,6 +35,7 @@ #define __KLEO_VERIFYDETACHEDJOB_H__ #include "job.h" +#include "qgpgme_export.h" #include commit 8c5abc8d932affab4bc79a85e3f98f6f6b982ae8 Author: Andre Heinecke Date: Thu Aug 11 17:22:35 2016 +0200 Qt: Add KeyForMailboxJob * lang/qt/src/job.cpp: Include moc and make subclass. * lang/qt/src/keyformailboxjob.h, lang/qt/src/qgpgmekeyformailboxjob.cpp, lang/qt/src/qgpgmekeyformailboxjob.h: New. * lang/qt/tests/run-keyformailboxjob.cpp: New manual test. * lang/qt/tests/Makefile.am: Add run-keyformailboxjob. * lang/qt/src/Makefile.am: Update accordingly. * lang/qt/src/protocol.h, lang/qt/src/protocol_p.h: Add keyformailboxjob. -- The KeyForMailboxjob can be used to determine the best key to use to encrypt something to a given mail address. diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index ae316ba..59d8abc 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -33,7 +33,7 @@ qgpgme_sources = \ qgpgmesecretkeyexportjob.cpp qgpgmesignencryptjob.cpp \ qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \ qgpgmeverifyopaquejob.cpp threadedjobmixin.cpp \ - gpgme_backend_debug.cpp + qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp # If you add one here make sure that you also add one in camelcase qgpgme_headers= \ @@ -49,6 +49,7 @@ qgpgme_headers= \ exportjob.h \ hierarchicalkeylistjob.h \ job.h \ + keyformailboxjob.h \ multideletejob.h \ protocol.h \ qgpgme_export.h \ @@ -95,7 +96,8 @@ camelcase_headers= \ KeyGenerationJob \ KeyListJob \ ListAllKeysJob \ - VerifyDetachedJob + VerifyDetachedJob \ + KeyForMailboxJob private_qgpgme_headers = \ qgpgme_export.h \ @@ -124,6 +126,7 @@ private_qgpgme_headers = \ qgpgmesignkeyjob.h \ qgpgmeverifydetachedjob.h \ qgpgmeverifyopaquejob.h \ + qgpgmekeyformailboxjob.h \ specialjob.h \ threadedjobmixin.h @@ -175,7 +178,9 @@ qgpgme_moc_sources = \ signkeyjob.moc \ specialjob.moc \ verifydetachedjob.moc \ - verifyopaquejob.moc + verifyopaquejob.moc \ + keyformailboxjob.moc \ + qgpgmekeyformailboxjob.moc qgpgmeincludedir = $(includedir)/qgpgme qgpgmeinclude_HEADERS = $(qgpgme_headers) diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp index 7ca1df9..8e50647 100644 --- a/lang/qt/src/job.cpp +++ b/lang/qt/src/job.cpp @@ -55,6 +55,7 @@ #include "refreshkeysjob.h" #include "adduseridjob.h" #include "specialjob.h" +#include "keyformailboxjob.h" #include #include @@ -120,6 +121,7 @@ make_job_subclass(DeleteJob) make_job_subclass(RefreshKeysJob) make_job_subclass(AddUserIDJob) make_job_subclass(SpecialJob) +make_job_subclass(KeyForMailboxJob) #undef make_job_subclass @@ -148,3 +150,4 @@ make_job_subclass(SpecialJob) #include "refreshkeysjob.moc" #include "adduseridjob.moc" #include "specialjob.moc" +#include "keyformailboxjob.moc" diff --git a/lang/qt/src/keyformailboxjob.h b/lang/qt/src/keyformailboxjob.h new file mode 100644 index 0000000..9e76df5 --- /dev/null +++ b/lang/qt/src/keyformailboxjob.h @@ -0,0 +1,101 @@ +/* + keyformailboxjob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ +#ifndef __KLEO_KEYFORMAILBOX_H__ +#define __KLEO_KEYFORMAILBOX_H__ + +#include + +#include "job.h" + +#include +namespace GpgME +{ +class Error; +class KeyListResult; +} + +namespace QGpgME +{ + +/** + @short Get the best key to use for a Mailbox + + To use the keyformailboxjob, first obtain an instance from the + CryptoBackend and either exec it or start and + conncet the result() signals to a suitable slot. + The job will be automatically deleted in which + case the KeylistJob instance will have schedules it's own + destruction with a call to QObject::deleteLater(). + + The best key is defined as the key with a UID that has an + E-Mail that matches the mailbox provided. If multiple + keys are found the one with the highest validity is returned. + + After result() is emitted, the + KeyListJob will schedule it's own destruction by calling + QObject::deleteLater(). +*/ +class QGPGME_EXPORT KeyForMailboxJob: public Job +{ + Q_OBJECT +protected: + explicit KeyForMailboxJob(QObject *parent); + +public: + ~KeyForMailboxJob(); + + /** + Starts the operation. \a mailbox is the mailbox to + look for. + + The result is the same as for the LocateKeysJob. + + If \a canEncrypt is true, only keys that have a subkey for encryption + usage are returned. Use this if you need to select a + key for signing. + */ + virtual GpgME::Error start(const QString &mailbox, bool canEncrypt = true) = 0; + + virtual GpgME::KeyListResult exec(const QString &mailbox, bool canEncrypt, GpgME::Key &key, GpgME::UserID &uid) = 0; + +Q_SIGNALS: + /** The result. \a Key is the key found or a Null key. + * + * The userid is the uid where the mailbox matches. + * + * The auditlog params are always null / empty. + */ + void result(const GpgME::KeyListResult &result, const GpgME::Key &key, const GpgME::UserID &uid, const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error()); +}; + +} +#endif diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index 64146b8..23b9d93 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -62,6 +62,7 @@ class ChangeOwnerTrustJob; class ChangePasswdJob; class AddUserIDJob; class SpecialJob; +class KeyForMailboxJob; /** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors. * @@ -145,6 +146,8 @@ public: * with both includeSigs and validate options. */ virtual KeyListJob *locateKeysJob() const = 0; + /** Find the best key to use for a mailbox. */ + virtual KeyForMailboxJob *keyForMailboxJob() const = 0; }; /** Obtain a reference to the OpenPGP Protocol. diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index 9fcbc8b..afb4f9c 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -56,6 +56,7 @@ #include "qgpgmechangeownertrustjob.h" #include "qgpgmechangepasswdjob.h" #include "qgpgmeadduseridjob.h" +#include "qgpgmekeyformailboxjob.h" namespace { @@ -377,6 +378,15 @@ public: context->setKeyListMode(GpgME::Extern | GpgME::Local | GpgME::Signatures | GpgME::Validate); return new QGpgME::QGpgMEKeyListJob(context); } + + QGpgME::KeyForMailboxJob *keyForMailboxJob() const Q_DECL_OVERRIDE + { + GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); + if (!context) { + return Q_NULLPTR; + } + return new QGpgME::QGpgMEKeyForMailboxJob(context); + } }; } diff --git a/lang/qt/src/qgpgmekeyformailboxjob.cpp b/lang/qt/src/qgpgmekeyformailboxjob.cpp new file mode 100644 index 0000000..0702a36 --- /dev/null +++ b/lang/qt/src/qgpgmekeyformailboxjob.cpp @@ -0,0 +1,136 @@ +/* + qgpgmekeyformailboxjob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "qgpgmekeyformailboxjob.h" +#include "qgpgmekeylistjob.h" + +#include + +using namespace GpgME; +using namespace QGpgME; + +QGpgMEKeyForMailboxJob::QGpgMEKeyForMailboxJob(Context *context) + : mixin_type(context) +{ + lateInitialization(); +} + +QGpgMEKeyForMailboxJob::~QGpgMEKeyForMailboxJob() {} + +static bool keyIsOk(const Key k) +{ + return !k.isExpired() && !k.isRevoked() && !k.isInvalid() && !k.isDisabled(); +} + +static bool uidIsOk(const UserID uid) +{ + return keyIsOk(uid.parent()) && !uid.isRevoked() && !uid.isInvalid(); +} + +static bool subkeyIsOk(const Subkey s) +{ + return !s.isRevoked() && !s.isInvalid() && !s.isDisabled(); +} + +static QGpgMEKeyForMailboxJob::result_type do_work(Context *ctx, const QString &mailbox, bool canEncrypt) +{ + /* Do a Keylisting. */ + ctx->setKeyListMode(GpgME::Extern | GpgME::Local | GpgME::Signatures | GpgME::Validate); + std::vector keys; + QGpgMEKeyListJob *keylist = new QGpgMEKeyListJob(ctx); + + KeyListResult result = keylist->exec(QStringList() << mailbox, false, keys); + + if (result.error()) { + return std::make_tuple(result, Key(), UserID(), QString(), Error()); + } + + // This should ideally be decided by GnuPG and this Job changed + // to just call the according API in GpgME + // See: https://bugs.gnupg.org/gnupg/issue2359 + Key keyC; + UserID uidC; + Q_FOREACH (const Key k, keys) { + if (canEncrypt && !k.canEncrypt()) { + continue; + } + /* First get the uid that matches the mailbox */ + Q_FOREACH (const UserID u, k.userIDs()) { + if (QString::fromUtf8(u.email()).toLower() == mailbox.toLower()) { + if (uidC.isNull()) { + keyC = k; + uidC = u; + } else if ((!uidIsOk(uidC) && uidIsOk(u)) || uidC.validity() < u.validity()) { + /* Validity of the new key is better. */ + uidC = u; + keyC = k; + } else if (uidC.validity() == u.validity() && uidIsOk(u)) { + /* Both are the same check which one is newer. */ + time_t oldTime = 0; + Q_FOREACH (const Subkey s, keyC.subkeys()) { + if ((canEncrypt && s.canEncrypt()) && subkeyIsOk(s)) { + oldTime = s.creationTime(); + } + } + time_t newTime = 0; + Q_FOREACH (const Subkey s, k.subkeys()) { + if ((canEncrypt && s.canEncrypt()) && subkeyIsOk(s)) { + newTime = s.creationTime(); + } + } + if (newTime > oldTime) { + uidC = u; + keyC = k; + } + } + } + } + } + return std::make_tuple(result, keyC, uidC, QString(), Error()); +} + +Error QGpgMEKeyForMailboxJob::start(const QString &mailbox, bool canEncrypt) +{ + run(std::bind(&do_work, std::placeholders::_1, mailbox, canEncrypt)); + return Error(); +} + +KeyListResult QGpgMEKeyForMailboxJob::exec(const QString &mailbox, bool canEncrypt, Key &key, UserID &uid) +{ + const result_type r = do_work(context(), mailbox, canEncrypt); + resultHook(r); + key = std::get<1>(r); + uid = std::get<2>(r); + return std::get<0>(r); +} + +#include "qgpgmekeyformailboxjob.moc" diff --git a/lang/qt/src/qgpgmekeyformailboxjob.h b/lang/qt/src/qgpgmekeyformailboxjob.h new file mode 100644 index 0000000..02a16d3 --- /dev/null +++ b/lang/qt/src/qgpgmekeyformailboxjob.h @@ -0,0 +1,79 @@ +/* + qgpgmekeyformailboxjob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004,2008 Klar?lvdalens Datakonsult AB + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __QGPGME_QGPGMEKEYFORMAILBOXJOB_H__ +#define __QGPGME_QGPGMEKEYFORMAILBOXJOB_H__ +#include "keyformailboxjob.h" + +#include "threadedjobmixin.h" + +#include +#include + +namespace QGpgME +{ + +class QGpgMEKeyForMailboxJob +#ifdef Q_MOC_RUN + : public KeyForMailboxJob +#else + : public _detail::ThreadedJobMixin > +#endif +{ + Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: + void slotFinished(); +#endif +public: + explicit QGpgMEKeyForMailboxJob(GpgME::Context *context); + ~QGpgMEKeyForMailboxJob(); + + /** + Starts the operation. \a mailbox is the mailbox to + look for. + + The result is the same as for the LocateKeysJob. + + If \a canEncrypt is true, only keys that have a subkey for encryption + usage are returned. Use this if you need to select a + key for signing. + */ + GpgME::Error start(const QString &mailbox, bool canEncrypt = true) Q_DECL_OVERRIDE; + + GpgME::KeyListResult exec(const QString &mailbox, bool canEncrypt, GpgME::Key &key, GpgME::UserID &uid) Q_DECL_OVERRIDE; +}; + +} +#endif diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 13495a8..85f6fa6 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -55,12 +55,14 @@ t_keylocate_SOURCES = t-keylocate.cpp $(support_src) t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src) t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src) t_encrypt_SOURCES = t-encrypt.cpp $(support_src) +run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp nodist_t_keylist_SOURCES = $(moc_files) BUILT_SOURCES = $(moc_files) -noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt +noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ + run-keyformailboxjob CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \ diff --git a/lang/qt/tests/run-keyformailboxjob.cpp b/lang/qt/tests/run-keyformailboxjob.cpp new file mode 100644 index 0000000..9ac7668 --- /dev/null +++ b/lang/qt/tests/run-keyformailboxjob.cpp @@ -0,0 +1,56 @@ +/* + run-keyformailbox.cpp + + This file is part of QGpgME's test suite. + Copyright (c) 2016 Intevation GmbH + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "keyformailboxjob.h" +#include "keylistjob.h" +#include "protocol.h" + +#include "key.h" +#include "keylistresult.h" + +#include + + +int main(int argc, char **argv) +{ + QString mailbox; + if (argc == 2) { + mailbox = QString::fromLocal8Bit(argv[1]); + } + + auto job = QGpgME::openpgp()->keyForMailboxJob(); + GpgME::Key k; + GpgME::UserID uid; + job->exec(mailbox, true, k, uid); + qDebug() << "UID Name: " << uid.name() << " Mail: " << uid.email() << " id: " << uid.id(); + qDebug() << "Key fpr: " << k.primaryFingerprint(); + return 0; +} ----------------------------------------------------------------------- Summary of changes: lang/qt/src/Makefile.am | 17 ++- lang/qt/src/abstractimportjob.h | 4 +- lang/qt/src/cryptoconfig.h | 9 +- lang/qt/src/defaultkeygenerationjob.cpp | 123 +++++++++++++++++++ ...pgmedeletejob.cpp => defaultkeygenerationjob.h} | 67 +++++----- lang/qt/src/deletejob.h | 3 +- lang/qt/src/exportjob.h | 3 +- lang/qt/src/importfromkeyserverjob.h | 3 +- lang/qt/src/importjob.h | 3 +- lang/qt/src/job.cpp | 3 + lang/qt/src/{keylistjob.h => keyformailboxjob.h} | 74 ++++++----- lang/qt/src/keygenerationjob.h | 3 +- lang/qt/src/keylistjob.h | 3 +- lang/qt/src/listallkeysjob.h | 3 +- lang/qt/src/protocol.h | 3 + lang/qt/src/protocol_p.h | 10 ++ lang/qt/src/qgpgmekeyformailboxjob.cpp | 136 +++++++++++++++++++++ ...qgpgmekeylistjob.h => qgpgmekeyformailboxjob.h} | 52 ++++---- lang/qt/src/refreshkeysjob.h | 3 +- lang/qt/src/signencryptjob.h | 3 +- lang/qt/src/specialjob.h | 3 +- lang/qt/src/verifydetachedjob.h | 1 + lang/qt/tests/Makefile.am | 4 +- .../run-keyformailboxjob.cpp} | 52 ++++---- 24 files changed, 439 insertions(+), 146 deletions(-) create mode 100644 lang/qt/src/defaultkeygenerationjob.cpp copy lang/qt/src/{qgpgmedeletejob.cpp => defaultkeygenerationjob.h} (55%) copy lang/qt/src/{keylistjob.h => keyformailboxjob.h} (50%) create mode 100644 lang/qt/src/qgpgmekeyformailboxjob.cpp copy lang/qt/src/{qgpgmekeylistjob.h => qgpgmekeyformailboxjob.h} (63%) copy lang/qt/{src/abstractimportjob.h => tests/run-keyformailboxjob.cpp} (59%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 11 21:36:54 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 11 Aug 2016 21:36:54 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-74-g70b5d7c 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 70b5d7c43a57a44dad60c2c700a263610748d8f4 (commit) via 0698324cde3e0cef7eeb6cfd1640c5eefdf13698 (commit) from 72fa314b71e4ce8780f59b16d32cabf5d4bd5451 (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 70b5d7c43a57a44dad60c2c700a263610748d8f4 Author: Werner Koch Date: Thu Aug 11 21:31:12 2016 +0200 gpg: New option --input-size-hint. * g10/options.h: Include stdint.h. (struct opt): Add field 'input_size_hint'. * g10/gpg.c (oInputSizeHint): New. (opts): Add --input-size-hint. (main): Set opt.input_size_hint. * g10/progress.c (write_status_progress): Use the hint. -- This is a prerequisite to fix GnuPG-bug-id: 2368 Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 944734b..894d384 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2155,6 +2155,15 @@ works properly with such messages, there is often a desire to set a maximum file size that will be generated before processing is forced to stop by the OS limits. Defaults to 0, which means "no limit". + at item --input-size-hint @var{n} + at opindex input-size-hint +This option can be used to tell GPG the size of the input data in +bytes. @var{n} must be a positive base-10 number. This option is +only useful if the input is not taken from a file. GPG may use thos +hint to optimize its buffer allocation strategy. It is also used by +the @option{--status-fd} line ``PROGRESS'' to provide a value for +``total'' if that is not available by other means. + @item --import-options @code{parameters} @opindex import-options This is a space or comma delimited string that gives options for diff --git a/g10/gpg.c b/g10/gpg.c index adc32f0..fd21fde 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -99,6 +99,7 @@ enum cmd_and_opt_values aListSecretKeys = 'K', oBatch = 500, oMaxOutput, + oInputSizeHint, oSigNotation, oCertNotation, oShowNotation, @@ -554,6 +555,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")), ARGPARSE_p_u (oMaxOutput, "max-output", "@"), + ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"), ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), ARGPARSE_s_n (oQuiet, "quiet", "@"), @@ -2459,7 +2461,13 @@ main (int argc, char **argv) case oArmor: opt.armor = 1; opt.no_armor=0; break; case oOutput: opt.outfile = pargs.r.ret_str; break; + case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break; + + case oInputSizeHint: + opt.input_size_hint = string_to_u64 (pargs.r.ret_str); + break; + case oQuiet: opt.quiet = 1; break; case oNoTTY: tty_no_terminal(1); break; case oDryRun: opt.dry_run = 1; break; diff --git a/g10/options.h b/g10/options.h index d1c3634..230c96a 100644 --- a/g10/options.h +++ b/g10/options.h @@ -23,6 +23,7 @@ #include #include +#include #include "main.h" #include "packet.h" #include "tofu.h" @@ -54,6 +55,12 @@ struct char *outfile; estream_t outfp; /* Hack, sometimes used in place of outfile. */ off_t max_output; + + /* If > 0 a hint with the expected number of input data bytes. This + * is not necessary an exact number but intended to be used for + * progress info and to decide on how to allocate buffers. */ + uint64_t input_size_hint; + int dry_run; int autostart; int list_only; diff --git a/g10/progress.c b/g10/progress.c index efc3b3a..f151657 100644 --- a/g10/progress.c +++ b/g10/progress.c @@ -73,11 +73,12 @@ release_progress_context (progress_filter_context_t *pfx) static void write_status_progress (const char *what, - unsigned long current, unsigned long total) + unsigned long current, unsigned long total_arg) { char buffer[60]; char units[] = "BKMGTPEZY?"; int unitidx = 0; + uint64_t total = total_arg; /* Although we use an unsigned long for the values, 32 bit * applications using GPGME will use an "int" and thus are limited @@ -91,6 +92,10 @@ write_status_progress (const char *what, * thus scaling CURRENT and TOTAL down before they get to large, * should not have a noticeable effect except for rounding * imprecision. */ + + if (!total && opt.input_size_hint) + total = opt.input_size_hint; + if (total) { if (current > total) @@ -116,7 +121,7 @@ write_status_progress (const char *what, unitidx = 9; snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu %c%s", - what? what : "?", current, total, + what? what : "?", current, (unsigned long)total, units[unitidx], unitidx? "iB" : ""); write_status_text (STATUS_PROGRESS, buffer); commit 0698324cde3e0cef7eeb6cfd1640c5eefdf13698 Author: Werner Koch Date: Thu Aug 11 20:46:51 2016 +0200 common: New function string_to_u64. * common/stringhelp.c (string_to_u64): New. * dirmngr/http.c (longcounter_t): Remove. (struct cookie_s): Change content_length to uint64_t. (parse_response): Use string_to_u64. -- Meanwhile we allow some C99 features including stdint.h. Thus we can simplify things now. Signed-off-by: Werner Koch diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index b1b56f3..943f20a 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -36,9 +36,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include diff --git a/common/stringhelp.c b/common/stringhelp.c index 990fc35..b5d9f4c 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -58,6 +58,7 @@ #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a')) + /* Sometimes we want to avoid mixing slashes and backslashes on W32 and prefer backslashes. There is usual no problem with mixing them, however a very few W32 API calls can't grok plain slashes. @@ -660,6 +661,25 @@ compare_filenames (const char *a, const char *b) } +/* Convert a base-10 number in STRING into a 64 bit unsigned int + * value. Leading white spaces are skipped but no error checking is + * done. Thus it is similar to atoi(). */ +uint64_t +string_to_u64 (const char *string) +{ + uint64_t val = 0; + + while (spacep (string)) + string++; + for (; digitp (string); string++) + { + val *= 10; + val += *string - '0'; + } + return val; +} + + /* Convert 2 hex characters at S to a byte value. Return this value or -1 if there is an error. */ int diff --git a/common/stringhelp.h b/common/stringhelp.h index adf2f20..79d2284 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -33,6 +33,7 @@ #ifndef GNUPG_COMMON_STRINGHELP_H #define GNUPG_COMMON_STRINGHELP_H +#include #include "types.h" /*-- stringhelp.c --*/ @@ -59,6 +60,7 @@ char *make_absfilename_try (const char *first_part, ...) GPGRT_ATTR_SENTINEL(0); int compare_filenames( const char *a, const char *b ); +uint64_t string_to_u64 (const char *string); int hextobyte (const char *s); size_t utf8_charcount (const char *s, int len); diff --git a/dirmngr/http.c b/dirmngr/http.c index a512e9a..ac8238c 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -130,15 +130,6 @@ "01234567890@" \ "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~" -/* A long counter type. */ -#ifdef HAVE_STRTOULL -typedef unsigned long long longcounter_t; -# define counter_strtoul(a) strtoull ((a), NULL, 10) -#else -typedef unsigned long longcounter_t; -# define counter_strtoul(a) strtoul ((a), NULL, 10) -#endif - #if HTTP_USE_NTBTLS typedef ntbtls_t tls_session_t; # define USE_TLS 1 @@ -206,7 +197,7 @@ struct cookie_s /* The remaining content length and a flag telling whether to use the content length. */ - longcounter_t content_length; + uint64_t content_length; unsigned int content_length_valid:1; }; typedef struct cookie_s *cookie_t; @@ -2170,7 +2161,7 @@ parse_response (http_t hd) if (s) { cookie->content_length_valid = 1; - cookie->content_length = counter_strtoul (s); + cookie->content_length = string_to_u64 (s); } } ----------------------------------------------------------------------- Summary of changes: common/exechelp-posix.c | 4 +--- common/stringhelp.c | 20 ++++++++++++++++++++ common/stringhelp.h | 2 ++ dirmngr/http.c | 13 ++----------- doc/gpg.texi | 9 +++++++++ g10/gpg.c | 8 ++++++++ g10/options.h | 7 +++++++ g10/progress.c | 9 +++++++-- 8 files changed, 56 insertions(+), 16 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 08:18:27 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Aug 2016 08:18:27 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-281-g75c974c 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 75c974c4e0a31981325f7d151bd13f2523f5df20 (commit) from 105f5446e69db00291164397cf0d8e68374cf420 (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 75c974c4e0a31981325f7d151bd13f2523f5df20 Author: Andre Heinecke Date: Fri Aug 12 08:17:18 2016 +0200 Qt: Fix defaultkeygenerationjob build * lang/qt/src/defaultkeygenerationjob.cpp: Include moc. diff --git a/lang/qt/src/defaultkeygenerationjob.cpp b/lang/qt/src/defaultkeygenerationjob.cpp index 727eabb..8257a72 100644 --- a/lang/qt/src/defaultkeygenerationjob.cpp +++ b/lang/qt/src/defaultkeygenerationjob.cpp @@ -121,3 +121,5 @@ bool DefaultKeyGenerationJob::eventFilter(QObject *watched, QEvent *event) return Job::eventFilter(watched, event); } + +#include "defaultkeygenerationjob.moc" ----------------------------------------------------------------------- Summary of changes: lang/qt/src/defaultkeygenerationjob.cpp | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 09:30:59 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Aug 2016 09:30:59 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-24-gc71ba9a 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 c71ba9a57c0a4e3f919d90ea181ba7313d9533aa (commit) via fa97de673bd36758ae4ce151923435318f7c8877 (commit) from 2227f67af53f38d3d7f97760f2553d2c9ed05969 (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 c71ba9a57c0a4e3f919d90ea181ba7313d9533aa Author: Andre Heinecke Date: Wed Jun 1 15:15:41 2016 +0200 Update NEWS -- diff --git a/NEWS b/NEWS index 6241a62..4278865 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,24 @@ Noteworthy changes in version 0.9.8 (unreleased) ------------------------------------------------ + * Qt pinentry now supports repeat mode in one dialog. + + * Qt and GTK pinentries now make it possible to show the + entered value. + + * Qt pinentry now only grabs the keyboard if an entry field + is focused. + + * Fixed foreground handling in pinentry-qt if compiled + with Qt5 for Windows. + + * Fixed error output for cached passwords. + + * Fixed potential crash in Qt qualitybar calculation. + + * GTK keyboard grabbing is now a bit more robust. + + Noteworthy changes in version 0.9.7 (2015-12-07) ------------------------------------------------ commit fa97de673bd36758ae4ce151923435318f7c8877 Author: Kristian Fiskerstrand Date: Thu Aug 11 14:44:37 2016 +0200 Qt: Append -std=c++11 if building against Qt 5.7 * m4/qt.m4: Append -std=c++11 to CFLAGS if building against Qt 5.7 -- Qt 5.7 enables C++11 for Qt modules, and any app relying on it require to be compiled with at least this standard. This patch adds detection for Qt 5.7 and make sure -std=c++11 is passed if building against Qt 5.7 or higher. diff --git a/m4/qt.m4 b/m4/qt.m4 index 093f428..90c4a6e 100644 --- a/m4/qt.m4 +++ b/m4/qt.m4 @@ -35,6 +35,7 @@ AC_DEFUN([FIND_QT], enable_pinentry_qt5="try") have_qt5_libs="no"; + require_qt_cpp11="no"; if test "$enable_pinentry_qt5" != "no"; then PKG_CHECK_MODULES(PINENTRY_QT, @@ -47,6 +48,15 @@ AC_DEFUN([FIND_QT], fi fi if test "$have_qt5_libs" = "yes"; then + PKG_CHECK_MODULES(PINENTRY_QT_REQUIRE_CPP11, + Qt5Core >= 5.7.0, + [require_qt_cpp11="yes"], + [require_qt_cpp11="no"]) + + if test "${require_qt_cpp11}" = "yes"; then + PINENTRY_QT_CFLAGS="$PINENTRY_QT_CFLAGS -std=c++11" + fi + AC_CHECK_TOOL(MOC, moc) AC_MSG_CHECKING([moc version]) mocversion=`$MOC -v 2>&1` ----------------------------------------------------------------------- Summary of changes: NEWS | 18 ++++++++++++++++++ m4/qt.m4 | 10 ++++++++++ 2 files changed, 28 insertions(+) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 12:21:16 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Fri, 12 Aug 2016 12:21:16 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-76-g3a75ff6 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 3a75ff65fba24ea2d024bd8fef633ab7d8f7d520 (commit) via 61c2a1fa6d6cb345f9d81f4bdd3f8f8ddac1ea3e (commit) from 70b5d7c43a57a44dad60c2c700a263610748d8f4 (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 3a75ff65fba24ea2d024bd8fef633ab7d8f7d520 Author: Daniel Kahn Gillmor Date: Fri Aug 12 01:37:58 2016 -0400 Avoid leading ": " in the log output when there are no prefixes. * common/logging.c (do_logv): When no prefixes have been requested, omit the ": " separator, since there is nothing on the left-hand side of it. Signed-off-by: Daniel Kahn Gillmor diff --git a/common/logging.c b/common/logging.c index b6bafc7..c70ba35 100644 --- a/common/logging.c +++ b/common/logging.c @@ -687,14 +687,15 @@ do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr) else es_fprintf_unlocked (logstream, "[%u]", (unsigned int)getpid ()); } - if (!with_time || force_prefixes) + if ((!with_time && (with_prefix || with_pid)) || force_prefixes) es_putc_unlocked (':', logstream); /* A leading backspace suppresses the extra space so that we can correctly output, programname, filename and linenumber. */ if (fmt && *fmt == '\b') fmt++; else - es_putc_unlocked (' ', logstream); + if (with_time || with_prefix || with_pid || force_prefixes) + es_putc_unlocked (' ', logstream); } switch (level) commit 61c2a1fa6d6cb345f9d81f4bdd3f8f8ddac1ea3e Author: Daniel Kahn Gillmor Date: Fri Aug 12 01:37:57 2016 -0400 Call log_set_prefix() with human-readable labels. * agent/preset-passphrase.c, agent/protect-tool.c, dirmngr/dirmngr.c * dirmngr/t-http.c, g10/gpg.c, g10/gpgv.c, g13/g13-syshelp.c * g13/g13.c, kbx/kbxutil.c, scd/scdaemon.c, sm/gpgsm.c * tests/gpgscm/main.c, tools/gpg-check-pattern.c * tools/gpg-connect-agent.c, tools/gpgconf.c, tools/gpgtar.c * tools/symcryptrun.c: Invoke log_set_prefix() with human-readable labels. -- Some invocations of log_set_prefix() were done with raw numeric values instead of values that humans can understand. Use symbolic representations instead of numeric for better readability. Signed-off-by: Daniel Kahn Gillmor diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c index 485ca7b..a104977 100644 --- a/agent/preset-passphrase.c +++ b/agent/preset-passphrase.c @@ -208,7 +208,7 @@ main (int argc, char **argv) early_system_init (); set_strusage (my_strusage); - log_set_prefix ("gpg-preset-passphrase", 1); + log_set_prefix ("gpg-preset-passphrase", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); diff --git a/agent/protect-tool.c b/agent/protect-tool.c index f41cc0b..dbf7811 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -560,7 +560,7 @@ main (int argc, char **argv ) early_system_init (); set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix ("gpg-protect-tool", 1); + log_set_prefix ("gpg-protect-tool", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 007fa10..cb17420 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -743,7 +743,7 @@ main (int argc, char **argv) #endif /*USE_W32_SERVICE*/ set_strusage (my_strusage); - log_set_prefix (DIRMNGR_NAME, 1|4); + log_set_prefix (DIRMNGR_NAME, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID); /* Make sure that our subsystems are ready. */ i18n_init (); @@ -1073,7 +1073,7 @@ main (int argc, char **argv) if (logfile) { log_set_file (logfile); - log_set_prefix (NULL, 2|4); + log_set_prefix (NULL, GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); } if (debug_wait) diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 3a6be6c..59959c4 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -154,7 +154,7 @@ main (int argc, char **argv) http_session_t session = NULL; gpgrt_init (); - log_set_prefix (PGM, 1 | 4); + log_set_prefix (PGM, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID); if (argc) { argc--; argv++; } while (argc && last_argc != argc ) diff --git a/g10/gpg.c b/g10/gpg.c index fd21fde..891c85f 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2171,7 +2171,7 @@ main (int argc, char **argv) gnupg_rl_initialize (); set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix (GPG_NAME, 1); + log_set_prefix (GPG_NAME, GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init(); @@ -3429,7 +3429,7 @@ main (int argc, char **argv) if (logfile && opt.batch) { log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); + log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); } if (opt.verbose > 2) diff --git a/g10/gpgv.c b/g10/gpgv.c index fd1090e..4ef3e8b 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -149,7 +149,7 @@ main( int argc, char **argv ) early_system_init (); set_strusage (my_strusage); - log_set_prefix ("gpgv", 1); + log_set_prefix ("gpgv", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init(); diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index 0bb34da..7976be4 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -244,7 +244,7 @@ main ( int argc, char **argv) set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix (G13_NAME "-syshelp", 1); + log_set_prefix (G13_NAME "-syshelp", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); @@ -437,7 +437,7 @@ main ( int argc, char **argv) if (logfile) { log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); + log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); } if (gnupg_faked_time_p ()) diff --git a/g13/g13.c b/g13/g13.c index 082edc9..7c6e2e3 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -364,7 +364,7 @@ main ( int argc, char **argv) set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix (G13_NAME, 1); + log_set_prefix (G13_NAME, GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); @@ -655,7 +655,7 @@ main ( int argc, char **argv) if (logfile) { log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); + log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); } if (gnupg_faked_time_p ()) diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index e452b4d..77b134a 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -454,7 +454,7 @@ main( int argc, char **argv ) early_system_init (); set_strusage( my_strusage ); gcry_control (GCRYCTL_DISABLE_SECMEM); - log_set_prefix ("kbxutil", 1); + log_set_prefix ("kbxutil", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 263d9bd..514e3c2 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -416,7 +416,7 @@ main (int argc, char **argv ) /* Please note that we may running SUID(ROOT), so be very CAREFUL when adding any stuff between here and the call to INIT_SECMEM() somewhere after the option parsing */ - log_set_prefix ("scdaemon", 1|4); + log_set_prefix ("scdaemon", GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID); /* Make sure that our subsystems are ready. */ i18n_init (); @@ -695,7 +695,7 @@ main (int argc, char **argv ) if (logfile) { log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); + log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); } if (debug_wait && pipe_server) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 42b6706..e3b1e88 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -930,7 +930,7 @@ main ( int argc, char **argv) /* Please note that we may running SUID(ROOT), so be very CAREFUL when adding any stuff between here and the call to secmem_init() somewhere after the option parsing */ - log_set_prefix (GPGSM_NAME, 1); + log_set_prefix (GPGSM_NAME, GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); @@ -1507,7 +1507,7 @@ main ( int argc, char **argv) if (logfile && cmd == aServer) { log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); + log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); } if (gnupg_faked_time_p ()) diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c index 5b3792e..34ebb9f 100644 --- a/tests/gpgscm/main.c +++ b/tests/gpgscm/main.c @@ -216,7 +216,7 @@ main (int argc, char **argv) *p = 0, scmpath_len++; set_strusage (my_strusage); - log_set_prefix ("gpgscm", 1); + log_set_prefix ("gpgscm", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c index aa228a7..fba2365 100644 --- a/tools/gpg-check-pattern.c +++ b/tools/gpg-check-pattern.c @@ -165,7 +165,7 @@ main (int argc, char **argv ) early_system_init (); set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix ("gpg-check-pattern", 1); + log_set_prefix ("gpg-check-pattern", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init (); diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 6b5f507..106a8eb 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -1172,7 +1172,7 @@ main (int argc, char **argv) early_system_init (); gnupg_rl_initialize (); set_strusage (my_strusage); - log_set_prefix ("gpg-connect-agent", 1); + log_set_prefix ("gpg-connect-agent", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init(); diff --git a/tools/gpgconf.c b/tools/gpgconf.c index f7ce4c9..69ea9c9 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -223,7 +223,7 @@ main (int argc, char **argv) early_system_init (); gnupg_reopen_std (GPGCONF_NAME); set_strusage (my_strusage); - log_set_prefix (GPGCONF_NAME, 1); + log_set_prefix (GPGCONF_NAME, GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init(); diff --git a/tools/gpgtar.c b/tools/gpgtar.c index fcbee50..9c17139 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -416,7 +416,7 @@ main (int argc, char **argv) gnupg_reopen_std (GPGTAR_NAME); set_strusage (my_strusage); - log_set_prefix (GPGTAR_NAME, 1); + log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init(); diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index b6dc843..b2d8f5c 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -886,7 +886,7 @@ main (int argc, char **argv) early_system_init (); set_strusage (my_strusage); - log_set_prefix ("symcryptrun", 1); + log_set_prefix ("symcryptrun", GPGRT_LOG_WITH_PREFIX); /* Make sure that our subsystems are ready. */ i18n_init(); ----------------------------------------------------------------------- Summary of changes: agent/preset-passphrase.c | 2 +- agent/protect-tool.c | 2 +- common/logging.c | 5 +++-- dirmngr/dirmngr.c | 4 ++-- dirmngr/t-http.c | 2 +- g10/gpg.c | 4 ++-- g10/gpgv.c | 2 +- g13/g13-syshelp.c | 4 ++-- g13/g13.c | 4 ++-- kbx/kbxutil.c | 2 +- scd/scdaemon.c | 4 ++-- sm/gpgsm.c | 4 ++-- tests/gpgscm/main.c | 2 +- tools/gpg-check-pattern.c | 2 +- tools/gpg-connect-agent.c | 2 +- tools/gpgconf.c | 2 +- tools/gpgtar.c | 2 +- tools/symcryptrun.c | 2 +- 18 files changed, 26 insertions(+), 25 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 12:28:46 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 12 Aug 2016 12:28:46 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-282-g06e601a 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 06e601ad1a169ec8e941125afe698e722eca657d (commit) from 75c974c4e0a31981325f7d151bd13f2523f5df20 (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 06e601ad1a169ec8e941125afe698e722eca657d Author: Justus Winter Date: Fri Aug 12 12:28:03 2016 +0200 Add Python bindings to NEWS. -- Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 71c18a8..b3a250b 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] * Notation flags are now correctly set on verify. + * Bindings for Python 3 are now included. + * Interface changes relative to the 1.6.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_pubkey_algo_string NEW. ----------------------------------------------------------------------- Summary of changes: NEWS | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 13:12:03 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Aug 2016 13:12:03 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-25-g300755c 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 300755c1a10eec1f8bccd4182ed15c569473982c (commit) from c71ba9a57c0a4e3f919d90ea181ba7313d9533aa (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 300755c1a10eec1f8bccd4182ed15c569473982c Author: Andre Heinecke Date: Fri Aug 12 13:07:54 2016 +0200 Qt: Disable automatic wrap for desc and errors * qt/pinentrydialog.cpp (PinEntryDialog): Disable WordWrap. -- The agent already sends line breaks which should be respected. This fixes the problem that pinentry-qt would break ssh fingerprints because it treated the colon as a breakable character. GnuPG's translators and GnuPG itself should take care how descriptions and errors should be formatted. diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index 11a157c..009cd31 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -135,14 +135,12 @@ PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, _icon->setPixmap(icon()); _error = new QLabel(this); - _error->setWordWrap(true); QPalette pal; pal.setColor(QPalette::WindowText, Qt::red); _error->setPalette(pal); _error->hide(); _desc = new QLabel(this); - _desc->setWordWrap(true); _desc->hide(); _prompt = new QLabel(this); ----------------------------------------------------------------------- Summary of changes: qt/pinentrydialog.cpp | 2 -- 1 file changed, 2 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 14:15:04 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 12 Aug 2016 14:15:04 +0200 Subject: [git] gnupg-doc - branch, master, updated. c6d8a1bfeed3328af23815c9b9e8eebda6d819b4 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 c6d8a1bfeed3328af23815c9b9e8eebda6d819b4 (commit) from cc3c0679a8ff6a468fc00415a37af203a2909e1d (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 c6d8a1bfeed3328af23815c9b9e8eebda6d819b4 Author: Justus Winter Date: Fri Aug 12 14:14:19 2016 +0200 blog: New entry about the Python bindings for GPGME Signed-off-by: Justus Winter diff --git a/misc/blog.gnupg.org/20160812-python-bindings-for-gpgme.org b/misc/blog.gnupg.org/20160812-python-bindings-for-gpgme.org new file mode 100644 index 0000000..971bbaf --- /dev/null +++ b/misc/blog.gnupg.org/20160812-python-bindings-for-gpgme.org @@ -0,0 +1,72 @@ +# Python bindings for GPGME +#+AUTHOR: Justus +#+DATE: August 12th, 2016 + +** Python bindings for GPGME + +GPGME 1.7 includes bindings for Python >= 3.4. The bindings are a +port of the [[https://bitbucket.org/malb/pyme][~pyme~]] bindings to Python 3, with a small shim on top to +provide a more idiomatic interface. For the purposes of this post I +will refer to the preexisting bindings that are for Python 2 only +~pyme2~, and to our new bindings as ~pyme3~. + +Existing applications using ~pyme2~ should continue to work with +little to no changes beyond what is needed to port them to Python 3. + +~pyme2~ offers an interface that is very close to that of GPGME. This +interface exposes all features of the underlying library, but it is +not very "pythonic". Therefore, we made an effort to provide a nicer +interface on top of that. Let me demonstrate how that looks. + +One important aspect is how to pass data around. GPGME uses +~gpgme_data_t~ for that, and in ~pyme2~ one had to explicitly create +~pyme.core.Data~ objects to pass data to GPGME or to receive data. +With ~pyme3~ one can use every object that implements the buffer +protocol (e.g. ~bytes~), file-like objects with a ~fileno~ method, or +explicit ~pyme.Data~ objects in places where GPGME expects a +~gpgme_data_t~ object: + +#+BEGIN_SRC python +import pyme +with pyme.Context(armor=True) as c: + ciphertext, _, _ = c.encrypt(b"Hello Python world :)", passphrase="foo") +#+END_SRC + +This will encrypt the given plaintext using symmetric encryption and +the given passphrase, wrap it up using the OpenPGP protocol, and +encode it using ascii-armor. The plaintext is easily recovered using: + +#+BEGIN_SRC python +with pyme.Context() as c: + plaintext, _, _ = c.decrypt(ciphertext, passphrase="foo") +assert plaintext == b"Hello Python world :)" +#+END_SRC + +If ~passphrase~ is omitted, it is asked for out-of-band using GnuPG's +pinentry mechanism. Alternatively, if one or more recipients are +specified, asymmetric encryption is used. For details, please have a +look at the docstring of ~pyme.Context.encrypt~. + +Most file-like objects can be used without explicit wrapping. This is +a filter that decrypts OpenPGP messages in three lines of code: + +#+BEGIN_SRC python +import sys +import pyme +pyme.Context().decrypt(sys.stdin, sink=sys.stdout) +#+END_SRC + +For more examples, have a look at the tests and examples shipped with +the bindings under ~lang/python~. + +If you cannot wait until ~pyme3~ is packaged by your distribution, and +you do not want to build GPGME 1.7 from source merely to get ~pyme3~, +you can build it out-of-tree provided you have at least GPGME 1.6, the +Python development packages, and SWIG. You can get it from [[https://pypi.python.org/pypi/pyme3][pypi]] or +directly install it using ~pip~: + +#+BEGIN_SRC sh +# As of this writing, there is no released version uploaded to pypi, +# hence we need --pre. +$ pip install --pre pyme3 +#+END_SRC ----------------------------------------------------------------------- Summary of changes: .../20160812-python-bindings-for-gpgme.org | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 misc/blog.gnupg.org/20160812-python-bindings-for-gpgme.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 15:35:34 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 12 Aug 2016 15:35:34 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-284-gfe1e8e7 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 fe1e8e71aa18b4ac6471292b2894b8859f42f7c8 (commit) via 293d1736911fd5e77b8cec305168b35b2420c612 (commit) from 06e601ad1a169ec8e941125afe698e722eca657d (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 fe1e8e71aa18b4ac6471292b2894b8859f42f7c8 Author: Werner Koch Date: Fri Aug 12 15:24:46 2016 +0200 core: Make use of the "size-hint" in engine-gpg. * src/engine-gpg.c: Include data.h. (add_input_size_hint): New. (gpg_decrypt, gpg_encrypt, gpg_encrypt_sign, gpg_sign) (gpg_verify): Call new function, * tests/run-encrypt.c (status_cb): Print to stderr. (progress_cb): New.o (main): Add option --progress. Print full-status lines. Provide a size for the input data. Signed-off-by: Werner Koch diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 2bbed28..8b0ec52 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -2177,6 +2177,30 @@ The function @code{gpgme_data_set_encoding} changes the encoding of the data object with the handle @var{dh} to @var{enc}. @end deftypefun + at deftypefun {gpgme_error_t} gpgme_data_set_flag @ + (@w{gpgme_data_t @var{dh}}, @ + @w{const char *@var{name}}, @ + @w{const char *@var{value}}) + +Some minor properties of the data object can be controlled with flags +set by this function. The properties are identified by the following +values for @var{name}: + + at table @code + at item size-hint +The value is a decimal number with the length gpgme shall assume for +this data object. This is useful if the data is provided by callbacks +or via file descriptors but the applications knows the total size of +the data. If this is set the OpenPGP engine may use this to decide on +buffer allocation strategies and to provide a total value for its +progress information. + + at end table + +This function returns @code{0} on success. + at end deftypefun + + @node Data Buffer Convenience @subsection Data Buffer Convenience Functions @cindex data buffer, convenience diff --git a/src/engine-gpg.c b/src/engine-gpg.c index efab80a..3edac6c 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -42,6 +42,7 @@ #include "priv-io.h" #include "sema.h" #include "debug.h" +#include "data.h" #include "engine-backend.h" @@ -1483,6 +1484,35 @@ start (engine_gpg_t gpg) } +/* Add the --input-size-hint option if requested. */ +static gpgme_error_t +add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data) +{ + gpgme_error_t err; + gpgme_off_t value = _gpgme_data_get_size_hint (data); + char numbuf[50]; /* Large enough for even 2^128 in base-10. */ + char *p; + + if (!value || !have_gpg_version (gpg, "2.1.15")) + return 0; + + err = add_arg (gpg, "--input-size-hint"); + if (!err) + { + p = numbuf + sizeof numbuf; + *--p = 0; + do + { + *--p = '0' + (value % 10); + value /= 10; + } + while (value); + err = add_arg (gpg, p); + } + return err; +} + + static gpgme_error_t gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain) { @@ -1499,6 +1529,8 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain) if (!err) err = add_data (gpg, plain, 1, 1); if (!err) + err = add_input_size_hint (gpg, ciph); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, ciph, -1, 0); @@ -1764,6 +1796,8 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, err = add_arg (gpg, gpgme_data_get_file_name (plain)); } if (!err) + err = add_input_size_hint (gpg, plain); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, plain, -1, 0); @@ -1837,6 +1871,8 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], err = add_arg (gpg, gpgme_data_get_file_name (plain)); } if (!err) + err = add_input_size_hint (gpg, plain); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, plain, -1, 0); @@ -2291,7 +2327,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only, err = add_arg (gpg, "--with-colons"); /* Since gpg 2.1.15 fingerprints are always printed, thus there is - * no more need to explictly reqeust them. */ + * no more need to explictly request them. */ if (!have_gpg_version (gpg, "2.1.15")) { if (!err) @@ -2436,6 +2472,8 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out, /* Tell the gpg object about the data. */ if (!err) + err = add_input_size_hint (gpg, in); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, in, -1, 0); @@ -2481,11 +2519,12 @@ gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, if (plaintext) { /* Normal or cleartext signature. */ - err = add_arg (gpg, "--output"); if (!err) err = add_arg (gpg, "-"); if (!err) + err = add_input_size_hint (gpg, sig); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, sig, -1, 0); @@ -2496,6 +2535,8 @@ gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, { err = add_arg (gpg, "--verify"); if (!err) + err = add_input_size_hint (gpg, signed_text); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, sig, -1, 0); diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c index 210f88a..b94b028 100644 --- a/tests/run-encrypt.c +++ b/tests/run-encrypt.c @@ -36,16 +36,33 @@ static int verbose; + static gpg_error_t status_cb (void *opaque, const char *keyword, const char *value) { (void)opaque; - printf ("status_cb: %s %s\n", keyword, value); + fprintf (stderr, "status_cb: %s %s\n", nonnull(keyword), nonnull(value)); return 0; } static void +progress_cb (void *opaque, const char *what, int type, int current, int total) +{ + (void)opaque; + (void)type; + + if (total) + fprintf (stderr, "progress for '%s' %u%% (%d of %d)\n", + nonnull (what), + (unsigned)(((double)current / total) * 100), current, total); + else + fprintf (stderr, "progress for '%s' %d\n", nonnull(what), current); + fflush (stderr); +} + + +static void print_result (gpgme_encrypt_result_t result) { gpgme_invalid_key_t invkey; @@ -65,6 +82,7 @@ show_usage (int ex) "Options:\n" " --verbose run in verbose mode\n" " --status print status lines from the backend\n" + " --progress print progress info\n" " --openpgp use the OpenPGP protocol (default)\n" " --cms use the CMS protocol\n" " --uiserver use the UI server\n" @@ -87,12 +105,14 @@ main (int argc, char **argv) gpgme_data_t in, out; gpgme_encrypt_result_t result; int print_status = 0; + int print_progress = 0; int use_loopback = 0; char *keyargs[10]; gpgme_key_t keys[10+1]; int keycount = 0; int i; gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST; + gpgme_off_t offset; if (argc) { argc--; argv++; } @@ -120,6 +140,11 @@ main (int argc, char **argv) print_status = 1; argc--; argv++; } + else if (!strcmp (*argv, "--progress")) + { + print_progress = 1; + argc--; argv++; + } else if (!strcmp (*argv, "--openpgp")) { protocol = GPGME_PROTOCOL_OpenPGP; @@ -179,7 +204,12 @@ main (int argc, char **argv) gpgme_set_protocol (ctx, protocol); gpgme_set_armor (ctx, 1); if (print_status) - gpgme_set_status_cb (ctx, status_cb, NULL); + { + gpgme_set_status_cb (ctx, status_cb, NULL); + gpgme_set_ctx_flag (ctx, "full-status", "1"); + } + if (print_progress) + gpgme_set_progress_cb (ctx, progress_cb, NULL); if (use_loopback) { gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK); @@ -200,6 +230,41 @@ main (int argc, char **argv) *argv, gpg_strerror (err)); exit (1); } + offset = gpgme_data_seek (in, 0, SEEK_END); + if (offset == (gpgme_off_t)(-1)) + { + err = gpg_error_from_syserror (); + fprintf (stderr, PGM ": error seeking `%s': %s\n", + *argv, gpg_strerror (err)); + exit (1); + } + if (gpgme_data_seek (in, 0, SEEK_SET) == (gpgme_off_t)(-1)) + { + err = gpg_error_from_syserror (); + fprintf (stderr, PGM ": error seeking `%s': %s\n", + *argv, gpg_strerror (err)); + exit (1); + } + { + char numbuf[50]; + char *p; + + p = numbuf + sizeof numbuf; + *--p = 0; + do + { + *--p = '0' + (offset % 10); + offset /= 10; + } + while (offset); + err = gpgme_data_set_flag (in, "size-hint", p); + if (err) + { + fprintf (stderr, PGM ": error setting size-hint for `%s': %s\n", + *argv, gpg_strerror (err)); + exit (1); + } + } err = gpgme_data_new (&out); fail_if_err (err); commit 293d1736911fd5e77b8cec305168b35b2420c612 Author: Werner Koch Date: Fri Aug 12 15:21:16 2016 +0200 core: Add gpgme_data_set_flag to add more meta data to data objects. * src/gpgme.h.in (gpgme_data_set_flag): New public function. * src/data.c (gpgme_data_set_flag): New. (_gpgme_data_get_size_hint): New. * src/data.h (strucy gpgme_data): Add field 'size_hint'. * src/gpgme.def, src/libgpgme.vers: Add new function. * src/conversion.c (_gpgme_string_to_off): New. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index b3a250b..e47ec91 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] gpgme_pubkey_algo_string NEW. GPGME_PK_EDDSA NEW. gpgme_set_ctx_flag NEW. + gpgme_data_set_flag NEW. gpgme_signature_t EXTENDED: New field tofu. gpgme_subkey_t EXTENDED: New field keygrip. gpgme_tofu_policy_t NEW. diff --git a/src/conversion.c b/src/conversion.c index c2b27a1..3df8fe5 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -364,6 +364,25 @@ _gpgme_strtoul_field (const char *string, unsigned long *result) } +/* Convert STRING into an offset value. Note that this functions only + * allows for a base-10 length. This function is similar to atoi() + * and thus there is no error checking. */ +gpgme_off_t +_gpgme_string_to_off (const char *string) +{ + gpgme_off_t value = 0; + + while (*string == ' ' || *string == '\t') + string++; + for (; *string >= '0' && *string <= '9'; string++) + { + value *= 10; + value += atoi_1 (string); + } + return value; +} + + #ifdef HAVE_W32_SYSTEM static time_t _gpgme_timegm (struct tm *tm) diff --git a/src/data.c b/src/data.c index 87b619e..6964246 100644 --- a/src/data.c +++ b/src/data.c @@ -243,6 +243,28 @@ gpgme_data_get_file_name (gpgme_data_t dh) return dh->file_name; } + +/* Set a flag for the data object DH. See the manual for details. */ +gpg_error_t +gpgme_data_set_flag (gpgme_data_t dh, const char *name, const char *value) +{ + TRACE_BEG2 (DEBUG_DATA, "gpgme_data_set_flag", dh, + "%s=%s", name, value); + + if (!dh) + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + + if (!strcmp (name, "size-hint")) + { + dh->size_hint= value? _gpgme_string_to_off (value) : 0; + } + else + return gpg_error (GPG_ERR_UNKNOWN_NAME); + + return 0; +} + + /* Functions to support the wait interface. */ @@ -334,3 +356,11 @@ _gpgme_data_get_fd (gpgme_data_t dh) return -1; return (*dh->cbs->get_fd) (dh); } + + +/* Get the size-hint value for DH or 0 if not available. */ +gpgme_off_t +_gpgme_data_get_size_hint (gpgme_data_t dh) +{ + return dh ? dh->size_hint : 0; +} diff --git a/src/data.h b/src/data.h index 3d404af..0a15b61 100644 --- a/src/data.h +++ b/src/data.h @@ -89,6 +89,9 @@ struct gpgme_data /* File name of the data object. */ char *file_name; + /* Hint on the to be expected toatl size of the data. */ + gpgme_off_t size_hint; + union { /* For gpgme_data_new_from_fd. */ @@ -134,4 +137,7 @@ void _gpgme_data_release (gpgme_data_t dh); return -1. */ int _gpgme_data_get_fd (gpgme_data_t dh); +/* Get the size-hint value for DH or 0 if not available. */ +gpgme_off_t _gpgme_data_get_size_hint (gpgme_data_t dh); + #endif /* DATA_H */ diff --git a/src/gpgme.def b/src/gpgme.def index dfdb6c6..a15c35b 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -226,5 +226,8 @@ EXPORTS gpgme_pubkey_algo_string @169 gpgme_set_ctx_flag @170 + + gpgme_data_set_flag @171 + ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 56d15f4..40f5442 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1282,6 +1282,10 @@ char *gpgme_data_get_file_name (gpgme_data_t dh); gpgme_error_t gpgme_data_set_file_name (gpgme_data_t dh, const char *file_name); +/* Set a flag for the data object DH. See the manual for details. */ +gpg_error_t gpgme_data_set_flag (gpgme_data_t dh, + const char *name, const char *value); + /* Try to identify the type of the data in DH. */ gpgme_data_type_t gpgme_data_identify (gpgme_data_t dh, int reserved); diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 873cb19..d29bc14 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -230,6 +230,8 @@ GPGME_1.0 { gpgme_err_code_from_syserror; gpgme_err_set_errno; + gpgme_data_set_flag; + local: *; diff --git a/src/util.h b/src/util.h index 5a0f790..a3425f0 100644 --- a/src/util.h +++ b/src/util.h @@ -134,6 +134,9 @@ int _gpgme_split_fields (char *string, char **array, int arraysize); * trailing garbage. */ gpgme_error_t _gpgme_strtoul_field (const char *string, unsigned long *result); +/* Convert STRING into an offset value similar to atoi(). */ +gpgme_off_t _gpgme_string_to_off (const char *string); + /* Parse the string TIMESTAMP into a time_t. The string may either be seconds since Epoch or in the ISO 8601 format like "20390815T143012". Returns 0 for an empty string or seconds since ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/gpgme.texi | 24 +++++++++++++++++++ src/conversion.c | 19 +++++++++++++++ src/data.c | 30 +++++++++++++++++++++++ src/data.h | 6 +++++ src/engine-gpg.c | 45 ++++++++++++++++++++++++++++++++-- src/gpgme.def | 3 +++ src/gpgme.h.in | 4 ++++ src/libgpgme.vers | 2 ++ src/util.h | 3 +++ tests/run-encrypt.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 11 files changed, 202 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 12 16:57:38 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Aug 2016 16:57:38 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-286-g391e554 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 391e55411cda11446ca9de4dd0dc2b54d3e6fff5 (commit) via df7bbf5a66576a5a320b54c8f6ad52bc84f0e833 (commit) from fe1e8e71aa18b4ac6471292b2894b8859f42f7c8 (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 391e55411cda11446ca9de4dd0dc2b54d3e6fff5 Author: Andre Heinecke Date: Fri Aug 12 16:55:51 2016 +0200 Qt: Add test for progress signal of encryptjob * lang/qt/tests/t-encrypt.cpp (testProgress): New. -- This tests that a ByteArray IODevice now gives proper progress signals. diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp index c6fcaa2..708c205 100644 --- a/lang/qt/tests/t-encrypt.cpp +++ b/lang/qt/tests/t-encrypt.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "keylistjob.h" #include "encryptjob.h" #include "qgpgmeencryptjob.h" @@ -39,8 +41,11 @@ #include "qgpgmedecryptjob.h" #include "qgpgmebackend.h" #include "keylistresult.h" +#include "engineinfo.h" #include "t-support.h" +#define PROGRESS_TEST_SIZE 1 * 1024 * 1024 + using namespace QGpgME; using namespace GpgME; @@ -48,6 +53,9 @@ class EncryptionTest : public QGpgMETest { Q_OBJECT +Q_SIGNALS: + void asyncDone(); + private Q_SLOTS: void testSimpleEncryptDecrypt() @@ -82,6 +90,60 @@ private Q_SLOTS: delete decJob; } + void testProgress() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.15") { + // We can only test the progress with 2.1.15 as this started to + // have total progress for memory callbacks + return; + } + auto listjob = openpgp()->keyListJob(false, false, false); + std::vector keys; + auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa at example.net"), + false, keys); + Q_ASSERT(!keylistresult.error()); + Q_ASSERT(keys.size() == 1); + delete listjob; + + auto job = openpgp()->encryptJob(/*ASCII Armor */false, /* Textmode */ false); + Q_ASSERT(job); + QByteArray plainBa; + plainBa.fill('X', PROGRESS_TEST_SIZE); + QByteArray cipherText; + + bool initSeen = false; + bool finishSeen = false; + connect(job, &Job::progress, this, [this, &initSeen, &finishSeen] (const QString& what, int current, int total) { + // We only check for progress 0 and max progress as the other progress + // lines depend on the system speed and are as such unreliable to test. + Q_ASSERT(total == PROGRESS_TEST_SIZE); + if (current == 0) { + initSeen = true; + } + if (current == total) { + finishSeen = true; + } + Q_ASSERT(current >= 0 && current <= total); + }); + connect(job, &EncryptJob::result, this, [this, &initSeen, &finishSeen] (const GpgME::EncryptionResult &result, + const QByteArray &cipherText, + const QString, + const GpgME::Error) { + Q_ASSERT(initSeen); + Q_ASSERT(finishSeen); + Q_EMIT asyncDone(); + }); + + auto inptr = std::shared_ptr(new QBuffer(&plainBa)); + inptr->open(QIODevice::ReadOnly); + auto outptr = std::shared_ptr(new QBuffer(&cipherText)); + outptr->open(QIODevice::WriteOnly); + + job->start(keys, inptr, outptr, Context::AlwaysTrust); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } + void testSymmetricEncryptDecrypt() { auto ctx = Context::createForProtocol(OpenPGP); commit df7bbf5a66576a5a320b54c8f6ad52bc84f0e833 Author: Andre Heinecke Date: Fri Aug 12 16:51:13 2016 +0200 Cpp: Provide size-hint for seekable and mem data * lang/cpp/src/data.cpp (GpgME::Data::Data): Set size-hint for mem and DataProvider based Data. -- This fixes the case that QGpgME did not have a total value for progress as the size was unknown. diff --git a/lang/cpp/src/data.cpp b/lang/cpp/src/data.cpp index 64acb47..9527b2f 100644 --- a/lang/cpp/src/data.cpp +++ b/lang/cpp/src/data.cpp @@ -62,6 +62,9 @@ GpgME::Data::Data(const char *buffer, size_t size, bool copy) { gpgme_data_t data; const gpgme_error_t e = gpgme_data_new_from_mem(&data, buffer, size, int(copy)); + std::string sizestr = std::to_string(size); + // Ignore errors as this is optional + gpgme_data_set_flag(data, "size-hint", sizestr.c_str()); d.reset(new Private(e ? 0 : data)); } @@ -125,6 +128,13 @@ GpgME::Data::Data(DataProvider *dp) if (e) { d->data = 0; } + if (dp->isSupported(DataProvider::Seek)) { + off_t size = seek(0, SEEK_END); + seek(0, SEEK_SET); + std::string sizestr = std::to_string(size); + // Ignore errors as this is optional + gpgme_data_set_flag(d->data, "size-hint", sizestr.c_str()); + } #ifndef NDEBUG //std::cerr << "GpgME::Data(): DataProvider supports: " // << ( d->cbs.read ? "read" : "no read" ) << ", " ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/data.cpp | 10 ++++++++ lang/qt/tests/t-encrypt.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sat Aug 13 13:52:36 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 13 Aug 2016 13:52:36 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-77-gb57f553 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 b57f55321295846d47144bd6b39fbbcac0127421 (commit) from 3a75ff65fba24ea2d024bd8fef633ab7d8f7d520 (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 b57f55321295846d47144bd6b39fbbcac0127421 Author: Werner Koch Date: Sat Aug 13 12:49:54 2016 +0200 g13: New command --find-device. * common/status.h (STATUS_BLOCKDEV: New. * g13/call-syshelp.c: Include "call-syshelp.h". (finddevice_status_cb, call_syshelp_find_device): New. * g13/g13.c (aFindDevice): New. (opts): Add "--find-device". (main): Implement --find-device. * g13/sh-cmd.c (cmd_finddevice): New. (register_commands): Register new command. -- This might be useful for scripting. Signed-off-by: Werner Koch diff --git a/common/status.h b/common/status.h index f9771c2..079a04a 100644 --- a/common/status.h +++ b/common/status.h @@ -142,6 +142,7 @@ enum STATUS_TRUNCATED, STATUS_MOUNTPOINT, + STATUS_BLOCKDEV, STATUS_PINENTRY_LAUNCHED, diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index bc93d20..d0f1b00 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -33,6 +33,7 @@ #include "keyblob.h" #include "membuf.h" #include "create.h" +#include "call-syshelp.h" /* Local data for this module. A pointer to this is stored in the @@ -172,6 +173,68 @@ call_syshelp_release (ctrl_t ctrl) } + +/* Staus callback for call_syshelp_find_device. */ +static gpg_error_t +finddevice_status_cb (void *opaque, const char *line) +{ + char **r_blockdev = opaque; + char *p; + + if ((p = has_leading_keyword (line, "BLOCKDEV")) && *p && !*r_blockdev) + { + *r_blockdev = xtrystrdup (p); + if (!*r_blockdev) + return gpg_error_from_syserror (); + } + + return 0; +} + + +/* Send the FINDDEVICE command to the syshelper. On success the name + * of the block device is stored at R_BLOCKDEV. */ +gpg_error_t +call_syshelp_find_device (ctrl_t ctrl, const char *name, char **r_blockdev) +{ + gpg_error_t err; + assuan_context_t ctx; + char *line = NULL; + char *blockdev = NULL; /* The result. */ + + *r_blockdev = NULL; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + line = xtryasprintf ("FINDDEVICE %s", name); + if (!line) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, + finddevice_status_cb, &blockdev); + if (err) + goto leave; + if (!blockdev) + { + log_error ("status line for successful FINDDEVICE missing\n"); + err = gpg_error (GPG_ERR_UNEXPECTED); + goto leave; + } + *r_blockdev = blockdev; + blockdev = NULL; + + leave: + xfree (blockdev); + xfree (line); + return err; +} + + + /* Send the DEVICE command to the syshelper. FNAME is the name of the device. */ gpg_error_t diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h index c2578f2..14deb7d 100644 --- a/g13/call-syshelp.h +++ b/g13/call-syshelp.h @@ -23,6 +23,8 @@ #include "g13tuple.h" void call_syshelp_release (ctrl_t ctrl); +gpg_error_t call_syshelp_find_device (ctrl_t ctrl, + const char *name, char **r_blockdev); gpg_error_t call_syshelp_set_device (ctrl_t ctrl, const char *fname); gpg_error_t call_syshelp_run_create (ctrl_t ctrl, int conttype); gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, diff --git a/g13/g13.c b/g13/g13.c index 7c6e2e3..799fd66 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -62,6 +62,7 @@ enum cmd_and_opt_values { aSuspend, aResume, aServer, + aFindDevice, oOptions, oDebug, @@ -115,6 +116,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aSuspend, "suspend", N_("Suspend a file system container") ), ARGPARSE_c (aResume, "resume", N_("Resume a file system container") ), ARGPARSE_c (aServer, "server", N_("Run in server mode")), + ARGPARSE_c (aFindDevice, "find-device", "@"), ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"), ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"), @@ -491,6 +493,7 @@ main ( int argc, char **argv) case aSuspend: case aResume: case aCreate: + case aFindDevice: set_cmd (&cmd, pargs.r_opt); break; @@ -744,6 +747,22 @@ main ( int argc, char **argv) } break; + case aFindDevice: + { + char *blockdev; + + if (argc != 1) + wrong_args ("--find-device name"); + + err = call_syshelp_find_device (&ctrl, argv[0], &blockdev); + if (err) + log_error ("error finding device '%s': %s <%s>\n", + argv[0], gpg_strerror (err), gpg_strsource (err)); + else + puts (blockdev); + } + break; + case aCreate: /* Create a new container. */ { if (argc != 1) diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index fe596f4..e00bb77 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -157,6 +157,82 @@ reset_notify (assuan_context_t ctx, char *line) } +static const char hlp_finddevice[] = + "FINDDEVICE \n" + "\n" + "Find the device matching NAME. NAME be any identifier from\n" + "g13tab permissable for the user. The corresponding block\n" + "device is retruned using a status line."; +static gpg_error_t +cmd_finddevice (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + tab_item_t ti; + const char *s; + const char *name; + + name = skip_options (line); + + /* Are we allowed to use the given device? We check several names: + * 1. The full block device + * 2. The label + * 3. The final part of the block device if NAME does not have a slash. + * 4. The mountpoint + */ + for (ti=ctrl->client.tab; ti; ti = ti->next) + if (!strcmp (name, ti->blockdev)) + break; + if (!ti) + { + for (ti=ctrl->client.tab; ti; ti = ti->next) + if (ti->label && !strcmp (name, ti->label)) + break; + } + if (!ti && !strchr (name, '/')) + { + for (ti=ctrl->client.tab; ti; ti = ti->next) + { + s = strrchr (ti->blockdev, '/'); + if (s && s[1] && !strcmp (name, s+1)) + break; + } + } + if (!ti) + { + for (ti=ctrl->client.tab; ti; ti = ti->next) + if (ti->mountpoint && !strcmp (name, ti->mountpoint)) + break; + } + + if (!ti) + { + err = set_error (GPG_ERR_NOT_FOUND, "device not configured for user"); + goto leave; + } + + /* Check whether we have permissions to open the device. */ + { + estream_t fp = es_fopen (ti->blockdev, "rb"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("error opening '%s': %s\n", + ti->blockdev, gpg_strerror (err)); + goto leave; + } + es_fclose (fp); + } + + err = g13_status (ctrl, STATUS_BLOCKDEV, ti->blockdev, NULL); + if (err) + return err; + + leave: + return leave_cmd (ctx, err); +} + + static const char hlp_device[] = "DEVICE \n" "\n" @@ -588,6 +664,7 @@ register_commands (assuan_context_t ctx, int fail_all) assuan_handler_t handler; const char * const help; } table[] = { + { "FINDDEVICE", cmd_finddevice, hlp_finddevice }, { "DEVICE", cmd_device, hlp_device }, { "CREATE", cmd_create, hlp_create }, { "MOUNT", cmd_mount, hlp_mount }, ----------------------------------------------------------------------- Summary of changes: common/status.h | 1 + g13/call-syshelp.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ g13/call-syshelp.h | 2 ++ g13/g13.c | 19 ++++++++++++++ g13/sh-cmd.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Aug 14 22:15:38 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 14 Aug 2016 22:15:38 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-82-gf02ceb6 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 f02ceb6c6e94c6fbfaeeafe728397be38107de4d (commit) via b781113cf1391926dedf8dc943624d3bb9726318 (commit) via c9a0bccc77c93c08d6980a1718dfaf238a559eb9 (commit) via 700920640211168ae1c97d0adef74ba8615d90bb (commit) via 37e932658cbd873ac96ff7e2067a97dffc2e0507 (commit) from b57f55321295846d47144bd6b39fbbcac0127421 (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 f02ceb6c6e94c6fbfaeeafe728397be38107de4d Author: Werner Koch Date: Sun Aug 14 20:23:12 2016 +0200 g13: Allow the use of a g13tab label for --mount. * g13/mount.c (g13_mount_container): Do not run the first access check if syshelp is required. Signed-off-by: Werner Koch diff --git a/g13/mount.c b/g13/mount.c index f4371cc..b46c8d0 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -60,10 +60,6 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) char *mountpoint_buffer = NULL; char *blockdev_buffer = NULL; - /* A quick check to see whether the container exists. */ - if (access (filename, F_OK)) - return gpg_error_from_syserror (); - /* Decide whether we need to use the g13-syshelp. */ err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer); if (!err) @@ -77,6 +73,12 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) filename, gpg_strerror (err), gpg_strsource (err)); return err; } + else + { + /* A quick check to see whether we can the container exists. */ + if (access (filename, R_OK)) + return gpg_error_from_syserror (); + } if (!mountpoint) { commit b781113cf1391926dedf8dc943624d3bb9726318 Author: Werner Koch Date: Sun Aug 14 20:17:51 2016 +0200 g13: Implement --umount for dm-crypt. * g13/g13.c (main): Implement command --umount. * g13/mount.c (g13_umount_container): use the syshelper if needed. * g13/backend.c (be_umount_container): New. * g13/be-dmcrypt.c (be_dmcrypt_umount_container): New. * g13/call-syshelp.c (call_syshelp_run_umount): New. * g13/sh-cmd.c (cmd_umount): New. (register_commands): Register UMOUNT. * g13/sh-dmcrypt.c (sh_dmcrypt_umount_container): New. Signed-off-by: Werner Koch diff --git a/g13/backend.c b/g13/backend.c index dd21768..659c6b7 100644 --- a/g13/backend.c +++ b/g13/backend.c @@ -240,6 +240,24 @@ be_mount_container (ctrl_t ctrl, int conttype, } +/* Dispatcher to the backend's umount function. */ +gpg_error_t +be_umount_container (ctrl_t ctrl, int conttype, const char *fname) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_umount_container (ctrl, fname); + + default: + return no_such_backend (conttype); + } +} + + /* Dispatcher to the backend's suspend function. */ gpg_error_t be_suspend_container (ctrl_t ctrl, int conttype, const char *fname) diff --git a/g13/backend.h b/g13/backend.h index 66d9cd5..d1cedb3 100644 --- a/g13/backend.h +++ b/g13/backend.h @@ -39,6 +39,7 @@ gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, const char *fname, const char *mountpoint, tupledesc_t tuples, unsigned int *r_id); +gpg_error_t be_umount_container (ctrl_t ctrl, int conttype, const char *fname); gpg_error_t be_suspend_container (ctrl_t ctrl, int conttype, const char *fname); gpg_error_t be_resume_container (ctrl_t ctrl, int conttype, diff --git a/g13/be-dmcrypt.c b/g13/be-dmcrypt.c index e5e9b33..c65be08 100644 --- a/g13/be-dmcrypt.c +++ b/g13/be-dmcrypt.c @@ -64,6 +64,23 @@ be_dmcrypt_mount_container (ctrl_t ctrl, } +/* Unmount the container described by the filename FNAME. */ +gpg_error_t +be_dmcrypt_umount_container (ctrl_t ctrl, const char *fname) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_umount (ctrl, CONTTYPE_DM_CRYPT); + + leave: + return err; +} + + /* Suspend the container described by the filename FNAME. */ gpg_error_t be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname) diff --git a/g13/be-dmcrypt.h b/g13/be-dmcrypt.h index d74e09f..189bfee 100644 --- a/g13/be-dmcrypt.h +++ b/g13/be-dmcrypt.h @@ -27,6 +27,7 @@ gpg_error_t be_dmcrypt_mount_container (ctrl_t ctrl, const char *fname, const char *mountpoint, tupledesc_t tuples); +gpg_error_t be_dmcrypt_umount_container (ctrl_t ctrl, const char *fname); gpg_error_t be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname); gpg_error_t be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples); diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index 952d8de..76d181b 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -522,6 +522,40 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, /* + * Run the UMOUNT command on the current device. CONTTYPES gives the + * content type of the container (fixme: Do we really need this?). + */ +gpg_error_t +call_syshelp_run_umount (ctrl_t ctrl, int conttype) +{ + gpg_error_t err; + assuan_context_t ctx; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + if (conttype == CONTTYPE_DM_CRYPT) + { + err = assuan_transact (ctx, "UMOUNT dm-crypt", + NULL, NULL, + NULL, NULL, + NULL, NULL); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} + + + +/* * Run the SUSPEND command on the current device. CONTTYPES gives the * requested content type for the new container. */ diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h index aa4b692..0e110c9 100644 --- a/g13/call-syshelp.h +++ b/g13/call-syshelp.h @@ -33,6 +33,7 @@ gpg_error_t call_syshelp_run_create (ctrl_t ctrl, int conttype); gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, tupledesc_t tuples); +gpg_error_t call_syshelp_run_umount (ctrl_t ctrl, int conttype); gpg_error_t call_syshelp_run_suspend (ctrl_t ctrl, int conttype); gpg_error_t call_syshelp_run_resume (ctrl_t ctrl, int conttype, tupledesc_t tuples); diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h index dae2bd0..618b41d 100644 --- a/g13/g13-syshelp.h +++ b/g13/g13-syshelp.h @@ -86,6 +86,7 @@ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp); gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, tupledesc_t keyblob); +gpg_error_t sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname); gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname); gpg_error_t sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname, tupledesc_t keyblob); diff --git a/g13/g13.c b/g13/g13.c index 799fd66..7744855 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -793,9 +793,10 @@ main ( int argc, char **argv) { if (argc != 1) wrong_args ("--umount filename"); - err = GPG_ERR_NOT_IMPLEMENTED; - log_error ("error unmounting container '%s': %s <%s>\n", - *argv, gpg_strerror (err), gpg_strsource (err)); + err = g13_umount_container (&ctrl, argv[0], NULL); + if (err) + log_error ("error unmounting container '%s': %s <%s>\n", + *argv, gpg_strerror (err), gpg_strsource (err)); } break; diff --git a/g13/mount.c b/g13/mount.c index d682585..f4371cc 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -64,10 +64,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) if (access (filename, F_OK)) return gpg_error_from_syserror (); - /* Decide whether we need to use the g13-syshelp because we can't - use lock files for them. This is most likely the case for device - files; thus we test for this. FIXME: The correct solution would - be to call g13-syshelp to match the file against the g13tab. */ + /* Decide whether we need to use the g13-syshelp. */ err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer); if (!err) { @@ -217,27 +214,50 @@ gpg_error_t g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) { gpg_error_t err; - unsigned int rid; - runner_t runner; - - (void)ctrl; + char *blockdev; if (!filename && !mountpoint) return gpg_error (GPG_ERR_ENOENT); - err = mountinfo_find_mount (filename, mountpoint, &rid); - if (err) - return err; - - runner = runner_find_by_rid (rid); - if (!runner) + /* Decide whether we need to use the g13-syshelp. */ + err = call_syshelp_find_device (ctrl, filename, &blockdev); + if (!err) + { + /* Need to employ the syshelper to umount the file system. */ + /* FIXME: We should get the CONTTYPE from the blockdev. */ + err = be_umount_container (ctrl, CONTTYPE_DM_CRYPT, blockdev); + if (!err) + { + /* if (conttype == CONTTYPE_DM_CRYPT) */ + g13_request_shutdown (); + } + } + else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND) { - log_error ("runner %u not found\n", rid); - return gpg_error (GPG_ERR_NOT_FOUND); + log_error ("error finding device '%s': %s <%s>\n", + filename, gpg_strerror (err), gpg_strsource (err)); } + else + { + /* Not in g13tab - kill the runner process for this mount. */ + unsigned int rid; + runner_t runner; - runner_cancel (runner); - runner_release (runner); + err = mountinfo_find_mount (filename, mountpoint, &rid); + if (err) + return err; - return 0; + runner = runner_find_by_rid (rid); + if (!runner) + { + log_error ("runner %u not found\n", rid); + return gpg_error (GPG_ERR_NOT_FOUND); + } + + runner_cancel (runner); + runner_release (runner); + } + + xfree (blockdev); + return err; } diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index 20db8dc..8214919 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -500,6 +500,40 @@ cmd_mount (assuan_context_t ctx, char *line) } +static const char hlp_umount[] = + "UMOUNT \n" + "\n" + "Unmount an encrypted partition and wipe the key.\n" + " must be \"dm-crypt\" for now."; +static gpg_error_t +cmd_umount (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + + line = skip_options (line); + + if (strcmp (line, "dm-crypt")) + { + err = set_error (GPG_ERR_INV_ARG, "Type must be \"dm-crypt\""); + goto leave; + } + + if (!ctrl->server_local->devicename + || !ctrl->server_local->devicefp + || !ctrl->devti) + { + err = set_error (GPG_ERR_ENOENT, "No device has been set"); + goto leave; + } + + err = sh_dmcrypt_umount_container (ctrl, ctrl->server_local->devicename); + + leave: + return leave_cmd (ctx, err); +} + + static const char hlp_suspend[] = "SUSPEND \n" "\n" @@ -713,6 +747,7 @@ register_commands (assuan_context_t ctx, int fail_all) { "CREATE", cmd_create, hlp_create }, { "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob }, { "MOUNT", cmd_mount, hlp_mount }, + { "UMOUNT", cmd_umount, hlp_umount }, { "SUSPEND", cmd_suspend,hlp_suspend}, { "RESUME", cmd_resume, hlp_resume }, { "INPUT", NULL }, diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index e0cd2e1..201f856 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -723,6 +723,99 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, } +/* Unmount a DM-Crypt container on device DEVNAME and wipe the keys. */ +gpg_error_t +sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname) +{ + gpg_error_t err; + char *targetname_abs = NULL; + char *result = NULL; + + if (!ctrl->devti) + return gpg_error (GPG_ERR_INV_ARG); + + g13_syshelp_i_know_what_i_am_doing (); + + /* Check that the device is used by device mapper. */ + err = check_blockdev (devname, 1); + if (gpg_err_code (err) != GPG_ERR_EBUSY) + { + log_error ("device '%s' is not used by the device mapper: %s\n", + devname, gpg_strerror (err)); + goto leave; + } + + /* Fixme: Check that this is really a g13 partition. */ + + /* Device mapper needs a name for the device: Take it from the label + or use "0". */ + targetname_abs = strconcat ("/dev/mapper/", + "g13-", ctrl->client.uname, "-", + ctrl->devti->label? ctrl->devti->label : "0", + NULL); + if (!targetname_abs) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Run the regular umount command. */ + { + const char *argv[2]; + + argv[0] = targetname_abs; + argv[1] = NULL; + log_debug ("now running \"umount %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); + } + if (err) + { + log_error ("error running umount: %s\n", gpg_strerror (err)); + if (1) + { + /* Try to show some info about processes using the partition. */ + const char *argv[3]; + + argv[0] = "-mv"; + argv[1] = targetname_abs; + argv[2] = NULL; + gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); + } + goto leave; + } + if (result && *result) /* (We should not see output to stdout). */ + log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + xfree (result); + result = NULL; + + /* Run the dmsetup remove command. */ + { + const char *argv[3]; + + argv[0] = "remove"; + argv[1] = targetname_abs; + argv[2] = NULL; + log_debug ("now running \"dmsetup remove %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL); + } + if (err) + { + log_error ("error running \"dmsetup remove %s\": %s\n", + targetname_abs, gpg_strerror (err)); + goto leave; + } + if (result && *result) + log_debug ("dmsetup result: %s\n", result); + xfree (result); + result = NULL; + + leave: + xfree (targetname_abs); + xfree (result); + return err; +} + + /* Suspend a DM-Crypt container on device DEVNAME and wipe the keys. */ gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname) commit c9a0bccc77c93c08d6980a1718dfaf238a559eb9 Author: Werner Koch Date: Sat Aug 13 19:42:18 2016 +0200 g13: Fix double free bug. * g13/sh-cmd.c (cmd_mount, cmd_resume): Do not xfree TIUPLES. Signed-off-by: Werner Koch diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index 10b1ba9..20db8dc 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -495,7 +495,6 @@ cmd_mount (assuan_context_t ctx, char *line) tuples); leave: - xfree (tuples); destroy_tupledesc (tuples); return leave_cmd (ctx, err); } @@ -610,7 +609,6 @@ cmd_resume (assuan_context_t ctx, char *line) tuples); leave: - xfree (tuples); destroy_tupledesc (tuples); return leave_cmd (ctx, err); } commit 700920640211168ae1c97d0adef74ba8615d90bb Author: Werner Koch Date: Sat Aug 13 19:27:28 2016 +0200 g13: Consider g13tab for a mount command. * g13/sh-cmd.c (cmd_getkeyblob): New. (register_commands): Register it. * g13/call-syshelp.c (getkeyblob_data_cb): New. (call_syshelp_get_keyblob): New. * g13/mount.c: Include callsyshelp.h. (g13_mount_container): Ask syshelp whether the filename is managed by g13tab. Call syshelp to get the encrypted keyblob in this case. Signed-off-by: Werner Koch diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index d0f1b00..952d8de 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -235,6 +235,52 @@ call_syshelp_find_device (ctrl_t ctrl, const char *name, char **r_blockdev) +static gpg_error_t +getkeyblob_data_cb (void *opaque, const void *data, size_t datalen) +{ + membuf_t *mb = opaque; + + if (data) + put_membuf (mb, data, datalen); + + return 0; +} + + +/* Send the GTEKEYBLOB command to the syshelper. On success the + * encrypted keyblpob is stored at (R_ENCKEYBLOB,R_ENCKEYBLOBLEN). */ +gpg_error_t +call_syshelp_get_keyblob (ctrl_t ctrl, + void **r_enckeyblob, size_t *r_enckeybloblen) +{ + gpg_error_t err; + assuan_context_t ctx; + membuf_t mb; + + *r_enckeyblob = NULL; + *r_enckeybloblen = 0; + init_membuf (&mb, 512); + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + err = assuan_transact (ctx, "GETKEYBLOB", + getkeyblob_data_cb, &mb, + NULL, NULL, NULL, NULL); + if (err) + goto leave; + *r_enckeyblob = get_membuf (&mb, r_enckeybloblen); + if (!*r_enckeyblob) + err = gpg_error_from_syserror (); + + leave: + xfree (get_membuf (&mb, NULL)); + return err; +} + + + /* Send the DEVICE command to the syshelper. FNAME is the name of the device. */ gpg_error_t diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h index 14deb7d..aa4b692 100644 --- a/g13/call-syshelp.h +++ b/g13/call-syshelp.h @@ -25,6 +25,9 @@ void call_syshelp_release (ctrl_t ctrl); gpg_error_t call_syshelp_find_device (ctrl_t ctrl, const char *name, char **r_blockdev); +gpg_error_t call_syshelp_get_keyblob (ctrl_t ctrl, + void **r_enckeyblob, + size_t *r_enckeybloblen); gpg_error_t call_syshelp_set_device (ctrl_t ctrl, const char *fname); gpg_error_t call_syshelp_run_create (ctrl_t ctrl, int conttype); gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, diff --git a/g13/mount.c b/g13/mount.c index 951a859..d682585 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -38,6 +38,7 @@ #include "host2net.h" #include "server.h" /*(g13_keyblob_decrypt)*/ #include "../common/sysutils.h" +#include "call-syshelp.h" /* Mount the container with name FILENAME at MOUNTPOINT. */ @@ -46,7 +47,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) { gpg_error_t err; dotlock_t lock; - int needs_syshelp; + int needs_syshelp = 0; void *enckeyblob = NULL; size_t enckeybloblen; void *keyblob = NULL; @@ -57,16 +58,28 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) int conttype; unsigned int rid; char *mountpoint_buffer = NULL; + char *blockdev_buffer = NULL; /* A quick check to see whether the container exists. */ - if (access (filename, R_OK)) + if (access (filename, F_OK)) return gpg_error_from_syserror (); /* Decide whether we need to use the g13-syshelp because we can't use lock files for them. This is most likely the case for device files; thus we test for this. FIXME: The correct solution would be to call g13-syshelp to match the file against the g13tab. */ - needs_syshelp = !strncmp (filename, "/dev/", 5); + err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer); + if (!err) + { + needs_syshelp = 1; + filename = blockdev_buffer; + } + else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND) + { + log_error ("error finding device '%s': %s <%s>\n", + filename, gpg_strerror (err), gpg_strsource (err)); + return err; + } if (!mountpoint) { @@ -105,20 +118,27 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) } /* Check again that the file exists. */ - { - struct stat sb; + if (!needs_syshelp) + { + struct stat sb; - if (stat (filename, &sb)) - { - err = gpg_error_from_syserror (); - goto leave; - } - } + if (stat (filename, &sb)) + { + err = gpg_error_from_syserror (); + goto leave; + } + } /* Read the encrypted keyblob. */ - /* Fixme: Should we move this to syshelp for dm-crypt or do we - assume that the encrypted device is world readable? */ - err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen); + if (needs_syshelp) + { + err = call_syshelp_set_device (ctrl, filename); + if (err) + goto leave; + err = call_syshelp_get_keyblob (ctrl, &enckeyblob, &enckeybloblen); + } + else + err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen); if (err) goto leave; @@ -186,6 +206,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) xfree (enckeyblob); dotlock_destroy (lock); xfree (mountpoint_buffer); + xfree (blockdev_buffer); return err; } @@ -203,6 +224,7 @@ g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) if (!filename && !mountpoint) return gpg_error (GPG_ERR_ENOENT); + err = mountinfo_find_mount (filename, mountpoint, &rid); if (err) return err; diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index e00bb77..10b1ba9 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -383,6 +383,52 @@ cmd_create (assuan_context_t ctx, char *line) } +static const char hlp_getkeyblob[] = + "GETKEYBLOB\n" + "\n" + "Return the encrypted keyblob of the current device."; +static gpg_error_t +cmd_getkeyblob (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + void *enckeyblob = NULL; + size_t enckeybloblen; + + line = skip_options (line); + + if (!ctrl->server_local->devicename + || !ctrl->server_local->devicefp + || !ctrl->devti) + { + err = set_error (GPG_ERR_ENOENT, "No device has been set"); + goto leave; + } + + err = sh_is_empty_partition (ctrl->server_local->devicename); + if (!err) + { + err = gpg_error (GPG_ERR_ENODEV); + assuan_set_error (ctx, err, "Partition is empty"); + goto leave; + } + err = 0; + + err = g13_keyblob_read (ctrl->server_local->devicename, + &enckeyblob, &enckeybloblen); + if (err) + goto leave; + + err = assuan_send_data (ctx, enckeyblob, enckeybloblen); + if (!err) + err = assuan_send_data (ctx, NULL, 0); /* Flush */ + + leave: + xfree (enckeyblob); + return leave_cmd (ctx, err); +} + + static const char hlp_mount[] = "MOUNT \n" "\n" @@ -667,6 +713,7 @@ register_commands (assuan_context_t ctx, int fail_all) { "FINDDEVICE", cmd_finddevice, hlp_finddevice }, { "DEVICE", cmd_device, hlp_device }, { "CREATE", cmd_create, hlp_create }, + { "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob }, { "MOUNT", cmd_mount, hlp_mount }, { "SUSPEND", cmd_suspend,hlp_suspend}, { "RESUME", cmd_resume, hlp_resume }, commit 37e932658cbd873ac96ff7e2067a97dffc2e0507 Author: Werner Koch Date: Sat Aug 13 17:39:28 2016 +0200 g13: Move some function around. * g13/keyblob.c (g13_keyblob_decrypt): Move to ... * g13/server.c: to here. * g13/suspend.c, g13/mount.c: Include server.h. * g13/Makefile.am (g13_syshelp_SOURCES): Add keyblob.c -- This is done to be able to use keyblob read code in syshelp w/o requiring linking to call-gpg.c Signed-off-by: Werner Koch diff --git a/g13/Makefile.am b/g13/Makefile.am index 05963c8..90dd471 100644 --- a/g13/Makefile.am +++ b/g13/Makefile.am @@ -57,7 +57,7 @@ g13_LDADD = $(libcommonpth) \ g13_syshelp_SOURCES = \ g13-syshelp.c g13-syshelp.h \ g13-common.c g13-common.h \ - keyblob.h \ + keyblob.c keyblob.h \ g13tuple.c g13tuple.h \ sh-cmd.c \ sh-blockdev.c \ diff --git a/g13/keyblob.c b/g13/keyblob.c index cad0c4f..8a5b622 100644 --- a/g13/keyblob.c +++ b/g13/keyblob.c @@ -28,12 +28,10 @@ #include #include "g13.h" -#include "i18n.h" #include "mount.h" #include "keyblob.h" #include "../common/sysutils.h" -#include "../common/call-gpg.h" #include "host2net.h" @@ -207,23 +205,3 @@ g13_keyblob_read (const char *filename, return err; } - - -/* - * Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result - * at (R_KEYBLOB, R_KEYBLOBLEN). Returns 0 on success or an error - * code. On error R_KEYBLOB is set to NULL. - */ -gpg_error_t -g13_keyblob_decrypt (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen, - void **r_keyblob, size_t *r_keybloblen) -{ - gpg_error_t err; - - /* FIXME: For now we only implement OpenPGP. */ - err = gpg_decrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments, - enckeyblob, enckeybloblen, - r_keyblob, r_keybloblen); - - return err; -} diff --git a/g13/keyblob.h b/g13/keyblob.h index 3415e9a..48f0b9c 100644 --- a/g13/keyblob.h +++ b/g13/keyblob.h @@ -157,9 +157,6 @@ gpg_error_t g13_is_container (ctrl_t ctrl, const char *filename); gpg_error_t g13_keyblob_read (const char *filename, void **r_enckeyblob, size_t *r_enckeybloblen); -gpg_error_t g13_keyblob_decrypt (ctrl_t ctrl, - const void *enckeyblob, size_t enckeybloblen, - void **r_keyblob, size_t *r_keybloblen); #endif /*G13_KEYBLOB_H*/ diff --git a/g13/mount.c b/g13/mount.c index 272cd77..951a859 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -36,6 +36,7 @@ #include "mountinfo.h" #include "runner.h" #include "host2net.h" +#include "server.h" /*(g13_keyblob_decrypt)*/ #include "../common/sysutils.h" diff --git a/g13/server.c b/g13/server.c index a96ec6e..5a273c2 100644 --- a/g13/server.c +++ b/g13/server.c @@ -34,6 +34,8 @@ #include "mount.h" #include "suspend.h" #include "../common/server-help.h" +#include "../common/call-gpg.h" + /* The filepointer for status message used in non-server mode */ static FILE *statusfp; @@ -769,3 +771,28 @@ g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line) return 0; return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0); } + + +/* + * Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result + * at (R_KEYBLOB, R_KEYBLOBLEN). Returns 0 on success or an error + * code. On error R_KEYBLOB is set to NULL. + * + * This actually does not belong here but for that simple wrapper it + * does not make sense to add another source file. Note that we do + * not want to have this in keyblob.c, because that code is also used + * by the syshelp. + */ +gpg_error_t +g13_keyblob_decrypt (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen, + void **r_keyblob, size_t *r_keybloblen) +{ + gpg_error_t err; + + /* FIXME: For now we only implement OpenPGP. */ + err = gpg_decrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments, + enckeyblob, enckeybloblen, + r_keyblob, r_keybloblen); + + return err; +} diff --git a/g13/server.h b/g13/server.h index af8494a..41636c8 100644 --- a/g13/server.h +++ b/g13/server.h @@ -25,4 +25,8 @@ gpg_error_t g13_server (ctrl_t ctrl); gpg_error_t g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line); +gpg_error_t g13_keyblob_decrypt (ctrl_t ctrl, + const void *enckeyblob, size_t enckeybloblen, + void **r_keyblob, size_t *r_keybloblen); + #endif /*G13_SERVER_H*/ diff --git a/g13/suspend.c b/g13/suspend.c index 0532c8b..39aeaeb 100644 --- a/g13/suspend.c +++ b/g13/suspend.c @@ -33,6 +33,7 @@ #include "keyblob.h" #include "backend.h" #include "g13tuple.h" +#include "server.h" /*(g13_keyblob_decrypt)*/ ----------------------------------------------------------------------- Summary of changes: g13/Makefile.am | 2 +- g13/backend.c | 18 +++++++++ g13/backend.h | 1 + g13/be-dmcrypt.c | 17 ++++++++ g13/be-dmcrypt.h | 1 + g13/call-syshelp.c | 80 +++++++++++++++++++++++++++++++++++++ g13/call-syshelp.h | 4 ++ g13/g13-syshelp.h | 1 + g13/g13.c | 7 ++-- g13/keyblob.c | 22 ---------- g13/keyblob.h | 3 -- g13/mount.c | 115 +++++++++++++++++++++++++++++++++++++---------------- g13/server.c | 27 +++++++++++++ g13/server.h | 4 ++ g13/sh-cmd.c | 84 +++++++++++++++++++++++++++++++++++++- g13/sh-dmcrypt.c | 93 +++++++++++++++++++++++++++++++++++++++++++ g13/suspend.c | 1 + 17 files changed, 414 insertions(+), 66 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 15 10:47:16 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 15 Aug 2016 10:47:16 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-1.4.0-6-g7f0a05e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 7f0a05e9133d8e16f42fad6b972732197978d55b (commit) via 657c99a1bdae8625a06f2baa30d06334ffe1af53 (commit) from c8cdb4c9a9bb590b8785b483cf71657e20e0b92d (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 7f0a05e9133d8e16f42fad6b972732197978d55b Author: Andre Heinecke Date: Mon Aug 15 10:45:13 2016 +0200 Fix sign only preselection * src/mailitem-events.cpp (MailItemEvents Open): Init draft_flags. -- If sign and not encrypt was selected draft_flags was used uninitalized. GnuPG-Bug-Id: 2341 diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index ddeecfc..6919b14 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -135,7 +135,7 @@ EVENT_SINK_INVOKE(MailItemEvents) case Open: { LPMESSAGE message; - int draft_flags; + int draft_flags = 0; if (!opt.encrypt_default && !opt.sign_default) { return S_OK; commit 657c99a1bdae8625a06f2baa30d06334ffe1af53 Author: Andre Heinecke Date: Mon Aug 15 10:44:27 2016 +0200 Fix minor typo in eventsink debug * src/eventsink.h: tdor->dtor diff --git a/src/eventsink.h b/src/eventsink.h index 83e6772..26aaad8 100644 --- a/src/eventsink.h +++ b/src/eventsink.h @@ -92,7 +92,7 @@ STDMETHODIMP subcls::Invoke (DISPID dispid, REFIID riid, LCID lcid, \ #define EVENT_SINK_DEFAULT_DTOR_CODE(subcls) \ { \ if (debug_oom) \ - log_debug ("%s:" #subcls ":%s: tdor", SRCNAME, __func__); \ + log_debug ("%s:" #subcls ":%s: dtor", SRCNAME, __func__); \ if (m_pCP) \ m_pCP->Unadvise(m_cookie); \ if (m_object) \ ----------------------------------------------------------------------- Summary of changes: src/eventsink.h | 2 +- src/mailitem-events.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 15 14:05:49 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 15 Aug 2016 14:05:49 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-1.4.0-10-g2b7009c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 2b7009cb713145d858be3f7ec418799f447054aa (commit) via 6b5acfcb5f89e4a460e859aa42b347e4474e96cc (commit) via 683e4136aca4091a8e616c3364cff160a335f6ba (commit) via 037a5a7edf36038b28d2fb2bdb1e7ffeb6cb1756 (commit) from 7f0a05e9133d8e16f42fad6b972732197978d55b (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 2b7009cb713145d858be3f7ec418799f447054aa Author: Andre Heinecke Date: Mon Aug 15 12:14:51 2016 +0200 Unify COM Release and add debugging * src/util.h (gpgol_release): New. Adds debugging for debug_oom_extra. * src/attached-file-events.cpp, src/attachment.cpp, src/attic.c, src/display.cpp, src/eventsink.h, src/explorers.cpp, src/ext-commands.cpp, src/inspectors.cpp, src/item-events.cpp, src/mailitem-events.cpp, src/mailitem.cpp, src/mapihelp.cpp, src/message-events.cpp, src/message.cpp, src/mlang-charset.cpp, src/olflange.cpp, src/oomhelp.cpp, src/oomhelp.h, src/revert.cpp, src/ribbon-callbacks.cpp: Use gpgol_release. -- This may help analyse rare crashes in case we have made an error with refcounting / releasing somewhere. diff --git a/src/attached-file-events.cpp b/src/attached-file-events.cpp index 6ae4f0b..94b99a3 100644 --- a/src/attached-file-events.cpp +++ b/src/attached-file-events.cpp @@ -202,7 +202,7 @@ GpgolAttachedFileEvents::OnWritePattToSzFile if (hr) { log_debug ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr); - stream->Release (); + gpgol_release (stream); symenc_close (symenc); return E_ABORT; } @@ -214,14 +214,14 @@ GpgolAttachedFileEvents::OnWritePattToSzFile "Please use the decrypt/verify button to decrypt the\n" "entire message again. Then open this attachment."), "GpgOL", MB_ICONERROR|MB_OK); - stream->Release (); + gpgol_release (stream); symenc_close (symenc); return E_ABORT; } rc = decrypt_and_write_file (stream, file, symenc); - stream->Release (); + gpgol_release (stream); symenc_close (symenc); return rc; } diff --git a/src/attachment.cpp b/src/attachment.cpp index 0ccf2d9..6f31510 100644 --- a/src/attachment.cpp +++ b/src/attachment.cpp @@ -298,7 +298,7 @@ do_crypt (LPDISPATCH mailitem, bool protect) { log_debug ("%s:%s: Failed to get MapiObject of attachment: %p", SRCNAME, __func__, attachment); - attachment->Release (); + gpgol_release (attachment); continue; } @@ -310,13 +310,13 @@ do_crypt (LPDISPATCH mailitem, bool protect) { log_error ("%s:%s: Error: Session crypto failed.", SRCNAME, __func__); - mapi_attachment->Release (); - attachment->Release (); + gpgol_release (mapi_attachment); + gpgol_release (attachment); goto done; } } - mapi_attachment->Release (); - attachment->Release (); + gpgol_release (mapi_attachment); + gpgol_release (attachment); } err = 0; diff --git a/src/attic.c b/src/attic.c index 1218eaa..4c30f9a 100644 --- a/src/attic.c +++ b/src/attic.c @@ -31,7 +31,7 @@ is_preview_pane_visible (LPEXCHEXTCALLBACK eecb) hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, &rVariant, NULL, NULL); - pDisp->Release(); + gpgol_release (pDisp); pDisp = NULL; if (hr == S_OK && rVariant.vt != VT_BOOL) { @@ -84,7 +84,7 @@ show_preview_pane (LPEXCHEXTCALLBACK eecb, int visible) hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); - pDisp->Release(); + gpgol_release (pDisp); pDisp = NULL; if (hr != S_OK) log_debug ("%s:%s: invoking ShowPane(%d) failed: %#lx", diff --git a/src/display.cpp b/src/display.cpp index bd10921..ecba56a 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -263,7 +263,7 @@ update_display (HWND hwnd, LPDISPATCH inspector, int is_sensitive, put_oom_string (item, "Body", ""); } rc = put_oom_string (item, is_html? "HTMLBody":"Body", text); - item->Release (); + gpgol_release (item); } else rc = -1; @@ -361,7 +361,7 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) if (!entryid) { log_error ("%s:%s: PR_ENTRYID missing\n", SRCNAME, __func__); - session->Release (); + gpgol_release (session); return -1; } log_hexdump (entryid, entryidlen, "orig entryid="); @@ -370,7 +370,7 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) if (!store_entryid) { log_error ("%s:%s: PR_STORE_ENTRYID missing\n", SRCNAME, __func__); - session->Release (); + gpgol_release (session); xfree (entryid); return -1; } @@ -379,7 +379,7 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) if (!parent_entryid) { log_error ("%s:%s: PR_PARENT_ENTRYID missing\n", SRCNAME, __func__); - session->Release (); + gpgol_release (session); xfree (store_entryid); xfree (entryid); return -1; @@ -393,7 +393,7 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) { log_error ("%s:%s: OpenMsgStore failed: hr=%#lx\n", SRCNAME, __func__, hr); - session->Release (); + gpgol_release (session); xfree (parent_entryid); xfree (store_entryid); xfree (entryid); @@ -408,11 +408,11 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) { log_error ("%s:%s: OpenEntry failed: hr=%#lx\n", SRCNAME, __func__, hr); - session->Release (); + gpgol_release (session); xfree (parent_entryid); xfree (store_entryid); xfree (entryid); - mdb->Release (); + gpgol_release (mdb); return -1; } log_debug ("%s:%s: mdb::OpenEntry succeeded type=%lx\n", @@ -426,12 +426,12 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) { log_error ("%s:%s: OpenEntry[folder] failed: hr=%#lx\n", SRCNAME, __func__, hr); - session->Release (); + gpgol_release (session); xfree (parent_entryid); xfree (store_entryid); xfree (entryid); - mdb->Release (); - mfolder->Release (); + gpgol_release (mdb); + gpgol_release (mfolder); return -1; } log_debug ("%s:%s: mdb::OpenEntry[message] succeeded type=%lx\n", @@ -443,18 +443,18 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) { log_error ("%s:%s: PrepareForm failed: hr=%#lx\n", SRCNAME, __func__, hr); - session->Release (); + gpgol_release (session); xfree (parent_entryid); xfree (store_entryid); xfree (entryid); - mdb->Release (); - mfolder->Release (); - message2->Release (); + gpgol_release (mdb); + gpgol_release (mfolder); + gpgol_release (message2); return -1; } /* Message2 is now represented by TOKEN; we need to release it. */ - message2->Release(); message2 = NULL; + gpgol_release (message2); message2 = NULL; hr = session->ShowForm (0, mdb, mfolder, @@ -466,12 +466,12 @@ open_inspector (LPEXCHEXTCALLBACK peecb, LPMESSAGE message) log_debug ("%s:%s: ShowForm result: hr=%#lx\n", SRCNAME, __func__, hr); - session->Release (); + gpgol_release (session); xfree (parent_entryid); xfree (store_entryid); xfree (entryid); - mdb->Release (); - mfolder->Release (); + gpgol_release (mdb); + gpgol_release (mfolder); return FAILED(hr)? -1:0; } diff --git a/src/eventsink.h b/src/eventsink.h index 26aaad8..3eb900c 100644 --- a/src/eventsink.h +++ b/src/eventsink.h @@ -96,7 +96,7 @@ STDMETHODIMP subcls::Invoke (DISPID dispid, REFIID riid, LCID lcid, \ if (m_pCP) \ m_pCP->Unadvise(m_cookie); \ if (m_object) \ - m_object->Release(); \ + gpgol_release (m_object); \ } \ /* End of macro EVENT_SINK_DTOR_DEFAULT_CODE. */ @@ -179,18 +179,18 @@ LPDISPATCH install_ ## subcls ## _sink (LPDISPATCH object) \ { \ log_error ("%s:%s:%s: ConnectionPoint not found: hr=%#lx", \ SRCNAME,#subcls, __func__, hr); \ - pCPC->Release (); \ + gpgol_release (pCPC); \ return NULL; \ } \ sink = new subcls; /* Note: Advise does another AddRef. */ \ hr = pCP->Advise ((LPUNKNOWN)sink, &cookie); \ - pCPC->Release (); \ + gpgol_release (pCPC); \ if (hr != S_OK) \ { \ log_error ("%s:%s:%s: Advice failed: hr=%#lx", \ SRCNAME, #subcls, __func__, hr); \ - pCP->Release (); \ - sink->Release (); \ + gpgol_release (pCP); \ + gpgol_release (sink); \ return NULL; \ } \ if (debug_oom) \ @@ -226,7 +226,7 @@ void detach_ ## subcls ## _sink (LPDISPATCH obj) \ if (debug_oom_extra) \ log_debug ("%s:%s:%s: Releasing connt point", \ SRCNAME, #subcls, __func__); \ - sink->m_pCP->Release (); \ + gpgol_release (sink->m_pCP); \ sink->m_pCP = NULL; \ } \ if (sink->m_object) \ @@ -234,10 +234,10 @@ void detach_ ## subcls ## _sink (LPDISPATCH obj) \ if (debug_oom_extra) \ log_debug ("%s:%s:%s: Releasing actual object", \ SRCNAME, #subcls, __func__); \ - sink->m_object->Release (); \ + gpgol_release (sink->m_object); \ sink->m_object = NULL; \ } \ - sink->Release (); \ + gpgol_release (sink); \ } \ /* End of macro END_EVENT_SINK. */ diff --git a/src/explorers.cpp b/src/explorers.cpp index 388fdff..68193bb 100644 --- a/src/explorers.cpp +++ b/src/explorers.cpp @@ -95,11 +95,11 @@ add_explorer_controls (LPOOMEXPLORER explorer) return; } button = get_oom_control_bytag (obj, "GpgOL_Start_Key_Manager"); - obj->Release (); + gpgol_release (obj); obj = NULL; if (button) { - button->Release (); + gpgol_release (button); log_debug ("%s:%s: Leave (Controls are already added)", SRCNAME, __func__); return; @@ -128,7 +128,7 @@ add_explorer_controls (LPOOMEXPLORER explorer) install_GpgolCommandBarButtonEvents_sink (button); /* Fixme: Save the returned object for an Unadvice. */ - button->Release (); + gpgol_release (button); } button = add_oom_button (controls); @@ -141,10 +141,10 @@ add_explorer_controls (LPOOMEXPLORER explorer) install_GpgolCommandBarButtonEvents_sink (button); /* Fixme: Save the returned object for an Unadvice. */ - button->Release (); + gpgol_release (button); } - controls->Release (); + gpgol_release (controls); controls = NULL; } @@ -169,9 +169,9 @@ add_explorer_controls (LPOOMEXPLORER explorer) install_GpgolCommandBarButtonEvents_sink (button); /* Fixme: store the event sink object somewhere. */ - button->Release (); + gpgol_release (button); } - controls->Release (); + gpgol_release (controls); } log_debug ("%s:%s: Leave", SRCNAME, __func__); @@ -217,7 +217,7 @@ run_explorer_revert_folder (LPDISPATCH button) if (obj) { gpgol_folder_revert (obj); - obj->Release (); + gpgol_release (obj); } } } diff --git a/src/ext-commands.cpp b/src/ext-commands.cpp index 0411cf0..82f978f 100644 --- a/src/ext-commands.cpp +++ b/src/ext-commands.cpp @@ -119,7 +119,7 @@ get_inspector (LPEXCHEXTCALLBACK eecb, HWND hwnd) { /* This should be MailItem; use the getInspector method. */ inspector = get_oom_object (obj, "GetInspector"); - obj->Release (); + gpgol_release (obj); } } return inspector; @@ -144,7 +144,7 @@ get_crypto_flags (LPEXCHEXTCALLBACK eecb, HWND hwnd, else { rc = get_inspector_composer_flags (inspector, r_sign, r_encrypt); - inspector->Release (); + gpgol_release (inspector); } return rc; } @@ -161,7 +161,7 @@ set_crypto_flags (LPEXCHEXTCALLBACK eecb, HWND hwnd, bool sign, bool encrypt) else { set_inspector_composer_flags (inspector, sign, encrypt); - inspector->Release (); + gpgol_release (inspector); } } @@ -256,7 +256,7 @@ GpgolExtCommands::InstallCommands ( msgcache_unref (refhandle); xfree (key); } - obj->Release (); + gpgol_release (obj); } } @@ -345,7 +345,7 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID) hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL); - pDisp->Release(); + gpgol_release (pDisp); pDisp = NULL; if (hr == S_OK) { @@ -360,7 +360,7 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID) else { if (pDisp) - pDisp->Release (); + gpgol_release (pDisp); log_debug ("%s:%s: invoking Close failed: no Close method)", SRCNAME, __func__); } diff --git a/src/inspectors.cpp b/src/inspectors.cpp index 729a7e9..631839b 100644 --- a/src/inspectors.cpp +++ b/src/inspectors.cpp @@ -250,7 +250,7 @@ find_ole_window (LPOOMINSPECTOR inspector) SRCNAME, __func__, hr); hwnd = NULL; } - olewndw->Release (); + gpgol_release (olewndw); log_debug ("%s:%s: inspector %p has hwnd=%p", SRCNAME, __func__, inspector, hwnd); return hwnd; @@ -324,18 +324,18 @@ deregister_inspector (LPGPGOLINSPECTOREVENTS sink) if (ol->sink) { detach_GpgolCommandBarButtonEvents_sink (ol->sink); - ol->sink->Release (); + gpgol_release (ol->sink); } if (ol->button) { del_oom_button (ol->button); - ol->button->Release (); + gpgol_release (ol->button); } xfree (ol); } - r->inspector->Release (); - r->eventsink->Release (); + gpgol_release (r->inspector); + gpgol_release (r->eventsink); xfree (r); } @@ -462,9 +462,9 @@ GpgolInspectorsEvents::NewInspector (LPOOMINSPECTOR inspector) if (obj) { register_inspector ((LPGPGOLINSPECTOREVENTS)obj, inspector); - obj->Release (); + gpgol_release (obj); } - inspector->Release (); + gpgol_release (inspector); return S_OK; } @@ -517,13 +517,13 @@ GpgolInspectorEvents::Activate (void) { // LPDISPATCH obj2 = install_GpgolItemEvents_sink (obj); // if (obj2) - // obj2->Release (); - obj->Release (); + // gpgol_release (obj2); + gpgol_release (obj); } } update_crypto_info (inspector); - inspector->Release (); + gpgol_release (inspector); } @@ -550,7 +550,7 @@ is_inspector_in_composer_mode (LPDISPATCH inspector) the class is 43. */ in_composer = (!get_oom_bool (obj, "Sent") && get_oom_int (obj, "Class") == 43); - obj->Release (); + gpgol_release (obj); } else in_composer = false; @@ -576,7 +576,7 @@ get_inspector_composer_flags (LPDISPATCH inspector, else { *r_sign = get_oom_int (button, "State") == msoButtonDown; - button->Release (); + gpgol_release (button); } button = get_button (inspector, "GpgOL_Inspector_Encrypt"); @@ -588,7 +588,7 @@ get_inspector_composer_flags (LPDISPATCH inspector, else { *r_encrypt = get_oom_int (button, "State") == msoButtonDown; - button->Release (); + gpgol_release (button); } if (!rc) @@ -614,7 +614,7 @@ set_one_button (LPDISPATCH inspector, const char *tag, bool down) { if (put_oom_int (button, "State", down? msoButtonDown : msoButtonUp)) rc = -1; - button->Release (); + gpgol_release (button); } return rc; } @@ -710,7 +710,7 @@ add_inspector_controls (LPOOMINSPECTOR inspector) move_to_button_list (&buttonlist, obj, button, tag); } - controls->Release (); + gpgol_release (controls); } } @@ -770,7 +770,7 @@ add_inspector_controls (LPOOMINSPECTOR inspector) move_to_button_list (&buttonlist, obj, button, tag); } - controls->Release (); + gpgol_release (controls); } @@ -824,7 +824,7 @@ add_inspector_controls (LPOOMINSPECTOR inspector) move_to_button_list (&buttonlist, obj, button, tag); } - controls->Release (); + gpgol_release (controls); } @@ -844,9 +844,9 @@ add_inspector_controls (LPOOMINSPECTOR inspector) { ol2 = ol->next; if (ol->sink) - ol->sink->Release (); + gpgol_release (ol->sink); if (ol->button) - ol->button->Release (); + gpgol_release (ol->button); xfree (ol); } } @@ -892,9 +892,9 @@ update_crypto_info (LPDISPATCH inspector) log_error ("%s:%s: error getting IMESSAGE: hr=%#lx", SRCNAME, __func__, hr); } - unknown->Release (); + gpgol_release (unknown); } - obj->Release (); + gpgol_release (obj); } if (message) { @@ -938,7 +938,7 @@ update_crypto_info (LPDISPATCH inspector) iconrc = IDB_DECRYPT_16; } - message->Release (); + gpgol_release (message); } } @@ -946,7 +946,7 @@ update_crypto_info (LPDISPATCH inspector) if (iconrc != -1) put_oom_icon (button, iconrc, 16); put_oom_bool (button, "Visible", (iconrc != -1)); - button->Release (); + gpgol_release (button); } @@ -982,14 +982,14 @@ get_message_from_button (unsigned long instid, LPDISPATCH *r_inspector) log_error ("%s:%s: error getting IMESSAGE: hr=%#lx", SRCNAME, __func__, hr); } - unknown->Release (); + gpgol_release (unknown); } - obj->Release (); + gpgol_release (obj); } if (r_inspector) *r_inspector = inspector; else - inspector->Release (); + gpgol_release (inspector); } return message; } @@ -1028,7 +1028,7 @@ toggle_button (LPDISPATCH button, const char *tag, int instid) log_debug ("%s:%s: setting `%s' state to %d", SRCNAME, __func__, tag2, state); set_one_button (inspector, tag2, state); - inspector->Release (); + gpgol_release (inspector); } @@ -1059,12 +1059,12 @@ proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid) { if (message_incoming_handler (message, hwnd, true)) message_display_handler (message, inspector, hwnd); - message->Release (); + gpgol_release (message); } if (inspector) { update_crypto_info (inspector); - inspector->Release (); + gpgol_release (inspector); } } else if (!tagcmp (tag, "GpgOL_Inspector_Debug-0")) @@ -1075,7 +1075,7 @@ proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid) if (message) { message_show_info (message, hwnd); - message->Release (); + gpgol_release (message); } } else if (!tagcmp (tag, "GpgOL_Inspector_Debug-1")) @@ -1092,7 +1092,7 @@ proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid) { /* We sync here. */ mapi_change_message_class (message, 1); - message->Release (); + gpgol_release (message); } } else if (!tagcmp (tag, "GpgOL_Inspector_Debug-3")) @@ -1106,7 +1106,7 @@ proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid) KEEP_OPEN_READWRITE|FORCE_SAVE); log_debug ("%s:%s: gpgol_message_revert returns %d\n", SRCNAME, __func__, rc); - message->Release (); + gpgol_release (message); } } diff --git a/src/item-events.cpp b/src/item-events.cpp index 36305f0..7e1aa39 100644 --- a/src/item-events.cpp +++ b/src/item-events.cpp @@ -155,9 +155,9 @@ GpgolItemEvents::OnOpenComplete (LPEXCHEXTCALLBACK eecb, ULONG flags) m_wasencrypted = true; } if (message) - message->Release (); + gpgol_release (message); if (mdb) - mdb->Release (); + gpgol_release (mdb); } return S_FALSE; diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index b376c53..5101610 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -90,7 +90,7 @@ MailItemEvents::~MailItemEvents() if (m_pCP) m_pCP->Unadvise(m_cookie); if (m_object) - m_object->Release(); + gpgol_release (m_object); } static DWORD WINAPI diff --git a/src/mailitem.cpp b/src/mailitem.cpp index b1ad383..817d238 100644 --- a/src/mailitem.cpp +++ b/src/mailitem.cpp @@ -182,7 +182,7 @@ GpgolItemEvents::Write (PBOOL cancel_default) log_error ("%s:%s: error getting IMESSAGE: hr=%#lx", SRCNAME, __func__, hr); } - unknown->Release (); + gpgol_release (unknown); } if (!message) diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index 25ef089..64fe721 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -491,7 +491,7 @@ mapi_get_body (LPMESSAGE message, size_t *r_nbytes) if (hr) { log_debug ("%s:%s: Stat failed: hr=%#lx", SRCNAME, __func__, hr); - stream->Release (); + gpgol_release (stream); return NULL; } @@ -504,7 +504,7 @@ mapi_get_body (LPMESSAGE message, size_t *r_nbytes) { log_debug ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr); xfree (body); - stream->Release (); + gpgol_release (stream); return NULL; } body[nread] = 0; @@ -513,10 +513,10 @@ mapi_get_body (LPMESSAGE message, size_t *r_nbytes) { log_debug ("%s:%s: not enough bytes returned\n", SRCNAME, __func__); xfree (body); - stream->Release (); + gpgol_release (stream); return NULL; } - stream->Release (); + gpgol_release (stream); { char *tmp; @@ -591,7 +591,7 @@ get_msgcls_from_pgp_lines (LPMESSAGE message) if (hr) { log_debug ("%s:%s: Stat failed: hr=%#lx", SRCNAME, __func__, hr); - stream->Release (); + gpgol_release (stream); return NULL; } @@ -606,7 +606,7 @@ get_msgcls_from_pgp_lines (LPMESSAGE message) { log_debug ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr); xfree (body); - stream->Release (); + gpgol_release (stream); return NULL; } body[nread] = 0; @@ -616,10 +616,10 @@ get_msgcls_from_pgp_lines (LPMESSAGE message) log_debug ("%s:%s: not enough bytes returned\n", SRCNAME, __func__); xfree (body); - stream->Release (); + gpgol_release (stream); return NULL; } - stream->Release (); + gpgol_release (stream); if (!is_binary) { @@ -717,14 +717,14 @@ is_really_cms_encrypted (LPMESSAGE message) { log_debug ("%s:%s: HrQueryAllRows failed: hr=%#lx", SRCNAME, __func__, hr); - mapitable->Release (); + gpgol_release (mapitable); return -1; } n_attach = mapirows->cRows > 0? mapirows->cRows : 0; if (n_attach != 1) { FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); log_debug ("%s:%s: not just one attachment", SRCNAME, __func__); return -1; } @@ -805,11 +805,11 @@ is_really_cms_encrypted (LPMESSAGE message) leave: if (stream) - stream->Release (); + gpgol_release (stream); if (att) - att->Release (); + gpgol_release (att); FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); return result; } @@ -842,14 +842,14 @@ get_first_attach_mime_tag (LPMESSAGE message) { log_debug ("%s:%s: HrQueryAllRows failed: hr=%#lx", SRCNAME, __func__, hr); - mapitable->Release (); + gpgol_release (mapitable); return NULL; } n_attach = mapirows->cRows > 0? mapirows->cRows : 0; if (n_attach != 1) { FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); log_debug ("%s:%s: not just one attachment", SRCNAME, __func__); return NULL; } @@ -887,9 +887,9 @@ get_first_attach_mime_tag (LPMESSAGE message) leave: if (att) - att->Release (); + gpgol_release (att); FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); return result; } @@ -1789,10 +1789,10 @@ mapi_to_mime (LPMESSAGE message, const char *filename) hr = 0; } - stream->Release (); + gpgol_release (stream); } - session->Release (); + gpgol_release (session); return hr; } @@ -2037,7 +2037,7 @@ mapi_create_attach_table (LPMESSAGE message, int fast) { log_debug ("%s:%s: HrQueryAllRows failed: hr=%#lx", SRCNAME, __func__, hr); - mapitable->Release (); + gpgol_release (mapitable); return NULL; } n_attach = mapirows->cRows > 0? mapirows->cRows : 0; @@ -2047,7 +2047,7 @@ mapi_create_attach_table (LPMESSAGE message, int fast) if (!n_attach) { FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); return NULL; } @@ -2098,7 +2098,7 @@ mapi_create_attach_table (LPMESSAGE message, int fast) } } table[pos].attach_type = get_gpgolattachtype (att, moss_tag); - att->Release (); + gpgol_release (att); } table[0].private_mapitable = mapitable; FreeProws (mapirows); @@ -2139,7 +2139,7 @@ mapi_release_attach_table (mapi_attach_item_t *table) mapitable = (LPMAPITABLE)table[0].private_mapitable; if (mapitable) - mapitable->Release (); + gpgol_release (mapitable); for (pos=0; !table[pos].end_of_table; pos++) { xfree (table[pos].filename); @@ -2177,7 +2177,7 @@ mapi_get_attach_as_stream (LPMESSAGE message, mapi_attach_item_t *item, if (item->method != ATTACH_BY_VALUE) { log_error ("%s:%s: attachment: method not supported", SRCNAME, __func__); - att->Release (); + gpgol_release (att); return NULL; } @@ -2187,14 +2187,14 @@ mapi_get_attach_as_stream (LPMESSAGE message, mapi_attach_item_t *item, { log_error ("%s:%s: can't open data stream of attachment: hr=%#lx", SRCNAME, __func__, hr); - att->Release (); + gpgol_release (att); return NULL; } if (r_attach) *r_attach = att; else - att->Release (); + gpgol_release (att); return stream; } @@ -2251,7 +2251,7 @@ attach_to_buffer (LPATTACH att, size_t *r_nbytes, int unprotect, if ( hr != S_OK ) { log_error ("%s:%s: Stat failed: hr=%#lx", SRCNAME, __func__, hr); - stream->Release (); + gpgol_release (stream); return NULL; } @@ -2263,7 +2263,7 @@ attach_to_buffer (LPATTACH att, size_t *r_nbytes, int unprotect, { log_error ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr); xfree (buffer); - stream->Release (); + gpgol_release (stream); return NULL; } if (nread != statInfo.cbSize.QuadPart) @@ -2272,7 +2272,7 @@ attach_to_buffer (LPATTACH att, size_t *r_nbytes, int unprotect, xfree (buffer); buffer = NULL; } - stream->Release (); + gpgol_release (stream); if (buffer && symenc) { @@ -2331,12 +2331,12 @@ mapi_get_attach (LPMESSAGE message, int unprotect, if (item->method != ATTACH_BY_VALUE) { log_error ("%s:%s: attachment: method not supported", SRCNAME, __func__); - att->Release (); + gpgol_release (att); return NULL; } buffer = attach_to_buffer (att, r_nbytes, unprotect, NULL); - att->Release (); + gpgol_release (att); return buffer; } @@ -2396,7 +2396,7 @@ mapi_mark_moss_attach (LPMESSAGE message, mapi_attach_item_t *item) retval = 0; leave: - att->Release (); + gpgol_release (att); return retval; } @@ -3089,14 +3089,14 @@ mapi_get_gpgol_body_attachment (LPMESSAGE message, { log_debug ("%s:%s: HrQueryAllRows failed: hr=%#lx", SRCNAME, __func__, hr); - mapitable->Release (); + gpgol_release (mapitable); return -1; } n_attach = mapirows->cRows > 0? mapirows->cRows : 0; if (!n_attach) { FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); log_debug ("%s:%s: No attachments at all", SRCNAME, __func__); return -1; } @@ -3162,15 +3162,15 @@ mapi_get_gpgol_body_attachment (LPMESSAGE message, body = charset; } } - att->Release (); + gpgol_release (att); if (r_ishtml) *r_ishtml = (bodytype == 2); break; } - att->Release (); + gpgol_release (att); } FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); if (!found) { log_error ("%s:%s: no suitable body attachment found", SRCNAME,__func__); @@ -3219,14 +3219,14 @@ mapi_delete_gpgol_body_attachment (LPMESSAGE message) { log_debug ("%s:%s: HrQueryAllRows failed: hr=%#lx", SRCNAME, __func__, hr); - mapitable->Release (); + gpgol_release (mapitable); return 0; } n_attach = mapirows->cRows > 0? mapirows->cRows : 0; if (!n_attach) { FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); return 0; /* No Attachments. */ } @@ -3256,7 +3256,7 @@ mapi_delete_gpgol_body_attachment (LPMESSAGE message) if (has_gpgol_body_name (att) && get_gpgolattachtype (att, moss_tag) == ATTACHTYPE_FROMMOSS) { - att->Release (); + gpgol_release (att); hr = message->DeleteAttach (mapirows->aRow[pos].lpProps[0].Value.l, 0, NULL, 0); if (hr) @@ -3271,10 +3271,10 @@ mapi_delete_gpgol_body_attachment (LPMESSAGE message) } break; } - att->Release (); + gpgol_release (att); } FreeProws (mapirows); - mapitable->Release (); + gpgol_release (mapitable); return found; } @@ -3354,12 +3354,12 @@ mapi_attachment_to_body (LPMESSAGE message, mapi_attach_item_t *item) { if (result) outstream->Revert (); - outstream->Release (); + gpgol_release (outstream); } if (instream) - instream->Release (); + gpgol_release (instream); if (att) - att->Release (); + gpgol_release (att); return result; } diff --git a/src/message-events.cpp b/src/message-events.cpp index fe6e72e..41af63a 100644 --- a/src/message-events.cpp +++ b/src/message-events.cpp @@ -109,7 +109,7 @@ get_crypto_flags (HWND hwnd, bool *r_sign, bool *r_encrypt) else { rc = get_inspector_composer_flags (inspector, r_sign, r_encrypt); - inspector->Release (); + gpgol_release (inspector); } return rc; } @@ -218,17 +218,17 @@ GpgolMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK eecb, ULONG flags) if (opt.enable_debug & DBG_OOM) log_debug ("%s:%s: %p->GetInspector returned %p", SRCNAME, __func__, obj, inspector); - obj->Release (); + gpgol_release (obj); } } message_display_handler (message, inspector, hwnd); if (inspector) - inspector->Release (); + gpgol_release (inspector); } if (message) - message->Release (); + gpgol_release (message); if (mdb) - mdb->Release (); + gpgol_release (mdb); } @@ -265,7 +265,7 @@ GpgolMessageEvents::OnWrite (LPEXCHEXTCALLBACK eecb) else { bodyfmt = get_oom_int (obj, "BodyFormat"); - obj->Release (); + gpgol_release (obj); } if (bodyfmt == 1) diff --git a/src/message.cpp b/src/message.cpp index 3adc7ed..6fe6747 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -563,7 +563,7 @@ message_verify (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd) return -1; inbuf = pgp_mime_from_clearsigned (rawstream, &inbuflen); - rawstream->Release (); + gpgol_release (rawstream); if (!inbuf) return -1; protocol = PROTOCOL_OPENPGP; @@ -654,7 +654,7 @@ message_verify (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd) MessageBox (NULL, buf, "GpgOL", MB_ICONINFORMATION|MB_OK); } if (opaquestream) - opaquestream->Release (); + gpgol_release (opaquestream); xfree (inbuf); if (err) @@ -778,7 +778,7 @@ pgp_body_to_attachment (LPMESSAGE message) SRCNAME, __func__, hr); goto leave; } - outstream->Release (); + gpgol_release (outstream); outstream = NULL; hr = newatt->SaveChanges (0); if (hr) @@ -787,7 +787,7 @@ pgp_body_to_attachment (LPMESSAGE message) SRCNAME, __func__, hr); goto leave; } - newatt->Release (); + gpgol_release (newatt); newatt = NULL; hr = mapi_save_changes (message, KEEP_OPEN_READWRITE); @@ -795,11 +795,11 @@ pgp_body_to_attachment (LPMESSAGE message) if (outstream) { outstream->Revert (); - outstream->Release (); + gpgol_release (outstream); } if (newatt) - newatt->Release (); - instream->Release (); + gpgol_release (newatt); + gpgol_release (instream); return hr? -1:0; } @@ -1090,13 +1090,13 @@ message_decrypt (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd) } } - cipherstream->Release (); + gpgol_release (cipherstream); retval = 0; leave: if (saved_attach) - saved_attach->Release (); + gpgol_release (saved_attach); mapi_release_attach_table (table); return retval; } @@ -1139,7 +1139,7 @@ get_recipients (LPMESSAGE message) { log_debug_w32 (-1, "%s:%s: HrQueryAllRows failed", SRCNAME, __func__); if (lpRecipientTable) - lpRecipientTable->Release(); + gpgol_release (lpRecipientTable); return NULL; } @@ -1185,7 +1185,7 @@ get_recipients (LPMESSAGE message) } if (lpRecipientTable) - lpRecipientTable->Release(); + gpgol_release (lpRecipientTable); if (lpRecipientRows) FreeProws(lpRecipientRows); diff --git a/src/mlang-charset.cpp b/src/mlang-charset.cpp index 3c71d1d..128a428 100644 --- a/src/mlang-charset.cpp +++ b/src/mlang-charset.cpp @@ -19,7 +19,8 @@ * along with this program; if not, see . */ -#include "util.h" +#include "config.h" +#include "common.h" #define INITGUID #include DEFINE_GUID (IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f, @@ -56,7 +57,7 @@ char *ansi_charset_to_utf8 (const char *charset, char *input, { log_error ("%s:%s: Inlen too long. Bug.", SRCNAME, __func__); - multilang->Release(); + gpgol_release (multilang); return NULL; } @@ -71,7 +72,7 @@ char *ansi_charset_to_utf8 (const char *charset, char *input, { log_error ("%s:%s: Failed to find charset for: %s", SRCNAME, __func__, charset); - multilang->Release (); + gpgol_release (multilang); return NULL; } enc = (mime_info.uiInternetEncoding == 0) ? mime_info.uiCodePage : @@ -84,14 +85,14 @@ char *ansi_charset_to_utf8 (const char *charset, char *input, { log_error ("%s:%s: Failed conversion.", SRCNAME, __func__); - multilang->Release (); + gpgol_release (multilang); return NULL; } buf = (wchar_t*) xmalloc(sizeof(wchar_t) * (wlen + 1)); err = multilang->ConvertStringToUnicode(&mode, enc, input, &uinlen, buf, &wlen); - multilang->Release (); + gpgol_release (multilang); if (FAILED (err)) { log_error ("%s:%s: Failed conversion 2.", diff --git a/src/olflange.cpp b/src/olflange.cpp index 3850d06..1020da0 100644 --- a/src/olflange.cpp +++ b/src/olflange.cpp @@ -571,7 +571,7 @@ GpgolExt::~GpgolExt (void) SRCNAME, __func__, ext_context_name (m_lContext)); // if (m_pOutlookExtItemEvents) -// m_pOutlookExtItemEvents->Release (); +// gpgol_release (m_pOutlookExtItemEvents); if (m_lContext == EECONTEXT_SESSION || !m_lContext) { @@ -687,9 +687,9 @@ GpgolExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags) { olversion = get_oom_string (disp, "Version"); g_ol_version_major = atoi (olversion); - disp->Release (); + gpgol_release (disp); } - obj->Release (); + gpgol_release (obj); } } pEECB->GetVersion (&lBuildVersion, EECBGV_GETBUILDVERSION); @@ -897,7 +897,7 @@ install_sinks (LPEXCHEXTCALLBACK eecb) { install_GpgolExplorersEvents_sink (disp); /* Fixme: Register the event sink object somewhere. */ - disp->Release (); + gpgol_release (disp); } /* It seems that when installing this sink the first explorer @@ -910,7 +910,7 @@ install_sinks (LPEXCHEXTCALLBACK eecb) else { add_explorer_controls ((LPOOMEXPLORER)disp); - disp->Release (); + gpgol_release (disp); } disp = get_oom_object ((LPDISPATCH)rootobj, "Application.Inspectors"); @@ -920,10 +920,10 @@ install_sinks (LPEXCHEXTCALLBACK eecb) { install_GpgolInspectorsEvents_sink (disp); /* Fixme: Register the event sink object somewhere. */ - disp->Release (); + gpgol_release (disp); } - rootobj->Release (); + gpgol_release (rootobj); } log_debug ("%s:%s: Leave", SRCNAME, __func__); @@ -951,9 +951,9 @@ get_eecb_object (LPEXCHEXTCALLBACK eecb) hr = pObj->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp); if (hr == S_OK && pDisp) result = pDisp; - pObj->Release (); + gpgol_release (pObj); } - pCb->Release (); + gpgol_release (pCb); } return result; } diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index e4cb7a4..3191c91 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -71,9 +71,9 @@ get_object_name (LPUNKNOWN obj) leave: if (tinfo) - tinfo->Release (); + gpgol_release (tinfo); if (disp) - disp->Release (); + gpgol_release (disp); return name; } @@ -161,12 +161,12 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) if (pDisp) { - pDisp->Release (); + gpgol_release (pDisp); pDisp = NULL; } pObj->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp); if (pObj != pStart) - pObj->Release (); + gpgol_release (pObj); pObj = NULL; if (!pDisp) return NULL; /* The object has no IDispatch interface. */ @@ -184,7 +184,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) dot = strchr (fullname, '.'); if (dot == fullname) { - pDisp->Release (); + gpgol_release (pDisp); return NULL; /* Empty name part: error. */ } else if (dot) @@ -232,7 +232,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) } if (!parmstr) { - pDisp->Release (); + gpgol_release (pDisp); return NULL; /* Error: Out of memory. */ } n_parms = 1; @@ -248,7 +248,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) { if (parmstr) SysFreeString (parmstr); - pDisp->Release (); + gpgol_release (pDisp); return NULL; /* Name not found. */ } @@ -293,7 +293,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) VariantClear (&vtResult); if (parmstr) SysFreeString (parmstr); - pDisp->Release (); + gpgol_release (pDisp); return NULL; /* Invoke failed. */ } @@ -690,7 +690,7 @@ get_oom_control_bytag (LPDISPATCH pDisp, const char *tag) if (hr == S_OK && rVariant.vt == VT_DISPATCH && rVariant.pdispVal) { rVariant.pdispVal->QueryInterface (IID_IDispatch, (LPVOID*)&result); - rVariant.pdispVal->Release (); + gpgol_release (rVariant.pdispVal); if (!result) log_debug ("%s:%s: Object with tag `%s' has no dispatch intf.", SRCNAME, __func__, tag); @@ -1170,7 +1170,7 @@ get_oom_base_message_from_mapi (LPDISPATCH mapi_message) log_oom_extra("%s:%s: About to call GetBaseMessage.", SRCNAME, __func__); hr = secureMessage->GetBaseMessage (&message); - secureMessage->Release (); + gpgol_release (secureMessage); if (hr != S_OK) { log_error_w32 (hr, "Failed to GetBaseMessage."); @@ -1192,7 +1192,7 @@ get_oom_base_message (LPDISPATCH mailitem) return NULL; } ret = get_oom_base_message_from_mapi ((LPDISPATCH)mapi_message); - mapi_message->Release (); + gpgol_release (mapi_message); return ret; } @@ -1245,7 +1245,7 @@ get_oom_mapi_session () return NULL; } mapiobj = get_oom_iunknown (oom_session, "MAPIOBJECT"); - oom_session->Release (); + gpgol_release (oom_session); if (!mapiobj) { @@ -1254,7 +1254,7 @@ get_oom_mapi_session () } session = NULL; hr = mapiobj->QueryInterface (IID_IMAPISession, (void**)&session); - mapiobj->Release (); + gpgol_release (mapiobj); if (hr != S_OK || !session) { log_error ("%s:%s: error getting IMAPISession: hr=%#lx", diff --git a/src/oomhelp.h b/src/oomhelp.h index 3c1ae51..b069b31 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -25,9 +25,6 @@ #include "mymapi.h" #include "myexchext.h" -/* Helper to release dispatcher */ -#define RELDISP(dispatcher) if (dispatcher) dispatcher->Release() - #define MSOCONTROLBUTTON 1 #define MSOCONTROLEDIT 2 #define MSOCONTROLDROPDOWN 3 diff --git a/src/revert.cpp b/src/revert.cpp index 103b325..7573e30 100644 --- a/src/revert.cpp +++ b/src/revert.cpp @@ -146,7 +146,7 @@ message_revert (LPMESSAGE message) else result = 2; - att->Release (); + gpgol_release (att); att = NULL; } break; @@ -639,7 +639,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) } folder = NULL; hr = unknown->QueryInterface (IID_IMAPIFolder, (void**)&folder); - unknown->Release (); + gpgol_release (unknown); if (hr != S_OK || !folder) { log_error ("%s:%s: error getting IMAPIFolder: hr=%#lx", @@ -664,7 +664,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) return -1; } unknown = get_oom_iunknown (disp, "MAPIOBJECT"); - disp->Release (); + gpgol_release (disp); if (!unknown) { log_error ("%s:%s: error getting Session.MAPIOBJECT", SRCNAME, __func__); @@ -673,7 +673,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) } session = NULL; hr = unknown->QueryInterface (IID_IMAPISession, (void**)&session); - unknown->Release (); + gpgol_release (unknown); if (hr != S_OK || !session) { log_error ("%s:%s: error getting IMAPISession: hr=%#lx", @@ -688,7 +688,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) if (!store_entryid) { log_error ("%s:%s: PR_STORE_ENTRYID missing\n", SRCNAME, __func__); - session->Release (); + gpgol_release (session); ul_release (folder, __func__, __LINE__); return -1; } @@ -701,7 +701,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) { log_error ("%s:%s: OpenMsgStore failed: hr=%#lx\n", SRCNAME, __func__, hr); - session->Release (); + gpgol_release (session); ul_release (folder, __func__, __LINE__); return -1; } @@ -714,7 +714,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) log_error ("%s:%s: error getting contents table: hr=%#lx\n", SRCNAME, __func__, hr); ul_release (mdb, __func__, __LINE__); - session->Release (); + gpgol_release (session); ul_release (folder, __func__, __LINE__); return -1; } @@ -725,9 +725,9 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) { log_error ("%s:%s: error setting contents table column: hr=%#lx\n", SRCNAME, __func__, hr); - contents->Release (); + gpgol_release (contents); ul_release (mdb, __func__, __LINE__); - session->Release (); + gpgol_release (session); ul_release (folder, __func__, __LINE__); return -1; } @@ -776,7 +776,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) log_debug ("%s:%s: this row has now message object (type=%d)" " - skipped\n", SRCNAME, __func__, (int)mtype); - message->Release (); + gpgol_release (message); } FreeProws (rows); rows = NULL; @@ -790,9 +790,9 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj) rows = NULL; } - contents->Release (); + gpgol_release (contents); ul_release (mdb, __func__, __LINE__); - session->Release (); + gpgol_release (session); ul_release (folder, __func__, __LINE__); return 0; } diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 452aae6..0b547f4 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -592,7 +592,7 @@ verify_mime (LPDISPATCH mailitem) return 0; } ret = message_incoming_handler (message, NULL, true /*force */); - message->Release (); + gpgol_release (message); return ret; } @@ -902,7 +902,7 @@ do_reader_action (LPDISPATCH ctrl, int flags) xfree (senderAddr); xfree (subject); if (tmpstream) - tmpstream->Release(); + gpgol_release (tmpstream); return S_OK; } @@ -982,7 +982,7 @@ getIcon (int id, VARIANT* result) if (CreateStreamOnHGlobal (hBuffer, FALSE, &pStream) == S_OK) { pbitmap = Gdiplus::Bitmap::FromStream (pStream); - pStream->Release(); + gpgol_release (pStream); if (!pbitmap || pbitmap->GetHBITMAP (0, &pdesc.bmp.hbitmap)) { log_error ("%s:%s: failed to get PNG.", diff --git a/src/util.h b/src/util.h index 6eccb35..b20f0bc 100644 --- a/src/util.h +++ b/src/util.h @@ -97,14 +97,17 @@ void log_window_hierarchy (HWND window, const char *fmt, #define log_oom if (opt.enable_debug & DBG_OOM) log_debug #define log_oom_extra if (opt.enable_debug & DBG_OOM_EXTRA) log_debug #define gpgol_release(X) \ +{ \ if (X && opt.enable_debug & DBG_OOM_EXTRA) \ { \ - log_debug ("Releasing: %p \n", X); \ log_debug ("%s:%s: Object: %p released ref: %lu \n", \ SRCNAME, __func__, X, X->Release()); \ } \ else if (X) \ - X->Release(); + { \ + X->Release(); \ + } \ +} const char *log_srcname (const char *s); #define SRCNAME log_srcname (__FILE__) commit 6b5acfcb5f89e4a460e859aa42b347e4474e96cc Author: Andre Heinecke Date: Mon Aug 15 11:55:17 2016 +0200 WIP release debug * src/attachment.cpp: New. * src/gpgoladdin.cpp: New. * src/mail.cpp: New. * src/mailitem-events.cpp: New. * src/mapihelp.cpp: New. * src/oomhelp.cpp: New. * src/revert.cpp: New. * src/ribbon-callbacks.cpp: New. * src/util.h: New. diff --git a/src/attachment.cpp b/src/attachment.cpp index 87071dc..0ccf2d9 100644 --- a/src/attachment.cpp +++ b/src/attachment.cpp @@ -237,7 +237,7 @@ do_crypt_mapi (LPATTACH att, bool encrypt) done: if (symenc) symenc_close (symenc); - RELDISP (stream); + gpgol_release (stream); return rc; } @@ -322,8 +322,8 @@ do_crypt (LPDISPATCH mailitem, bool protect) done: - RELDISP (message); - RELDISP (attachments); + gpgol_release (message); + gpgol_release (attachments); return err; } diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp index 28fe160..7c1ba7f 100644 --- a/src/gpgoladdin.cpp +++ b/src/gpgoladdin.cpp @@ -191,7 +191,7 @@ GpgolAddin::~GpgolAddin (void) } log_debug ("%s:%s: Releasing Application Event Sink;", SRCNAME, __func__); - RELDISP (m_applicationEventSink); + gpgol_release (m_applicationEventSink); engine_deinit (); write_options (); diff --git a/src/mail.cpp b/src/mail.cpp index c1cc386..1030c77 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -85,7 +85,7 @@ Mail::Mail (LPDISPATCH mailitem) : and just release the Mail item. */ log_error ("%s:%s: Failed to install MailItemEvents sink.", SRCNAME, __func__); - mailitem->Release (); + gpgol_release(mailitem); return; } g_mail_map.insert (std::pair (mailitem, this)); @@ -118,7 +118,7 @@ Mail::process_message () log_debug ("%s:%s: incoming handler status: %i", SRCNAME, __func__, err); - message->Release (); + gpgol_release (message); return 0; } @@ -127,7 +127,7 @@ Mail::~Mail() std::map::iterator it; detach_MailItemEvents_sink (m_event_sink); - m_event_sink->Release (); + gpgol_release(m_event_sink); it = g_mail_map.find(m_mailitem); if (it != g_mail_map.end()) @@ -135,7 +135,7 @@ Mail::~Mail() g_mail_map.erase (it); } - m_mailitem->Release (); + gpgol_release(m_mailitem); } Mail * @@ -223,7 +223,7 @@ Mail::insert_plaintext () /* Invalidate UI to set the correct sig status. */ gpgoladdin_invalidate_ui (); done: - RELDISP (base_message); + gpgol_release (base_message); return err; } @@ -269,7 +269,7 @@ Mail::do_crypto () } log_debug ("%s:%s: Status: %i", SRCNAME, __func__, err); - message->Release (); + gpgol_release (message); m_crypt_successful = !err; return err; } @@ -286,7 +286,7 @@ Mail::needs_crypto () return false; } ret = get_gpgol_draft_info_flags (message); - message->Release (); + gpgol_release(message); return ret; } @@ -323,7 +323,7 @@ Mail::update_sender () if (sender) { m_sender = get_oom_string (sender, "SmtpAddress"); - RELDISP (sender); + gpgol_release (sender); return 0; } /* Fallback to Sender object */ @@ -331,7 +331,7 @@ Mail::update_sender () if (sender) { m_sender = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); - RELDISP (sender); + gpgol_release (sender); return 0; } /* We don't have s sender object or SendUsingAccount, @@ -340,7 +340,7 @@ Mail::update_sender () if (sender) { m_sender = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); - RELDISP (sender); + gpgol_release (sender); return 0; } @@ -455,7 +455,7 @@ Mail::is_smime () xfree (proto); xfree (ct); } - RELDISP (message); + gpgol_release (message); m_is_smime_checked = true; return m_is_smime; } diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 6919b14..b376c53 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -156,7 +156,7 @@ EVENT_SINK_INVOKE(MailItemEvents) draft_flags += 2; } set_gpgol_draft_info_flags (message, draft_flags); - RELDISP (message); + gpgol_release (message); } case BeforeRead: { diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index e916209..25ef089 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -1539,7 +1539,7 @@ resolve_ex_from_address (LPMESSAGE message) MAPI_BEST_ACCESS, &utype, (IUnknown**)&user); } - RELDISP (session); + gpgol_release (session); if (FAILED (hr)) { diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index ae6497c..e4cb7a4 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -787,7 +787,7 @@ get_oom_context_window (LPDISPATCH context) log_debug ("%s:%s: Could not find active window", SRCNAME, __func__); } - RELDISP (actExplorer); + gpgol_release (actExplorer); return ret; } @@ -841,7 +841,7 @@ int set_pa_variant (LPDISPATCH pDisp, const char *dasl_id, VARIANT *value) DISPATCH_METHOD, &dispparams, &rVariant, &execpinfo, &argErr); SysFreeString (b_property); - RELDISP (propertyAccessor); + gpgol_release (propertyAccessor); if (hr != S_OK) { log_debug ("%s:%s: error: invoking SetProperty p=%p vt=%d" @@ -909,7 +909,7 @@ int get_pa_variant (LPDISPATCH pDisp, const char *dasl_id, VARIANT *rVariant) DISPATCH_METHOD, &dispparams, rVariant, &execpinfo, &argErr); SysFreeString (b_property); - RELDISP (propertyAccessor); + gpgol_release (propertyAccessor); if (hr != S_OK) { log_debug ("%s:%s: error: invoking GetProperty p=%p vt=%d" @@ -1114,7 +1114,7 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW) SysFreeString (inFileB); VariantClear (&vtResult); - RELDISP (attachments); + gpgol_release (attachments); return hr == S_OK ? 0 : -1; } diff --git a/src/revert.cpp b/src/revert.cpp index abf25f2..103b325 100644 --- a/src/revert.cpp +++ b/src/revert.cpp @@ -394,7 +394,7 @@ gpgol_mailitem_revert (LPDISPATCH mailitem) if (!body) { log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - RELDISP (attachment); + gpgol_release (attachment); goto done; } log_debug ("%s:%s: Restoring pgp-body.", @@ -403,7 +403,7 @@ gpgol_mailitem_revert (LPDISPATCH mailitem) { log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); xfree (body); - RELDISP (attachment); + gpgol_release (attachment); goto done; } body_restored = 1; @@ -591,11 +591,11 @@ done: for (i = 0; i < del_cnt; i++) { - RELDISP (to_delete[i]); + gpgol_release (to_delete[i]); } xfree (to_delete); - RELDISP (attachments); + gpgol_release (attachments); xfree (msgcls); if (!result && finalize_mapi (message)) @@ -605,7 +605,7 @@ done: result = -1; } - RELDISP (message); + gpgol_release (message); return result; } diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index c4f5c22..452aae6 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -460,13 +460,13 @@ failure: log_debug ("%s:%s: failed rc=%d (%s) <%s>", SRCNAME, __func__, rc, gpg_strerror (rc), gpg_strsource (rc)); engine_cancel (filter); - RELDISP(wordEditor); - RELDISP(application); - RELDISP(selection); - RELDISP(sender); - RELDISP(recipients); - RELDISP(mailItem); - RELDISP(tmpstream); + gpgol_release(wordEditor); + gpgol_release(application); + gpgol_release(selection); + gpgol_release(sender); + gpgol_release(recipients); + gpgol_release(mailItem); + gpgol_release(tmpstream); xfree (plaintext); xfree (senderAddr); if (recipientAddrs) @@ -552,7 +552,7 @@ decryptAttachments (LPDISPATCH ctrl) DISPATCH_METHOD, &saveParams, NULL, NULL, NULL); SysFreeString (saveParams.rgvarg[0].bstrVal); - RELDISP (attachmentObj); + gpgol_release (attachmentObj); if (FAILED(hr)) { int j; @@ -560,11 +560,11 @@ decryptAttachments (LPDISPATCH ctrl) SRCNAME, __func__, (unsigned int) hr); for (j = 0; j < i; j++) xfree (filenames[j]); - RELDISP (attachmentSelection); + gpgol_release (attachmentSelection); return hr; } } - RELDISP (attachmentSelection); + gpgol_release (attachmentSelection); err = op_assuan_start_decrypt_files (curWindow, filenames); for (i = 0; i < attachmentCount; i++) xfree (filenames[i]); @@ -739,7 +739,7 @@ do_reader_action (LPDISPATCH ctrl, int flags) /* Not SMTP, fall back to try getting the property. */ LPDISPATCH sender = get_oom_object (mailItem, "Sender"); senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); - RELDISP (sender); + gpgol_release (sender); } xfree (addrType); } @@ -749,7 +749,7 @@ do_reader_action (LPDISPATCH ctrl, int flags) in this case use the current address */ LPDISPATCH sender = get_oom_object (mailItem, "Session.CurrentUser"); senderAddr = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); - RELDISP (sender); + gpgol_release (sender); } /* Determine the protocol based on the content */ @@ -894,10 +894,10 @@ do_reader_action (LPDISPATCH ctrl, int flags) log_debug ("%s:%s: failed rc=%d (%s) <%s>", SRCNAME, __func__, rc, gpg_strerror (rc), gpg_strsource (rc)); engine_cancel (filter); - RELDISP (mailItem); - RELDISP (selection); - RELDISP (wordEditor); - RELDISP (wordApplication); + gpgol_release (mailItem); + gpgol_release (selection); + gpgol_release (wordEditor); + gpgol_release (wordApplication); xfree (encData); xfree (senderAddr); xfree (subject); @@ -1204,9 +1204,9 @@ failure: xfree (fileToEncryptW); xfree (attachName); xfree (subject); - RELDISP (mailItem); - RELDISP (sender); - RELDISP (recipients); + gpgol_release (mailItem); + gpgol_release (sender); + gpgol_release (recipients); if (hFile) CloseHandle (hFile); @@ -1331,9 +1331,9 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) rc = S_OK; done: - RELDISP (context); - RELDISP (mailitem); - RELDISP (message); + gpgol_release (context); + gpgol_release (mailitem); + gpgol_release (message); return rc; } @@ -1395,9 +1395,9 @@ HRESULT get_crypt_pressed (LPDISPATCH ctrl, int flags, VARIANT *result, VARIANT_FALSE; done: - RELDISP (context); - RELDISP (mailitem); - RELDISP (message); + gpgol_release (context); + gpgol_release (mailitem); + gpgol_release (message); return S_OK; } @@ -1471,9 +1471,9 @@ HRESULT get_crypt_status (LPDISPATCH ctrl, int flags, VARIANT *result) } done: - RELDISP (context); - RELDISP (mailitem); - RELDISP (message); + gpgol_release (context); + gpgol_release (mailitem); + gpgol_release (message); return S_OK; } diff --git a/src/util.h b/src/util.h index c8a44db..6eccb35 100644 --- a/src/util.h +++ b/src/util.h @@ -96,6 +96,15 @@ void log_window_hierarchy (HWND window, const char *fmt, #define log_oom if (opt.enable_debug & DBG_OOM) log_debug #define log_oom_extra if (opt.enable_debug & DBG_OOM_EXTRA) log_debug +#define gpgol_release(X) \ + if (X && opt.enable_debug & DBG_OOM_EXTRA) \ + { \ + log_debug ("Releasing: %p \n", X); \ + log_debug ("%s:%s: Object: %p released ref: %lu \n", \ + SRCNAME, __func__, X, X->Release()); \ + } \ + else if (X) \ + X->Release(); const char *log_srcname (const char *s); #define SRCNAME log_srcname (__FILE__) commit 683e4136aca4091a8e616c3364cff160a335f6ba Author: Andre Heinecke Date: Mon Aug 15 11:51:07 2016 +0200 Enable ASLR, DEP and Fortify Source * configure.ac (HARDENING): Add hardening flags. -- As plugins without DEP and ASLR lower the security of the parent application if it is buggy we better enable these for GpgOL. GnuPG-Bug-Id: 2366 diff --git a/configure.ac b/configure.ac index 3699875..709e427 100644 --- a/configure.ac +++ b/configure.ac @@ -201,6 +201,16 @@ fi if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall -mms-bitfields -fno-strict-aliasing" CXXFLAGS="$CXXFLAGS -Wall -mms-bitfields -fno-strict-aliasing" + # Hardening flags + # Stack protection + # -fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 + # causes gpgol not to be loaded by Outlook due to a runtime error. + # This needs to be analysed but could be an incompatibility between + # gcc's stack protection and COM / Outlook system calls. + HARDENING="-Wl,--dynamicbase -Wl,--nxcompat -fno-exceptions -D_FORTIFY_SOURCE=2 -O0" + CFLAGS="$CFLAGS $HARDENING" + CXXFLAGS="$CXXFLAGS $HARDENING" + if test "$USE_MAINTAINER_MODE" = "yes"; then CFLAGS="$CFLAGS -Werror -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wformat-security" commit 037a5a7edf36038b28d2fb2bdb1e7ffeb6cb1756 Author: Andre Heinecke Date: Mon Aug 15 11:12:21 2016 +0200 Fix missing field initializers and enable warning * configure.ac (CXXFLAGS, CFLAGS): Enable Wmissing-field-initalizers. * src/attachment.cpp (do_crypt_stream): Fix init. * src/main.c (write_options): Fix init. * src/windowmessages.cpp (do_in_ui_thread): Fix init. diff --git a/configure.ac b/configure.ac index 9b5cbad..3699875 100644 --- a/configure.ac +++ b/configure.ac @@ -203,21 +203,11 @@ if test "$GCC" = yes; then CXXFLAGS="$CXXFLAGS -Wall -mms-bitfields -fno-strict-aliasing" if test "$USE_MAINTAINER_MODE" = "yes"; then CFLAGS="$CFLAGS -Werror -Wcast-align -Wshadow -Wstrict-prototypes" - CFLAGS="$CFLAGS -Wno-format-y2k -Wformat-security" + CFLAGS="$CFLAGS -Wformat-security" CFLAGS="$CFLAGS -W -Wno-sign-compare" CXXFLAGS="$CXXFLAGS -Werror -Wcast-align -Wshadow" - CXXFLAGS="$CXXFLAGS -Wno-format-y2k -Wformat-security" + CXXFLAGS="$CXXFLAGS -Wformat-security" CXXFLAGS="$CXXFLAGS -W -Wno-sign-compare" - AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers]) - _gcc_cflags_save=$CFLAGS - CFLAGS="-Wno-missing-field-initializers" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_mfi=yes,_gcc_mfi=no) - AC_MSG_RESULT($_gcc_mfi) - CFLAGS=$_gcc_cflags_save; - if test x"$_gcc_mfi" = xyes ; then - CFLAGS="$CFLAGS -Wno-missing-field-initializers" - CXXFLAGS="$CXXFLAGS -Wno-missing-field-initializers" - fi fi AC_MSG_CHECKING([if gcc supports -Wno-pointer-sign]) diff --git a/src/attachment.cpp b/src/attachment.cpp index c93a3a4..87071dc 100644 --- a/src/attachment.cpp +++ b/src/attachment.cpp @@ -75,9 +75,9 @@ do_crypt_stream (LPSTREAM stream, symenc_t symenc, bool encrypt) stream returns E_NOT_IMPLMENTED for that :-) So we manually track the read and writepos. Read is offset at 16 because of the GpgOL message. */ - LARGE_INTEGER readpos = {0}, - writepos = {0}; - ULARGE_INTEGER new_size = {0}; + LARGE_INTEGER readpos = {0, 0}, + writepos = {0, 0}; + ULARGE_INTEGER new_size = {0, 0}; if (!encrypt) { diff --git a/src/main.c b/src/main.c index d30f74b..12321f3 100644 --- a/src/main.c +++ b/src/main.c @@ -736,22 +736,22 @@ write_options (void) int value; char *s_val; } table[] = { - {"enableSmime", 0, opt.enable_smime}, + {"enableSmime", 0, opt.enable_smime, NULL}, /* {"defaultProtocol", 3, opt.default_protocol}, */ - {"encryptDefault", 0, opt.encrypt_default}, - {"signDefault", 0, opt.sign_default}, - {"previewDecrypt", 0, opt.preview_decrypt}, - {"encodingFormat", 1, opt.enc_format}, + {"encryptDefault", 0, opt.encrypt_default, NULL}, + {"signDefault", 0, opt.sign_default, NULL}, + {"previewDecrypt", 0, opt.preview_decrypt, NULL}, + {"encodingFormat", 1, opt.enc_format, NULL}, {"logFile", 2, 0, logfile}, {"defaultKey", 2, 0, opt.default_key}, - {"enableDefaultKey", 0, opt.enable_default_key}, - {"preferHtml", 0, opt.prefer_html}, - {"gitCommit", 4, opt.git_commit}, - {"formsRevision", 1, opt.forms_revision}, - {"announceNumber", 1, opt.announce_number}, - {"bodyAsAttachment", 0, opt.body_as_attachment}, - {"mimeUI", MIME_UI_DEFAULT, opt.mime_ui}, - {NULL, 0} + {"enableDefaultKey", 0, opt.enable_default_key, NULL}, + {"preferHtml", 0, opt.prefer_html, NULL}, + {"gitCommit", 4, opt.git_commit, NULL}, + {"formsRevision", 1, opt.forms_revision, NULL}, + {"announceNumber", 1, opt.announce_number, NULL}, + {"bodyAsAttachment", 0, opt.body_as_attachment, NULL}, + {"mimeUI", MIME_UI_DEFAULT, opt.mime_ui, NULL}, + {NULL, 0, 0, NULL} }; char buf[32]; int rc, i; diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index ce1afa5..e0c95cd 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -99,7 +99,7 @@ send_msg_to_ui_thread (wm_ctx_t *ctx) int do_in_ui_thread (gpgol_wmsg_type type, void *data) { - wm_ctx_t ctx = {0}; + wm_ctx_t ctx = {NULL, UNKNOWN, 0}; ctx.wmsg_type = type; ctx.data = data; if (send_msg_to_ui_thread (&ctx)) ----------------------------------------------------------------------- Summary of changes: configure.ac | 24 ++++++------ src/attached-file-events.cpp | 6 +-- src/attachment.cpp | 22 +++++------ src/attic.c | 4 +- src/display.cpp | 36 ++++++++--------- src/eventsink.h | 16 ++++---- src/explorers.cpp | 16 ++++---- src/ext-commands.cpp | 12 +++--- src/gpgoladdin.cpp | 2 +- src/inspectors.cpp | 64 +++++++++++++++--------------- src/item-events.cpp | 4 +- src/mail.cpp | 22 +++++------ src/mailitem-events.cpp | 4 +- src/mailitem.cpp | 2 +- src/main.c | 26 ++++++------- src/mapihelp.cpp | 92 ++++++++++++++++++++++---------------------- src/message-events.cpp | 12 +++--- src/message.cpp | 22 +++++------ src/mlang-charset.cpp | 11 +++--- src/olflange.cpp | 18 ++++----- src/oomhelp.cpp | 34 ++++++++-------- src/oomhelp.h | 3 -- src/revert.cpp | 34 ++++++++-------- src/ribbon-callbacks.cpp | 62 ++++++++++++++--------------- src/util.h | 12 ++++++ src/windowmessages.cpp | 2 +- 26 files changed, 286 insertions(+), 276 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 16 16:51:14 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 16 Aug 2016 16:51:14 +0200 Subject: [git] GpgOL - branch, nomapi, created. gpgol-1.4.0-17-gc1398da Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, nomapi has been created at c1398da89a56f4c2cad743af8eb687d33e7f3246 (commit) - Log ----------------------------------------------------------------- commit c1398da89a56f4c2cad743af8eb687d33e7f3246 Author: Andre Heinecke Date: Tue Aug 16 16:45:49 2016 +0200 Add first (dummy) version of C++ MailParser * src/mail.cpp (get_cipherstream): Use second attachment for now. (use_body): Small helper to detect if the body should be used. (Mail::decrypt_mime): Removed. (Mail::decrypt): Removed. (add_attachments): New helper to create OOM attachments from Attachment Objects. (Mail::decrypt_verify): Use MailParser. (Mail::get_subject): New helper. * src/mailparser.cpp, src/mailparser.h: New. -- Instead of refactoring the mimeparser to work without MAPI structures I'm not incrementally factoring things out from there into a new MailParser class which will replace both message.cpp and mimeparser.c and should work without writing directly to MAPI so that in the future the MailParser can be moved into a different thread and we avoid chaning underlying MAPI Stores without going through oom. diff --git a/src/Makefile.am b/src/Makefile.am index 8834497..f9507f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,7 +86,8 @@ gpgol_SOURCES = \ mlang-charset.cpp mlang-charset.h \ gmime-table-private.h \ exechelp.c exechelp.h \ - addin-options.cpp addin-options.h + addin-options.cpp addin-options.h \ + mailparser.cpp mailparser.h #treeview_SOURCES = treeview.c diff --git a/src/mail.cpp b/src/mail.cpp index ba1f23f..4c16852 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -29,8 +29,12 @@ #include "revert.h" #include "gpgoladdin.h" #include "mymapitags.h" +#include "mailparser.h" +#include "gpgolstr.h" #include +#include +#include static std::map g_mail_map; @@ -204,8 +208,8 @@ get_cipherstream (LPDISPATCH mailitem) log_debug ("%s:%s: More then one attachment count: %i. Continuing anway.", SRCNAME, __func__, count); } - /* We assume the crypto attachment is the first item. */ - attachment = get_oom_object (attachments, "Item(1)"); + /* We assume the crypto attachment is the second item. */ + attachment = get_oom_object (attachments, "Item(2)"); gpgol_release (attachments); attachments = NULL; @@ -227,41 +231,53 @@ get_cipherstream (LPDISPATCH mailitem) return stream; } -/** The decryption for mime messages. - We get the original attachment table and decrypt the first - attachment. Then we replace the body and attachment table - with the new contents. */ -int -Mail::decrypt_mime() +/** Helper to check if the body should be used for decrypt verify + or if the mime Attachment should be used. */ +static bool +use_body(msgtype_t type) { - LPSTREAM cipherstream = get_cipherstream(m_mailitem); - - if (!cipherstream) + switch (type) { - log_debug ("%s:%s: Failed to get cipherstream.", - SRCNAME, __func__); - return 1; - } - - char tmpbuf[33]; - - if (put_oom_string (m_mailitem, "HTMLBody", WAIT_TEMPLATE)) - { - log_error ("%s:%s: Failed to modify body of item.", - SRCNAME, __func__); + case MSGTYPE_GPGOL_PGP_MESSAGE: + case MSGTYPE_GPGOL_CLEAR_SIGNED: + return true; + default: + return false; } - return 0; } -int -Mail::decrypt() +/** Helper to update the attachments of a mail object in oom. + does not modify the underlying mapi structure. */ +static bool +add_attachments(LPDISPATCH mail, + std::vector > attachments) { - return 0; + for (auto att: attachments) + { + wchar_t* wchar_name = utf8_to_wchar (att->get_display_name().c_str()); + log_debug("DisplayName %s", att->get_display_name().c_str()); + HANDLE hFile; + wchar_t* wchar_file = get_tmp_outfile (GpgOLStr("gpgol-attach-"), &hFile); + if (add_oom_attachment (mail, wchar_file, wchar_name)) + { + log_debug ("Failed to add attachment."); + } + CloseHandle (hFile); + DeleteFileW (wchar_file); + xfree (wchar_file); + xfree (wchar_name); + } + return false; } int Mail::decrypt_verify() { + if (m_type == MSGTYPE_UNKNOWN || m_type == MSGTYPE_GPGOL) + { + /* Not a message for us. */ + return 0; + } if (m_needs_wipe) { log_error ("%s:%s: Decrypt verify called for msg that needs wipe: %p", @@ -269,21 +285,69 @@ Mail::decrypt_verify() return 0; } - switch (m_type) + m_processed = true; + /* Do the actual parsing */ + std::unique_ptr parser; + if (!use_body (m_type)) { - case MSGTYPE_UNKNOWN: - /* Not a message for us. Ignore. */ - return 0; - case MSGTYPE_GPGOL: - log_debug ("%s:%s: ignoring unknown message of original SMIME class\n", - SRCNAME, __func__); - break; - case MSGTYPE_GPGOL_MULTIPART_ENCRYPTED: - return decrypt_mime(); - default: - log_debug ("%s:%s: Unhandled message class. \n", - SRCNAME, __func__); + auto cipherstream = get_cipherstream (m_mailitem); + + if (!cipherstream) + { + /* TODO Error message? */ + log_debug ("%s:%s: Failed to get cipherstream.", + SRCNAME, __func__); + return 1; + } + + parser = std::unique_ptr(new MailParser (cipherstream, m_type)); + gpgol_release (cipherstream); } + else + { + parser = std::unique_ptr(); + } + + const std::string err = parser->parse(); + if (!err.empty()) + { + /* TODO Show error message. */ + log_error ("%s:%s: Failed to parse message: %s", + SRCNAME, __func__, err.c_str()); + return 1; + } + + m_needs_wipe = true; + /* Update the body */ + const auto html = parser->get_utf8_html_body(); + if (!html->empty()) + { + if (put_oom_string (m_mailitem, "HTMLBody", html->c_str())) + { + log_error ("%s:%s: Failed to modify html body of item.", + SRCNAME, __func__); + return 1; + } + } + else + { + const auto body = parser->get_utf8_text_body(); + if (put_oom_string (m_mailitem, "Body", body->c_str())) + { + log_error ("%s:%s: Failed to modify body of item.", + SRCNAME, __func__); + return 1; + } + } + + /* Update attachments */ + if (add_attachments (m_mailitem, parser->get_attachments())) + { + log_error ("%s:%s: Failed to update attachments.", + SRCNAME, __func__); + return 1; + } + /* Invalidate UI to set the correct sig status. */ gpgoladdin_invalidate_ui (); return 0; @@ -520,3 +584,9 @@ Mail::is_smime () m_is_smime_checked = true; return m_is_smime; } + +std::string +Mail::get_subject() +{ + return std::string(get_oom_string (m_mailitem, "Subject")); +} diff --git a/src/mail.h b/src/mail.h index 5b75f79..1bbc789 100644 --- a/src/mail.h +++ b/src/mail.h @@ -24,6 +24,8 @@ #include "oomhelp.h" #include "mapihelp.h" +#include + /** @brief Data wrapper around a mailitem. * * This class is intended to bundle all that we know about @@ -136,6 +138,11 @@ public: * @returns A reference to the utf8 sender address. Or NULL. */ const char *get_sender (); + /** @brief get the subject string (UTF-8 encoded). + * + * @returns the subject or an empty string. */ + std::string get_subject (); + /** @brief Is this a crypto mail handled by gpgol. * * Calling this is only valid after a message has been processed. @@ -161,15 +168,6 @@ public: */ bool is_smime (); -protected: - /** @brief do the actual decryption for mime messages. - * - * @returns true on error. */ - int decrypt_mime(); - - /** @brief decryption helper. */ - int decrypt(); - private: LPDISPATCH m_mailitem; LPDISPATCH m_event_sink; diff --git a/src/mailparser.cpp b/src/mailparser.cpp new file mode 100644 index 0000000..500a383 --- /dev/null +++ b/src/mailparser.cpp @@ -0,0 +1,71 @@ +/* @file mailparser.cpp + * @brief Parse a mail and decrypt / verify accordingly + * + * Copyright (C) 2016 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify 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. + * + * GpgOL 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 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, see . + */ +#include "config.h" +#include "common.h" + +#include "mailparser.h" +#include "attachment.h" + +MailParser::MailParser(LPSTREAM instream, msgtype_t type): + m_body (std::shared_ptr(new std::string())), + m_htmlbody (std::shared_ptr(new std::string())), + m_stream (instream), + m_type (type), + m_error (false), + m_in_data (false), + signed_data (nullptr), + sig_data (nullptr) +{ + log_debug ("%s:%s: Creating parser for stream: %p", + SRCNAME, __func__, instream); + instream->AddRef(); +} + +MailParser::~MailParser() +{ + gpgol_release(m_stream); +} + +std::string +MailParser::parse() +{ + m_body = std::shared_ptr(new std::string("Hello world")); + Attachment *att = new Attachment (); + att->write ("Hello attachment", strlen ("Hello attachment")); + att->set_display_name ("The Attachment.txt"); + m_attachments.push_back (std::shared_ptr(att)); + return std::string(); +} + +std::shared_ptr MailParser::get_utf8_html_body() +{ + return m_htmlbody; +} + +std::shared_ptr MailParser::get_utf8_text_body() +{ + return m_body; +} + +std::vector > MailParser::get_attachments() +{ + return m_attachments; +} diff --git a/src/mailparser.h b/src/mailparser.h new file mode 100644 index 0000000..1e03139 --- /dev/null +++ b/src/mailparser.h @@ -0,0 +1,81 @@ +/* @file mailparser.h + * @brief Parse a mail and decrypt / verify accordingly + * + * Copyright (C) 2016 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify 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. + * + * GpgOL 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 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, see . + */ + +#ifndef MAILPARSER_H +#define MAILPARSER_H + +#include "oomhelp.h" +#include "mapihelp.h" +#include "gpgme.h" + +#include +#include +#include + +class Attachment; + +class MailParser +{ +public: + /** Construct a new MailParser for the stream instream. + instream is expected to point to a mime mail. + Adds a reference to the stream and releases it on + destruction. */ + MailParser(LPSTREAM instream, msgtype_t type); + ~MailParser(); + + /** Construct a new MailParser for an inline message where + the content is pointet to by body. + MailParser(const char *body, msgtype_t type); + */ + /** Main entry point. Parses the Mail returns an + * empty string on success or an error message on failure. */ + std::string parse(); + + /** Get the Body converted to utf8. Call parse first. */ + std::shared_ptr get_utf8_text_body(); + + /** Get an alternative? HTML Body converted to utf8. Call parse first. */ + std::shared_ptr get_utf8_html_body(); + + /** Get the decrypted / verified attachments. Call parse first. + */ + std::vector > get_attachments(); +private: + std::vector > m_attachments; + std::shared_ptr m_body; + std::shared_ptr m_htmlbody; + + /* State variables */ + LPSTREAM m_stream; + msgtype_t m_type; + bool m_error; + bool m_in_data; + gpgme_data_t signed_data;/* NULL or the data object used to collect + the signed data. It would be better to + just hash it but there is no support in + gpgme for this yet. */ + gpgme_data_t sig_data; /* NULL or data object to collect the + signature attachment which should be a + signature then. */ +}; + +#endif /* MAILPARSER_H */ commit 2bdf9f9b3afabfe5ce039ba61b72cfcd20ef2da8 Author: Andre Heinecke Date: Tue Aug 16 16:44:52 2016 +0200 Mark / create MOSS attachment in BeforeRead * src/mail.cpp (Mail::pre_process_message): Mark moss attach. -- This hides the MOSS attachments from the user and allows us to later find them again. diff --git a/src/mail.cpp b/src/mail.cpp index 7da636c..ba1f23f 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -161,6 +161,16 @@ Mail::pre_process_message () /* TODO: Unify this so mapi_change_message_class returns a useful value already. */ m_type = mapi_get_message_type (message); + + /* Create moss attachments here so that they are properly + hidden when the item is read into the model. */ + if (mapi_mark_or_create_moss_attach (message, m_type)) + { + log_error ("%s:%s: Failed to find moss attachment.", + SRCNAME, __func__); + m_type = MSGTYPE_UNKNOWN; + } + gpgol_release (message); return 0; } commit 78b87db761b72e8c7f9fad3f0c8ba1f44de71bb9 Author: Andre Heinecke Date: Tue Aug 16 16:39:19 2016 +0200 Add Attachment helper class * src/attachment.cpp (Attachment): New helper class. * src/attachment.h (Attachment): Declare class. * src/mail.cpp (Mail::wipe): No longer encrypt attachments. -- The Attachment class is similar to the Mail class in that it is a wrapper around some Attachment related data. The Attachment uses a temporary stream internally which ideally is never even created as a file. diff --git a/src/attachment.cpp b/src/attachment.cpp index 6f31510..a9ad736 100644 --- a/src/attachment.cpp +++ b/src/attachment.cpp @@ -21,320 +21,83 @@ #include "config.h" #include "common.h" #include "attachment.h" -#include "serpent.h" -#include "oomhelp.h" #include "mymapitags.h" #include "mapihelp.h" +#include "gpgolstr.h" #include -#define COPYBUFFERSIZE 4096 - -#define IV_DEFAULT_LEN 16 - -/** Decrypt the first 16 bytes of stream and check that it contains - our header. Return 0 on success. */ -static int -check_header (LPSTREAM stream, symenc_t symenc) +Attachment::Attachment() { HRESULT hr; - char tmpbuf[16]; - ULONG nread; - hr = stream->Read (tmpbuf, 16, &nread); - if (hr || nread != 16) - { - log_error ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr); - return -1; - } - symenc_cfb_decrypt (symenc, tmpbuf, tmpbuf, 16); - if (memcmp (tmpbuf, "GpgOL attachment", 16)) + hr = OpenStreamOnFile (MAPIAllocateBuffer, MAPIFreeBuffer, + (SOF_UNIQUEFILENAME | STGM_DELETEONRELEASE + | STGM_CREATE | STGM_READWRITE), + NULL, GpgOLStr("GPG"), &m_stream); + if (FAILED (hr)) { - log_error ("%s:%s: Invalid header.", - SRCNAME, __func__); - char buf2 [17]; - snprintf (buf2, 17, "%s", tmpbuf); - log_error("Buf2: %s", buf2); - return -1; + log_error ("%s:%s: can't create attachment: hr=%#lx\n", + SRCNAME, __func__, hr); + m_stream = NULL; } - return 0; } -/** Encrypts or decrypts a stream in place using the symenc context. - Returns 0 on success. */ -static int -do_crypt_stream (LPSTREAM stream, symenc_t symenc, bool encrypt) +Attachment::~Attachment() { - char *buf = NULL; - HRESULT hr; - ULONG nread; - bool fixed_str_written = false; - int rc = -1; - ULONG written = 0; - /* The original intention was to use IStream::Clone to have - an independent read / write stream. But the MAPI attachment - stream returns E_NOT_IMPLMENTED for that :-) - So we manually track the read and writepos. Read is offset - at 16 because of the GpgOL message. */ - LARGE_INTEGER readpos = {0, 0}, - writepos = {0, 0}; - ULARGE_INTEGER new_size = {0, 0}; - - if (!encrypt) - { - readpos.QuadPart = 16; - } - - buf = (char*)xmalloc (COPYBUFFERSIZE); - do - { - hr = stream->Read (buf, COPYBUFFERSIZE, &nread); - if (hr) - { - log_error ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr); - goto done; - } - if (!nread) - { - break; - } - readpos.QuadPart += nread; - stream->Seek(writepos, STREAM_SEEK_SET, NULL); - if (nread && encrypt && !fixed_str_written) - { - char tmpbuf[16]; - /* Write an encrypted fixed 16 byte string which we need to - check at decryption time to see whether we have actually - encrypted it using this session key. */ - symenc_cfb_encrypt (symenc, tmpbuf, "GpgOL attachment", 16); - stream->Write (tmpbuf, 16, NULL); - fixed_str_written = true; - writepos.QuadPart = 16; - } - if (encrypt) - { - symenc_cfb_encrypt (symenc, buf, buf, nread); - } - else - { - symenc_cfb_decrypt (symenc, buf, buf, nread); - } - - hr = stream->Write (buf, nread, &written); - if (FAILED (hr) || written != nread) - { - log_error ("%s:%s: Write failed: %i", SRCNAME, __func__, __LINE__); - goto done; - } - writepos.QuadPart += written; - stream->Seek(readpos, STREAM_SEEK_SET, NULL); - } - while (nread == COPYBUFFERSIZE); - - new_size.QuadPart = writepos.QuadPart; - hr = stream->SetSize (new_size); - if (FAILED (hr)) - { - log_error ("%s:%s: Failed to update size", SRCNAME, __func__); - goto done; - } - rc = 0; - -done: - xfree (buf); - - if (rc) - { - stream->Revert (); - } - else - { - stream->Commit (0); - } - - return rc; + log_debug ("%s:%s", SRCNAME, __func__); + gpgol_release (m_stream); } -/** If encrypt is set to true this will encrypt the attachment - data with serpent otherwiese it will decrypt. - This function handles the mapi side of things. - */ -static int -do_crypt_mapi (LPATTACH att, bool encrypt) +LPSTREAM +Attachment::get_stream() { - char *iv; - ULONG tag; - size_t ivlen = IV_DEFAULT_LEN; - symenc_t symenc = NULL; - HRESULT hr; - LPSTREAM stream = NULL; - int rc = -1; - - if (!att) - { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - return -1; - } - - /* Get or create a new IV */ - if (get_gpgolprotectiv_tag ((LPMESSAGE)att, &tag) ) - { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - return -1; - } - if (encrypt) - { - iv = (char*)create_initialization_vector (IV_DEFAULT_LEN); - } - else - { - iv = mapi_get_binary_prop ((LPMESSAGE)att, tag, &ivlen); - } - if (!iv) - { - log_error ("%s:%s: Error creating / getting IV: %i", SRCNAME, - __func__, __LINE__); - goto done; - } - - symenc = symenc_open (get_128bit_session_key (), 16, iv, ivlen); - xfree (iv); - if (!symenc) - { - log_error ("%s:%s: can't open encryption context", SRCNAME, __func__); - goto done; - } - - hr = att->OpenProperty (PR_ATTACH_DATA_BIN, &IID_IStream, - 0, MAPI_MODIFY, (LPUNKNOWN*) &stream); - if (FAILED (hr)) - { - log_error ("%s:%s: can't open data stream of attachment: hr=%#lx", - SRCNAME, __func__, hr); - goto done; - } - - /* When decrypting check the first 16 bytes for the header */ - if (!encrypt && check_header (stream, symenc)) - { - goto done; - } - - if (FAILED (hr)) - { - log_error ("%s:%s: can't create temp file: hr=%#lx", - SRCNAME, __func__, hr); - goto done; - } + return m_stream; +} - if (do_crypt_stream (stream, symenc, encrypt)) - { - log_error ("%s:%s: stream handling failed", - SRCNAME, __func__); - goto done; - } - rc = 0; +std::string +Attachment::get_display_name() const +{ + return m_utf8DisplayName; +} -done: - if (symenc) - symenc_close (symenc); - gpgol_release (stream); +std::string +Attachment::get_tmp_file_name() const +{ + return m_utf8FileName; +} - return rc; +void +Attachment::set_display_name(const char *name) +{ + m_utf8DisplayName = std::string(name); } -/** Protect or unprotect attachments.*/ -static int -do_crypt (LPDISPATCH mailitem, bool protect) +void +Attachment::set_attach_type(attachtype_t type) { - LPDISPATCH attachments = get_oom_object (mailitem, "Attachments"); - LPMESSAGE message = get_oom_base_message (mailitem); - int count = 0; - int err = -1; - char *item_str; - int i; - ULONG tag_id; + m_type = type; +} - if (!attachments || !message) - { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - return -1; - } - count = get_oom_int (attachments, "Count"); +void +Attachment::set_hidden(bool value) +{ + m_hidden = value; +} - if (get_gpgolattachtype_tag (message, &tag_id)) +int +Attachment::write(const char *data, size_t size) +{ + if (!data || !size) { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - goto done; + return 0; } - - if (count < 1) + if (!m_stream && m_stream->Write (data, size, NULL) != S_OK) { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - goto done; + return 1; } - - /* Yes the items start at 1! */ - for (i = 1; i <= count; i++) + if (m_stream->Commit (0) != S_OK) { - LPDISPATCH attachment; - LPATTACH mapi_attachment; - attachtype_t att_type; - - if (gpgrt_asprintf (&item_str, "Item(%i)", i) == -1) - { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - goto done; - } - - attachment = get_oom_object (attachments, item_str); - xfree (item_str); - if (!attachment) - { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - } - mapi_attachment = (LPATTACH) get_oom_iunknown (attachment, - "MapiObject"); - if (!mapi_attachment) - { - log_debug ("%s:%s: Failed to get MapiObject of attachment: %p", - SRCNAME, __func__, attachment); - gpgol_release (attachment); - continue; - } - - att_type = get_gpgolattachtype (mapi_attachment, tag_id); - if ((protect && att_type == ATTACHTYPE_FROMMOSS_DEC) || - (!protect && att_type == ATTACHTYPE_FROMMOSS)) - { - if (do_crypt_mapi (mapi_attachment, protect)) - { - log_error ("%s:%s: Error: Session crypto failed.", - SRCNAME, __func__); - gpgol_release (mapi_attachment); - gpgol_release (attachment); - goto done; - } - } - gpgol_release (mapi_attachment); - gpgol_release (attachment); + return 1; } - err = 0; - -done: - - gpgol_release (message); - gpgol_release (attachments); - return err; -} - -int -protect_attachments (LPDISPATCH mailitem) -{ - return do_crypt (mailitem, true); -} - -int -unprotect_attachments (LPDISPATCH mailitem) -{ - return do_crypt (mailitem, false); + return 0; } diff --git a/src/attachment.h b/src/attachment.h index 932a21a..68821ff 100644 --- a/src/attachment.h +++ b/src/attachment.h @@ -21,32 +21,44 @@ #define ATTACHMENT_H #include +#include "oomhelp.h" +#include "mapihelp.h" +#include -/** Protect attachments so that it can be stored - by outlook. This means to symetrically encrypt the - data with the session key. +/** Helper class for attachment actions. */ +class Attachment +{ +public: + /** Creates and opens a new temporary stream. */ + Attachment(); - This will change the messagetype back to - ATTACHTYPE_FROMMOSS it is only supposed to be - called on attachments with the Attachmentype - ATTACHTYPE_FROMMOSS_DEC. + /** Deletes the attachment and the underlying temporary file. */ + ~Attachment(); - The dispatch paramenter should be a mailitem. + /** Get an assoicated ISteam ptr or NULL. */ + LPSTREAM get_stream(); - Returns 0 on success. -*/ -int -protect_attachments (LPDISPATCH mailitem); + /** Writes data to the attachment stream. + * Calling this method automatically commits the stream. + * + * Returns 0 on success. */ + int write(const char *data, size_t size); -/** Remove the symetric session encryption of the attachments. + /** Set the display name */ + void set_display_name(const char *name); + std::string get_display_name() const; - The dispatch paramenter should be a mailitem. + std::string get_tmp_file_name() const; - This will change the messsagetype to - ATTACHTYPE_FROMMOSS_DEC it should only be called - with attachments of the type ATTACHTYPE_FROMMOSS. + void set_attach_type(attachtype_t type); + + void set_hidden(bool value); +private: + LPSTREAM m_stream; + std::string m_utf8FileName; + std::string m_utf8DisplayName; + attachtype_t m_type; + bool m_hidden; +}; - Returns 0 on success. */ -int -unprotect_attachments (LPDISPATCH mailitem); #endif // ATTACHMENT_H diff --git a/src/mail.cpp b/src/mail.cpp index 0559c93..7da636c 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -352,8 +352,7 @@ Mail::wipe () log_debug ("%s:%s: Removing plaintext from mailitem: %p.", SRCNAME, __func__, m_mailitem); if (put_oom_string (m_mailitem, "HTMLBody", - HTML_TEMPLATE) || - protect_attachments (m_mailitem)) + HTML_TEMPLATE)) { log_debug ("%s:%s: Failed to wipe mailitem: %p.", SRCNAME, __func__, m_mailitem); commit edb74e9f77e294d0aa9f29d8daf89d7149cfada6 Author: Andre Heinecke Date: Tue Aug 16 16:37:37 2016 +0200 Extend add_oom_attachment with display name * src/oomhelp.cpp (add_oom_attachment): Add display name- * src/oomhelp.h (add_oom_attachment): Update prototype. * src/ribbon-callbacks.cpp: Use new function. diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index 3191c91..2a286e9 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -1052,7 +1052,8 @@ get_oom_recipients (LPDISPATCH recipients) inFile is the path to the attachment. Name is the name that should be used in outlook. */ int -add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW) +add_oom_attachment (LPDISPATCH disp, const wchar_t* inFileW, + const wchar_t* displayName) { LPDISPATCH attachments = get_oom_object (disp, "Attachments"); @@ -1061,16 +1062,11 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW) VARIANT vtResult; VARIANT aVariant[4]; HRESULT hr; - BSTR inFileB = NULL; + BSTR inFileB = nullptr, + dispNameB = nullptr; unsigned int argErr = 0; EXCEPINFO execpinfo; - if (!inFileW || !wcslen (inFileW)) - { - log_error ("%s:%s: no filename provided", SRCNAME, __func__); - return -1; - } - dispid = lookup_oom_dispid (attachments, "Add"); if (dispid == DISPID_UNKNOWN) @@ -1080,7 +1076,14 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW) return -1; } - inFileB = SysAllocString (inFileW); + if (inFileW) + { + inFileB = SysAllocString (inFileW); + } + if (displayName) + { + dispNameB = SysAllocString (displayName); + } dispparams.rgvarg = aVariant; @@ -1088,9 +1091,8 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW) parameter and not the first. Additionally DisplayName is documented but gets ignored by Outlook since Outlook 2003 */ - dispparams.rgvarg[0].vt = VT_BSTR; /* DisplayName */ - dispparams.rgvarg[0].bstrVal = NULL; + dispparams.rgvarg[0].bstrVal = dispNameB; dispparams.rgvarg[1].vt = VT_INT; /* Position */ dispparams.rgvarg[1].intVal = 1; dispparams.rgvarg[2].vt = VT_INT; /* Type */ @@ -1112,7 +1114,10 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW) dump_excepinfo (execpinfo); } - SysFreeString (inFileB); + if (inFileB) + SysFreeString (inFileB); + if (dispNameB) + SysFreeString (dispNameB); VariantClear (&vtResult); gpgol_release (attachments); diff --git a/src/oomhelp.h b/src/oomhelp.h index b069b31..d352a8f 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -151,7 +151,8 @@ char ** get_oom_recipients (LPDISPATCH recipients); /* Add an attachment to a dispatcher */ int -add_oom_attachment (LPDISPATCH disp, wchar_t* inFile); +add_oom_attachment (LPDISPATCH disp, const wchar_t* inFile, + const wchar_t *displayName); /* Look up a string with the propertyAccessor interface */ char * diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 0b547f4..dccd3b2 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -160,7 +160,7 @@ attachSignature (LPDISPATCH mailItem, char *subject, HANDLE hFileToSign, } /* Now we have an encrypted file behind encryptedFile. Let's add it */ - add_oom_attachment (mailItem, sigFileName); + add_oom_attachment (mailItem, sigFileName, nullptr); failure: xfree (sigFileName); @@ -1182,7 +1182,7 @@ attachEncryptedFile (LPDISPATCH ctrl, int flags) } /* Now we have an encrypted file behind encryptedFile. Let's add it */ - add_oom_attachment (mailItem, encryptedFile); + add_oom_attachment (mailItem, encryptedFile, nullptr); if (flags & OP_SIGN) { commit 7e5e8e0ebc5e880beafb39d59319fbabb0241c11 Author: Andre Heinecke Date: Tue Aug 16 16:27:20 2016 +0200 * src/mapihelp.cpp: New. * src/mapihelp.h: New. * src/message.cpp: New. Factor out code from message.cpp to mapihelp * src/mapihelp.cpp (mapi_body_to_attachment): New moved from message.cpp. (mapi_mark_or_create_moss_attach): New. Combination of moss handling from message_decrypt and message_verify. * src/mapihelp.h: Add protoype * src/message.cpp (pgp_body_to_attachment): Remove. -- Moving the moss handling out of the decryption functions means that we can just mark the attachments / hide them in beforeRead and then do the actual decryption work with them later. diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index 64fe721..76213cb 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -3363,4 +3363,239 @@ mapi_attachment_to_body (LPMESSAGE message, mapi_attach_item_t *item) return result; } +/* Copy the MAPI body to a PGPBODY type attachment. */ +int +mapi_body_to_attachment (LPMESSAGE message) +{ + HRESULT hr; + LPSTREAM instream; + ULONG newpos; + LPATTACH newatt = NULL; + SPropValue prop; + LPSTREAM outstream = NULL; + LPUNKNOWN punk; + GpgOLStr body_filename (PGPBODYFILENAME); + + instream = mapi_get_body_as_stream (message); + if (!instream) + return -1; + + hr = message->CreateAttach (NULL, 0, &newpos, &newatt); + if (hr) + { + log_error ("%s:%s: can't create attachment: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + + prop.ulPropTag = PR_ATTACH_METHOD; + prop.Value.ul = ATTACH_BY_VALUE; + hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); + if (hr) + { + log_error ("%s:%s: can't set attach method: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + + /* Mark that attachment so that we know why it has been created. */ + if (get_gpgolattachtype_tag (message, &prop.ulPropTag) ) + goto leave; + prop.Value.l = ATTACHTYPE_PGPBODY; + hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); + if (hr) + { + log_error ("%s:%s: can't set %s property: hr=%#lx\n", + SRCNAME, __func__, "GpgOL Attach Type", hr); + goto leave; + } + + prop.ulPropTag = PR_ATTACHMENT_HIDDEN; + prop.Value.b = TRUE; + hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); + if (hr) + { + log_error ("%s:%s: can't set hidden attach flag: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + + prop.ulPropTag = PR_ATTACH_FILENAME_A; + prop.Value.lpszA = body_filename; + hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); + if (hr) + { + log_error ("%s:%s: can't set attach filename: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + + punk = (LPUNKNOWN)outstream; + hr = newatt->OpenProperty (PR_ATTACH_DATA_BIN, &IID_IStream, 0, + MAPI_CREATE|MAPI_MODIFY, &punk); + if (FAILED (hr)) + { + log_error ("%s:%s: can't create output stream: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + outstream = (LPSTREAM)punk; + + /* Insert a blank line so that our mime parser skips over the mail + headers. */ + hr = outstream->Write ("\r\n", 2, NULL); + if (hr) + { + log_error ("%s:%s: Write failed: hr=%#lx", SRCNAME, __func__, hr); + goto leave; + } + + { + ULARGE_INTEGER cb; + cb.QuadPart = 0xffffffffffffffffll; + hr = instream->CopyTo (outstream, cb, NULL, NULL); + } + if (hr) + { + log_error ("%s:%s: can't copy streams: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + hr = outstream->Commit (0); + if (hr) + { + log_error ("%s:%s: Commiting output stream failed: hr=%#lx", + SRCNAME, __func__, hr); + goto leave; + } + gpgol_release (outstream); + outstream = NULL; + hr = newatt->SaveChanges (0); + if (hr) + { + log_error ("%s:%s: SaveChanges of the attachment failed: hr=%#lx\n", + SRCNAME, __func__, hr); + goto leave; + } + gpgol_release (newatt); + newatt = NULL; + hr = mapi_save_changes (message, KEEP_OPEN_READWRITE); + + leave: + if (outstream) + { + outstream->Revert (); + gpgol_release (outstream); + } + if (newatt) + gpgol_release (newatt); + gpgol_release (instream); + return hr? -1:0; +} + +int +mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype) +{ + int i; + if (msgtype == MSGTYPE_UNKNOWN || + msgtype == MSGTYPE_GPGOL) + { + return 0; + } + /* First check if we already have one marked. */ + mapi_attach_item_t *table = mapi_create_attach_table (message, 0); + for (i = 0; table && !table[i].end_of_table; i++) + { + if (table[i].attach_type == ATTACHTYPE_PGPBODY || + table[i].attach_type == ATTACHTYPE_MOSS || + table[i].attach_type == ATTACHTYPE_MOSSTEMPL) + { + /* Found existing moss attachment */ + mapi_release_attach_table (table); + return 0; + } + } + + if (msgtype == MSGTYPE_GPGOL_CLEAR_SIGNED || + msgtype == MSGTYPE_GPGOL_PGP_MESSAGE) + { + /* Inline message we need to create body attachment so that we + are able to restore the content. */ + return mapi_body_to_attachment (message); + } + if (!table) + { + log_debug ("%s:%s: Neither pgp inline nor an attachment table.", + SRCNAME, __func__); + return -1; + } + + /* MIME Mails check for S/MIME first. */ + for (i = 0; !table[i].end_of_table; i++) + { + if (table[i].content_type + && (!strcmp (table[i].content_type, "application/pkcs7-mime") + || !strcmp (table[i].content_type, + "application/x-pkcs7-mime")) + && table[i].filename + && !strcmp (table[i].filename, "smime.p7m")) + break; + } + if (!table[i].end_of_table) + { + mapi_mark_moss_attach (message, table + i); + mapi_release_attach_table (table); + return 0; + } + + /* PGP/MIME or S/MIME stuff. */ + /* Multipart/encrypted message: We expect 2 attachments. + The first one with the version number and the second one + with the ciphertext. As we don't know wether we are + called the first time, we first try to find these + attachments by looking at all attachments. Only if this + fails we identify them by their order (i.e. the first 2 + attachments) and mark them as part1 and part2. */ + for (i = 0; !table[i].end_of_table; i++); /* Count entries */ + if (i >= 2) + { + int part1_idx = -1, + part2_idx = -1; + /* At least 2 attachments but none are marked. Thus we + assume that this is the first time we see this + message and we will set the mark now if we see + appropriate content types. */ + if (table[0].content_type + && !strcmp (table[0].content_type, + "application/pgp-encrypted")) + part1_idx = 0; + if (table[1].content_type + && !strcmp (table[1].content_type, + "application/octet-stream")) + part2_idx = 1; + if (part1_idx != -1 && part2_idx != -1) + { + mapi_mark_moss_attach (message, table+part1_idx); + mapi_mark_moss_attach (message, table+part2_idx); + mapi_release_attach_table (table); + return 0; + } + } + + if (!table[0].end_of_table && table[1].end_of_table) + { + /* No MOSS flag found in the table but there is only one + attachment. Due to the message type we know that this is + the original MOSS message. We mark this attachment as + hidden, so that it won't get displayed. We further mark + it as our original MOSS attachment so that after parsing + we have a mean to find it again (see above). */ + mapi_mark_moss_attach (message, table + 0); + mapi_release_attach_table (table); + return 0; + } + + mapi_release_attach_table (table); + return -1; /* No original attachment - this should not happen. */ +} diff --git a/src/mapihelp.h b/src/mapihelp.h index ad2ede1..3f22538 100644 --- a/src/mapihelp.h +++ b/src/mapihelp.h @@ -177,6 +177,13 @@ attachtype_t get_gpgolattachtype (LPATTACH obj, ULONG tag); int get_gpgol_draft_info_flags (LPMESSAGE message); int set_gpgol_draft_info_flags (LPMESSAGE message, int flags); + +/* Mark crypto attachments as hidden. And mark the moss + attachment for later use. Returns true on error. */ +int mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype); + +/* Copy the MAPI body to a PGPBODY type attachment. */ +int mapi_body_to_attachment (LPMESSAGE message); #ifdef __cplusplus } #endif diff --git a/src/message.cpp b/src/message.cpp index 6fe6747..d04e919 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -673,137 +673,6 @@ message_verify (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd) } -/* Copy the MAPI body to a PGPBODY type attachment. */ -static int -pgp_body_to_attachment (LPMESSAGE message) -{ - HRESULT hr; - LPSTREAM instream; - ULONG newpos; - LPATTACH newatt = NULL; - SPropValue prop; - LPSTREAM outstream = NULL; - LPUNKNOWN punk; - GpgOLStr body_filename (PGPBODYFILENAME); - - instream = mapi_get_body_as_stream (message); - if (!instream) - return -1; - - hr = message->CreateAttach (NULL, 0, &newpos, &newatt); - if (hr) - { - log_error ("%s:%s: can't create attachment: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - - prop.ulPropTag = PR_ATTACH_METHOD; - prop.Value.ul = ATTACH_BY_VALUE; - hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); - if (hr) - { - log_error ("%s:%s: can't set attach method: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - - /* Mark that attachment so that we know why it has been created. */ - if (get_gpgolattachtype_tag (message, &prop.ulPropTag) ) - goto leave; - prop.Value.l = ATTACHTYPE_PGPBODY; - hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); - if (hr) - { - log_error ("%s:%s: can't set %s property: hr=%#lx\n", - SRCNAME, __func__, "GpgOL Attach Type", hr); - goto leave; - } - - prop.ulPropTag = PR_ATTACHMENT_HIDDEN; - prop.Value.b = TRUE; - hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); - if (hr) - { - log_error ("%s:%s: can't set hidden attach flag: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - - prop.ulPropTag = PR_ATTACH_FILENAME_A; - prop.Value.lpszA = body_filename; - hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); - if (hr) - { - log_error ("%s:%s: can't set attach filename: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - - punk = (LPUNKNOWN)outstream; - hr = newatt->OpenProperty (PR_ATTACH_DATA_BIN, &IID_IStream, 0, - MAPI_CREATE|MAPI_MODIFY, &punk); - if (FAILED (hr)) - { - log_error ("%s:%s: can't create output stream: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - outstream = (LPSTREAM)punk; - - /* Insert a blank line so that our mime parser skips over the mail - headers. */ - hr = outstream->Write ("\r\n", 2, NULL); - if (hr) - { - log_error ("%s:%s: Write failed: hr=%#lx", SRCNAME, __func__, hr); - goto leave; - } - - { - ULARGE_INTEGER cb; - cb.QuadPart = 0xffffffffffffffffll; - hr = instream->CopyTo (outstream, cb, NULL, NULL); - } - if (hr) - { - log_error ("%s:%s: can't copy streams: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - hr = outstream->Commit (0); - if (hr) - { - log_error ("%s:%s: Commiting output stream failed: hr=%#lx", - SRCNAME, __func__, hr); - goto leave; - } - gpgol_release (outstream); - outstream = NULL; - hr = newatt->SaveChanges (0); - if (hr) - { - log_error ("%s:%s: SaveChanges of the attachment failed: hr=%#lx\n", - SRCNAME, __func__, hr); - goto leave; - } - gpgol_release (newatt); - newatt = NULL; - hr = mapi_save_changes (message, KEEP_OPEN_READWRITE); - - leave: - if (outstream) - { - outstream->Revert (); - gpgol_release (outstream); - } - if (newatt) - gpgol_release (newatt); - gpgol_release (instream); - return hr? -1:0; -} - - /* Decrypt MESSAGE, check signature and update the attachments as required. MSGTYPE should be the type of the message so that the function can decide what to do. With FORCE set the decryption is @@ -875,7 +744,7 @@ message_decrypt (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd) if (part1_idx == -1) { mapi_release_attach_table (table); - if (pgp_body_to_attachment (message)) + if (mapi_body_to_attachment (message)) table = NULL; else table = mapi_create_attach_table (message, 0); commit 5c8b946a694b9e856c5513a8c3f275272d9b445f Author: Andre Heinecke Date: Tue Aug 16 16:23:36 2016 +0200 Enable c++11 * src/Makefile.am: Enable c++11. * src/olflange-dlgs.cpp: Fix compile error with c++11. -- The plan is to use a bit more c++ features in new code like shared / unique pointers and more objects for simplified data and memory handling. diff --git a/src/Makefile.am b/src/Makefile.am index f1c6856..8834497 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,7 @@ EXTRA_DIST = \ EXEEXT = .dll AM_CFLAGS = $(GPGME_CFLAGS) $(LIBASSUAN_CFLAGS) -shared -AM_CXXFLAGS = $(GPGME_CFLAGS) $(LIBASSUAN_CFLAGS) -shared +AM_CXXFLAGS = $(GPGME_CFLAGS) $(LIBASSUAN_CFLAGS) -shared -std=c++11 gpgol_SOURCES = \ main.c gpgol.def \ diff --git a/src/olflange-dlgs.cpp b/src/olflange-dlgs.cpp index 8bccbaa..0fed8a4 100644 --- a/src/olflange-dlgs.cpp +++ b/src/olflange-dlgs.cpp @@ -54,7 +54,7 @@ set_labels (HWND dlg) { IDC_GPG_OPTIONS, "Debug..."}, { IDC_GPG_CONF, N_("Crypto Engine")}, - { IDC_VERSION_INFO, "Version "VERSION}, + { IDC_VERSION_INFO, "Version " VERSION}, { 0, NULL} }; int i; commit 268212abb5f0403cc03f1127f2014cef780450ff Author: Andre Heinecke Date: Mon Aug 15 14:07:37 2016 +0200 Start mail handing restructuring * src/mail.cpp (Mail::process_message): Split out beforeRead parts into pre_process_message. (get_cipherstream): New helper to get OOM level attachment. (Mail::decrypt_mime): New. OOM based mime decryption. (Mail::decrypt): Dummy. (Mail::do_crypto): Rename to encrypt_sign. (Mail::decrypt_verify): New. Entry point for Read event. * src/mail.h: Update accordingly. * src/mailitem-events.cpp: Call new functions. -- First part of a series of commits that will rework the way decryption works without modifing the underlying mapi object. diff --git a/src/mail.cpp b/src/mail.cpp index 1030c77..0559c93 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1,7 +1,7 @@ /* @file mail.h * @brief High level class to work with Outlook Mailitems. * - * Copyright (C) 2015 Intevation GmbH + * Copyright (C) 2015, 2016 Intevation GmbH * * This file is part of GpgOL. * @@ -28,6 +28,7 @@ #include "message.h" #include "revert.h" #include "gpgoladdin.h" +#include "mymapitags.h" #include @@ -61,6 +62,19 @@ static std::map g_mail_map; "" \ "" +#define WAIT_TEMPLATE \ +"" \ +"" \ +"" \ +"" \ +"" \ +"" \ +"
" \ +"

This message is encrypted

" \ +"
" \ +"
Please wait while the message is decrypted by GpgOL..." \ +"
" + Mail::Mail (LPDISPATCH mailitem) : m_mailitem(mailitem), m_processed(false), @@ -69,7 +83,8 @@ Mail::Mail (LPDISPATCH mailitem) : m_crypt_successful(false), m_is_smime(false), m_is_smime_checked(false), - m_sender(NULL) + m_sender(NULL), + m_type(MSGTYPE_UNKNOWN) { if (get_mail_for_item (mailitem)) { @@ -91,37 +106,6 @@ Mail::Mail (LPDISPATCH mailitem) : g_mail_map.insert (std::pair (mailitem, this)); } -int -Mail::process_message () -{ - int err; - LPMESSAGE message = get_oom_base_message (m_mailitem); - if (!message) - { - log_error ("%s:%s: Failed to get base message.", - SRCNAME, __func__); - return 0; - } - log_oom_extra ("%s:%s: GetBaseMessage OK.", - SRCNAME, __func__); - /* Change the message class here. It is important that - we change the message class in the before read event - regardless if it is already set to one of GpgOL's message - classes. Changing the message class (even if we set it - to the same value again that it already has) causes - Outlook to reconsider what it "knows" about a message - and reread data from the underlying base message. */ - mapi_change_message_class (message, 1); - err = message_incoming_handler (message, NULL, - false); - m_processed = (err == 1) || (err == 2); - - log_debug ("%s:%s: incoming handler status: %i", - SRCNAME, __func__, err); - gpgol_release (message); - return 0; -} - Mail::~Mail() { std::map::iterator it; @@ -155,80 +139,148 @@ Mail::get_mail_for_item (LPDISPATCH mailitem) } int -Mail::insert_plaintext () +Mail::pre_process_message () { - int err = 0; - int is_html, was_protected = 0; - char *body = NULL; - - if (!m_processed) + LPMESSAGE message = get_oom_base_message (m_mailitem); + if (!message) { + log_error ("%s:%s: Failed to get base message.", + SRCNAME, __func__); return 0; } + log_oom_extra ("%s:%s: GetBaseMessage OK.", + SRCNAME, __func__); + /* Change the message class here. It is important that + we change the message class in the before read event + regardless if it is already set to one of GpgOL's message + classes. Changing the message class (even if we set it + to the same value again that it already has) causes + Outlook to reconsider what it "knows" about a message + and reread data from the underlying base message. */ + mapi_change_message_class (message, 1); + /* TODO: Unify this so mapi_change_message_class returns + a useful value already. */ + m_type = mapi_get_message_type (message); + gpgol_release (message); + return 0; +} - if (m_needs_wipe) +/** Get the cipherstream of the mailitem. */ +static LPSTREAM +get_cipherstream (LPDISPATCH mailitem) +{ + LPDISPATCH attachments = get_oom_object (mailitem, "Attachments"); + LPDISPATCH attachment = NULL; + LPATTACH mapi_attachment = NULL; + LPSTREAM stream = NULL; + + if (!attachments) { - log_error ("%s:%s: Insert plaintext called for msg that needs wipe: %p", - SRCNAME, __func__, m_mailitem); - return 0; + log_debug ("%s:%s: Failed to get attachments.", + SRCNAME, __func__); + return NULL; } - /* Outlook somehow is confused about the attachment - table of our sent mails. The securemessage interface - gives us access to the real attach table but the attachment - table of the message itself is broken. */ - LPMESSAGE base_message = get_oom_base_message (m_mailitem); - if (!base_message) + int count = get_oom_int (attachments, "Count"); + if (count < 1) { - log_error ("%s:%s: Failed to get base message", - SRCNAME, __func__); - return 0; + log_debug ("%s:%s: Invalid attachment count: %i.", + SRCNAME, __func__, count); + gpgol_release (attachments); + return NULL; + } + if (count > 1) + { + log_debug ("%s:%s: More then one attachment count: %i. Continuing anway.", + SRCNAME, __func__, count); } - err = mapi_get_gpgol_body_attachment (base_message, &body, NULL, - &is_html, &was_protected); - m_needs_wipe = was_protected; + /* We assume the crypto attachment is the first item. */ + attachment = get_oom_object (attachments, "Item(1)"); + gpgol_release (attachments); + attachments = NULL; - log_debug ("%s:%s: Setting plaintext for msg: %p", - SRCNAME, __func__, m_mailitem); - if (err || !body) + mapi_attachment = (LPATTACH) get_oom_iunknown (attachment, + "MapiObject"); + gpgol_release (attachment); + if (!mapi_attachment) { - log_error ("%s:%s: Failed to get body attachment. Err: %i", - SRCNAME, __func__, err); - put_oom_string (m_mailitem, "HTMLBody", HTML_TEMPLATE); - err = -1; - goto done; + log_debug ("%s:%s: Failed to get MapiObject of attachment: %p", + SRCNAME, __func__, attachment); } - if (put_oom_string (m_mailitem, is_html ? "HTMLBody" : "Body", body)) + if (FAILED (mapi_attachment->OpenProperty (PR_ATTACH_DATA_BIN, &IID_IStream, + 0, MAPI_MODIFY, (LPUNKNOWN*) &stream))) { - log_error ("%s:%s: Failed to modify body of item.", + log_debug ("%s:%s: Failed to open stream for mapi_attachment: %p", + SRCNAME, __func__, mapi_attachment); + gpgol_release (mapi_attachment); + } + return stream; +} + +/** The decryption for mime messages. + We get the original attachment table and decrypt the first + attachment. Then we replace the body and attachment table + with the new contents. */ +int +Mail::decrypt_mime() +{ + LPSTREAM cipherstream = get_cipherstream(m_mailitem); + + if (!cipherstream) + { + log_debug ("%s:%s: Failed to get cipherstream.", SRCNAME, __func__); - err = -1; + return 1; } - xfree (body); - /* TODO: unprotect attachments does not work for sent mails - as the attachment table of the mapiitem is invalid. - We need to somehow get outlook to use the attachment table - of the base message and and then decrypt those. - This will probably mean removing all attachments for the - message and adding the attachments from the base message then - we can call unprotect_attachments as usual. */ - if (unprotect_attachments (m_mailitem)) + char tmpbuf[33]; + + if (put_oom_string (m_mailitem, "HTMLBody", WAIT_TEMPLATE)) { - log_error ("%s:%s: Failed to unprotect attachments.", + log_error ("%s:%s: Failed to modify body of item.", SRCNAME, __func__); - err = -1; + } + return 0; +} + +int +Mail::decrypt() +{ + return 0; +} + +int +Mail::decrypt_verify() +{ + if (m_needs_wipe) + { + log_error ("%s:%s: Decrypt verify called for msg that needs wipe: %p", + SRCNAME, __func__, m_mailitem); + return 0; } + switch (m_type) + { + case MSGTYPE_UNKNOWN: + /* Not a message for us. Ignore. */ + return 0; + case MSGTYPE_GPGOL: + log_debug ("%s:%s: ignoring unknown message of original SMIME class\n", + SRCNAME, __func__); + break; + case MSGTYPE_GPGOL_MULTIPART_ENCRYPTED: + return decrypt_mime(); + default: + log_debug ("%s:%s: Unhandled message class. \n", + SRCNAME, __func__); + } /* Invalidate UI to set the correct sig status. */ gpgoladdin_invalidate_ui (); -done: - gpgol_release (base_message); - return err; + return 0; } int -Mail::do_crypto () +Mail::encrypt_sign () { int err = -1, flags = 0; diff --git a/src/mail.h b/src/mail.h index ff79567..5b75f79 100644 --- a/src/mail.h +++ b/src/mail.h @@ -1,7 +1,7 @@ /* @file mail.h * @brief High level class to work with Outlook Mailitems. * - * Copyright (C) 2015 Intevation GmbH + * Copyright (C) 2015, 2016 Intevation GmbH * * This file is part of GpgOL. * @@ -22,6 +22,7 @@ #define MAIL_H #include "oomhelp.h" +#include "mapihelp.h" /** @brief Data wrapper around a mailitem. * @@ -76,25 +77,22 @@ public: /** @brief Reference to the mailitem. Do not Release! */ LPDISPATCH item () { return m_mailitem; } - /** @brief Process the message. Ususally to be called from BeforeRead. + /** @brief Pre process the message. Ususally to be called from BeforeRead. * * This function assumes that the base message interface can be accessed - * and calles the MAPI Message handling which creates the GpgOL style - * attachments and sets up the message class etc. - * - * Sets the was_encrypted / processed variables. + * and calles the MAPI Message handling which changes the message class + * to enable our own handling. * * @returns 0 on success. */ - int process_message (); + int pre_process_message (); - /** @brief Replace the body with the plaintext and session decrypts - * attachments. + /** @brief Decrypt / Verify the mail. * - * Sets the needs_wipe variable. + * Sets the needs_wipe and was_encrypted variable. * * @returns 0 on success. */ - int insert_plaintext (); + int decrypt_verify (); /** @brief do crypto operations as selected by the user. * @@ -102,7 +100,7 @@ public: * draft info flags. * * @returns 0 on success. */ - int do_crypto (); + int encrypt_sign (); /** @brief Necessary crypto operations were completed successfully. */ bool crypto_successful () { return !needs_crypto() || m_crypt_successful; } @@ -163,6 +161,15 @@ public: */ bool is_smime (); +protected: + /** @brief do the actual decryption for mime messages. + * + * @returns true on error. */ + int decrypt_mime(); + + /** @brief decryption helper. */ + int decrypt(); + private: LPDISPATCH m_mailitem; LPDISPATCH m_event_sink; @@ -173,5 +180,6 @@ private: m_is_smime, /* This is an smime mail. */ m_is_smime_checked; /* it was checked if this is an smime mail */ char *m_sender; + msgtype_t m_type; /* Our messagetype as set in mapi */ }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 5101610..e526124 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -160,18 +160,18 @@ EVENT_SINK_INVOKE(MailItemEvents) } case BeforeRead: { - if (m_mail->process_message ()) + if (m_mail->pre_process_message ()) { - log_error ("%s:%s: Process message failed.", + log_error ("%s:%s: Pre process message failed.", SRCNAME, __func__); } break; } case Read: { - if (m_mail->insert_plaintext ()) + if (m_mail->decrypt_verify ()) { - log_error ("%s:%s: Failed to insert plaintext into oom.", + log_error ("%s:%s: Decrypt message failed.", SRCNAME, __func__); } if (!opt.enable_smime && m_mail->is_smime ()) @@ -300,7 +300,7 @@ EVENT_SINK_INVOKE(MailItemEvents) if (m_send_seen) { m_send_seen = false; - m_mail->do_crypto (); + m_mail->encrypt_sign (); if (m_mail->crypto_successful ()) { /* We can't trigger a Send event in the current state. ----------------------------------------------------------------------- hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 16 18:56:25 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 16 Aug 2016 18:56:25 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-288-g8c09dd9 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 8c09dd9989bcd434a8cb5997770cb8414b96bd5c (commit) via b7b0e7b5bfefd51c8092ea54f262b18aebf78128 (commit) from 391e55411cda11446ca9de4dd0dc2b54d3e6fff5 (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 8c09dd9989bcd434a8cb5997770cb8414b96bd5c Author: Werner Koch Date: Tue Aug 16 18:53:42 2016 +0200 core: New global flag "require-gnupg". * src/gpgme.c (gpgme_set_global_flag): Add flag. * src/engine.c (engine_minimal_version): New variable. (_gpgme_set_engine_minimal_version): New function. (gpgme_get_engine_info): Check that flag. * tests/run-keylist.c (main): New option --require-gnupg. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index e47ec91..ce16687 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] * Bindings for Python 3 are now included. + * New global flag "require-gnupg" to set a minimal gnupg version. + * Interface changes relative to the 1.6.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_pubkey_algo_string NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 8b0ec52..ac0fffa 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -678,12 +678,12 @@ as early as possible --- even before @code{gpgme_check_version}. The features are identified by the following values for @var{name}: @table @code - at item "debug" + at item debug To enable debugging use the string ``debug'' for @var{name} and @var{value} identical to the value used with the environment variable @code{GPGME_DEBUG}. - at item "disable-gpgconf" + at item disable-gpgconf Using this feature with any @var{value} disables the detection of the gpgconf program and thus forces GPGME to fallback into the simple OpenPGP only mode. It may be used to force the use of GnuPG-1 on @@ -691,8 +691,8 @@ systems which have both GPG versions installed. Note that in general the use of @code{gpgme_set_engine_info} is a better way to select a specific engine version. - at item "gpgconf-name" - at itemx "gpg-name" + at item gpgconf-name + at itemx gpg-name Set the name of the gpgconf respective gpg binary. The defaults are @code{GNU/GnuPG/gpgconf} and @code{GNU/GnuPG/gpg}. Under Unix the leading directory part is ignored. Under Windows the leading @@ -700,7 +700,13 @@ directory part is used as the default installation directory; the @code{.exe} suffix is added by GPGME. Use forward slashed even under Windows. - at item "w32-inst-dir" + at item require-gnupg +Set the mimimum version of the required GnuPG engine. If that version +is not met, GPGME fails early instead of trying to use the existant +version. The given version must be a string with major, minor, and +micro number. Example: "2.1.0". + + at item w32-inst-dir On Windows GPGME needs to know its installation directory to find its spawn helper. This is in general no problem because a DLL has this information. Some applications however link statically to GPGME and diff --git a/src/engine.c b/src/engine.c index a7c016f..f428034 100644 --- a/src/engine.c +++ b/src/engine.c @@ -63,6 +63,10 @@ static struct engine_ops *engine_ops[] = static gpgme_engine_info_t engine_info; DEFINE_STATIC_LOCK (engine_info_lock); +/* If non-NULL, the minimal version required for all engines. */ +static char *engine_minimal_version; + + /* Get the file name of the engine for PROTOCOL. */ static const char * @@ -178,6 +182,26 @@ _gpgme_engine_info_release (gpgme_engine_info_t info) } +/* This is an internal function to set a mimimal required version. + * This function must only be called by gpgme_set_global_flag. + * Returns 0 on success. */ +int +_gpgme_set_engine_minimal_version (const char *value) +{ + free (engine_minimal_version); + if (value) + { + engine_minimal_version = strdup (value); + return !engine_minimal_version; + } + else + { + engine_minimal_version = NULL; + return 0; + } +} + + /* Get the information about the configured and installed engines. A pointer to the first engine in the statically allocated linked list is returned in *INFO. If an error occurs, it is returned. The @@ -229,6 +253,17 @@ gpgme_get_engine_info (gpgme_engine_info_t *info) if (!*lastp && !err) err = gpg_error_from_syserror (); + /* Check against the optional minimal engine version. */ + if (!err && version && engine_minimal_version + && !_gpgme_compare_versions (version, engine_minimal_version)) + { +#if GPG_ERROR_VERSION_NUMBER < 0x011900 /* 1.25 */ + err = gpg_error (GPG_ERR_NO_ENGINE); +#else + err = gpg_error (GPG_ERR_ENGINE_TOO_OLD); +#endif + } + /* Now set the dummy version for pseudo engines. */ if (!err && !version) { diff --git a/src/engine.h b/src/engine.h index 238a21c..b713d96 100644 --- a/src/engine.h +++ b/src/engine.h @@ -38,6 +38,8 @@ typedef gpgme_error_t (*engine_command_handler_t) (void *priv, typedef gpgme_error_t (*engine_assuan_result_cb_t) (void *priv, gpgme_error_t result); +/* Helper for gpgme_set_global_flag. */ +int _gpgme_set_engine_minimal_version (const char *value); /* Get a deep copy of the engine info and return it in INFO. */ gpgme_error_t _gpgme_engine_info_copy (gpgme_engine_info_t *r_info); diff --git a/src/gpgme.c b/src/gpgme.c index e0cd9b0..d59f808 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -71,6 +71,8 @@ gpgme_set_global_flag (const char *name, const char *value) _gpgme_dirinfo_disable_gpgconf (); return 0; } + else if (!strcmp (name, "require-gnupg")) + return _gpgme_set_engine_minimal_version (value); else if (!strcmp (name, "gpgconf-name")) return _gpgme_set_default_gpgconf_name (value); else if (!strcmp (name, "gpg-name")) diff --git a/tests/run-keylist.c b/tests/run-keylist.c index fc0f066..cc4c354 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -54,6 +54,7 @@ show_usage (int ex) " --validate use GPGME_KEYLIST_MODE_VALIDATE\n" " --import import all keys\n" " --offline use offline mode\n" + " --require-gnupg required at least the given GnuPG version\n" , stderr); exit (ex); } @@ -149,9 +150,16 @@ main (int argc, char **argv) offline = 1; argc--; argv++; } + else if (!strcmp (*argv, "--require-gnupg")) + { + argc--; argv++; + if (!argc) + show_usage (1); + gpgme_set_global_flag ("require-gnupg", *argv); + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); - } if (argc > 1) commit b7b0e7b5bfefd51c8092ea54f262b18aebf78128 Author: Werner Koch Date: Tue Aug 16 18:49:11 2016 +0200 core: Simplify setting of dummy versions. * src/engine.c (_gpgme_engine_info_release): Do not assert but free FILE_NAME. (gpgme_get_engine_info): Provide default for VERSION and REQ_VERSION. Use calloc instead of malloc. (_gpgme_set_engine_info): Ditto. * src/engine-assuan.c (llass_get_version): Return NULL. (llass_get_req_version): Ditto. * src/engine-spawn.c (engspawn_get_version): Ditto. (engspawn_get_req_version): Ditto. * src/engine-uiserver.c (uiserver_get_version): Ditto. (uiserver_get_req_version): Ditto. Signed-off-by: Werner Koch diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 681be62..c4a84a3 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -131,14 +131,14 @@ llass_get_home_dir (void) static char * llass_get_version (const char *file_name) { - return strdup ("1.0.0"); + return NULL; } static const char * llass_get_req_version (void) { - return "1.0.0"; + return NULL; } diff --git a/src/engine-spawn.c b/src/engine-spawn.c index c01b50e..e2ee8ba 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -312,14 +312,14 @@ static char * engspawn_get_version (const char *file_name) { (void)file_name; - return strdup ("1.0.0"); + return NULL; } static const char * engspawn_get_req_version (void) { - return "1.0.0"; + return NULL; } diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index 1869ff3..de12f2b 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -123,14 +123,15 @@ static void uiserver_io_event (void *engine, static char * uiserver_get_version (const char *file_name) { - return strdup ("1.0.0"); + (void)file_name; + return NULL; } static const char * uiserver_get_req_version (void) { - return "1.0.0"; + return NULL; } diff --git a/src/engine.c b/src/engine.c index 4e59ada..a7c016f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -93,7 +93,8 @@ engine_get_home_dir (gpgme_protocol_t proto) /* Get a malloced string containing the version number of the engine - for PROTOCOL. */ + * for PROTOCOL. If this function returns NULL for a valid protocol, + * it should be assumed that the engine is a pseudo engine. */ static char * engine_get_version (gpgme_protocol_t proto, const char *file_name) { @@ -107,7 +108,8 @@ engine_get_version (gpgme_protocol_t proto, const char *file_name) } -/* Get the required version number of the engine for PROTOCOL. */ +/* Get the required version number of the engine for PROTOCOL. This + * may be NULL. */ static const char * engine_get_req_version (gpgme_protocol_t proto) { @@ -164,8 +166,8 @@ _gpgme_engine_info_release (gpgme_engine_info_t info) { gpgme_engine_info_t next_info = info->next; - assert (info->file_name); - free (info->file_name); + if (info->file_name) + free (info->file_name); if (info->home_dir) free (info->home_dir); if (info->version) @@ -203,6 +205,7 @@ gpgme_get_engine_info (gpgme_engine_info_t *info) { const char *ofile_name = engine_get_file_name (proto_list[proto]); const char *ohome_dir = engine_get_home_dir (proto_list[proto]); + char *version = engine_get_version (proto_list[proto], NULL); char *file_name; char *home_dir; @@ -222,10 +225,18 @@ gpgme_get_engine_info (gpgme_engine_info_t *info) else home_dir = NULL; - *lastp = malloc (sizeof (*engine_info)); + *lastp = calloc (1, sizeof (*engine_info)); if (!*lastp && !err) err = gpg_error_from_syserror (); + /* Now set the dummy version for pseudo engines. */ + if (!err && !version) + { + version = strdup ("1.0.0"); + if (!version) + err = gpg_error_from_syserror (); + } + if (err) { _gpgme_engine_info_release (engine_info); @@ -235,6 +246,8 @@ gpgme_get_engine_info (gpgme_engine_info_t *info) free (file_name); if (home_dir) free (home_dir); + if (version) + free (version); UNLOCK (engine_info_lock); return err; @@ -243,8 +256,10 @@ gpgme_get_engine_info (gpgme_engine_info_t *info) (*lastp)->protocol = proto_list[proto]; (*lastp)->file_name = file_name; (*lastp)->home_dir = home_dir; - (*lastp)->version = engine_get_version (proto_list[proto], NULL); + (*lastp)->version = version; (*lastp)->req_version = engine_get_req_version (proto_list[proto]); + if (!(*lastp)->req_version) + (*lastp)->req_version = "1.0.0"; /* Dummy for pseudo engines. */ (*lastp)->next = NULL; lastp = &(*lastp)->next; } @@ -353,6 +368,7 @@ _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto, { char *new_file_name; char *new_home_dir; + char *new_version; /* FIXME: Use some PROTO_MAX definition. */ if (proto > DIM (engine_ops)) @@ -401,6 +417,17 @@ _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto, new_home_dir = NULL; } + new_version = engine_get_version (proto, new_file_name); + if (!new_version) + { + new_version = strdup ("1.0.0"); /* Fake one for dummy entries. */ + if (!new_version) + { + free (new_file_name); + free (new_home_dir); + } + } + /* Remove the old members. */ assert (info->file_name); free (info->file_name); @@ -412,7 +439,7 @@ _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto, /* Install the new members. */ info->file_name = new_file_name; info->home_dir = new_home_dir; - info->version = engine_get_version (proto, new_file_name); + info->version = new_version; return 0; } diff --git a/src/version.c b/src/version.c index 15e5aee..e2f1c35 100644 --- a/src/version.c +++ b/src/version.c @@ -124,7 +124,7 @@ parse_version_number (const char *str, int *number) /* Parse the version string STR in the format MAJOR.MINOR.MICRO (for example, 9.3.2) and return the components in MAJOR, MINOR and MICRO as integers. The function returns the tail of the string that - follows the version number. This might be te empty string if there + follows the version number. This might be the empty string if there is nothing following the version number, or a patchlevel. The function returns NULL if the version string is not valid. */ static const char * ----------------------------------------------------------------------- Summary of changes: NEWS | 2 ++ doc/gpgme.texi | 16 +++++++---- src/engine-assuan.c | 4 +-- src/engine-spawn.c | 4 +-- src/engine-uiserver.c | 5 ++-- src/engine.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++----- src/engine.h | 2 ++ src/gpgme.c | 2 ++ src/version.c | 2 +- tests/run-keylist.c | 10 ++++++- 10 files changed, 103 insertions(+), 20 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 16 18:58:39 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 16 Aug 2016 18:58:39 +0200 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.24-2-gb2640cb 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 b2640cb1f7b3b056ea4f8fe4b79d58fcd10ef93b (commit) from 231406339b96f087b63dc649144c8b7e1858ce84 (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 b2640cb1f7b3b056ea4f8fe4b79d58fcd10ef93b Author: Werner Koch Date: Tue Aug 16 18:55:42 2016 +0200 New error code GPG_ERR_ENGINE_TOO_OLD diff --git a/NEWS b/NEWS index e25129a..31b2b75 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ Noteworthy changes in version 1.25 (unreleased) [C19/A19/R_) ----------------------------------------------- + * Interface changes relative to the 1.23 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPG_ERR_ENGINE_TOO_OLD NEW. + Noteworthy changes in version 1.24 (2016-07-14) [C19/A19/R1) ----------------------------------------------- diff --git a/src/err-codes.h.in b/src/err-codes.h.in index eefe088..b44ac3f 100644 --- a/src/err-codes.h.in +++ b/src/err-codes.h.in @@ -319,7 +319,8 @@ # 282 to 299 are reserved for future assuan codes. -# 300 to 720 are free to be used. +300 GPG_ERR_ENGINE_TOO_OLD Crypto engine too old +# 301 to 720 are free to be used. # # Mapping of LDAP error codes ----------------------------------------------------------------------- Summary of changes: NEWS | 4 ++++ src/err-codes.h.in | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 16 19:09:40 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 16 Aug 2016 19:09:40 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-83-gb5d63e8 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 b5d63e81d5c472647decc7687cef91fee0378eb8 (commit) from f02ceb6c6e94c6fbfaeeafe728397be38107de4d (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 b5d63e81d5c472647decc7687cef91fee0378eb8 Author: Werner Koch Date: Tue Aug 16 19:06:28 2016 +0200 agent: Allow import of overly large keys. * agent/command.c (MAXLEN_KEYDATA): Double the size. -- Debian-bug-id: 834447 Signed-off-by: Werner Koch diff --git a/agent/command.c b/agent/command.c index 7fc28ad..9522f89 100644 --- a/agent/command.c +++ b/agent/command.c @@ -49,7 +49,7 @@ /* Maximum allowed size of the key parameters. */ #define MAXLEN_KEYPARAM 1024 /* Maximum allowed size of key data as used in inquiries (bytes). */ -#define MAXLEN_KEYDATA 4096 +#define MAXLEN_KEYDATA 8192 /* The size of the import/export KEK key (in bytes). */ #define KEYWRAP_KEYSIZE (128/8) ----------------------------------------------------------------------- Summary of changes: agent/command.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 Wed Aug 17 02:46:12 2016 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 17 Aug 2016 02:46:12 +0200 Subject: [git] GPGME - branch, ben/minor-docs-fixes, created. gpgme-1.6.0-289-g71d8536 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, ben/minor-docs-fixes has been created at 71d8536f624948a48f9fdda1384363a41a470b69 (commit) - Log ----------------------------------------------------------------- commit 71d8536f624948a48f9fdda1384363a41a470b69 Author: Ben McGinnes Date: Wed Aug 17 02:16:41 2016 +1000 TODO stuff * Expanded the documentation section to reflect the quandary with quality documentation. diff --git a/lang/python/docs/TODO.rst b/lang/python/docs/TODO.rst index a398ccd..d3e0719 100644 --- a/lang/python/docs/TODO.rst +++ b/lang/python/docs/TODO.rst @@ -21,3 +21,11 @@ Documentation is to be moved to a more appropriate docs/ directory and produced using reST in preparation for inevitable publication by way of Sphinx and the existing infrastructure at readthedocs.org or the projects new home at gnupg.org. + +Alternatively Org-Mode might be used, as with the rest of the GNU +Privacy Guard projects. + +The third option is to use an XML based build process with greater +support for multilingual publications such as those provided by ruby +domains (that's the XML ruby, not the programming language ruby; +they're totally different things). commit 5c44454d0047364605b3b7a7549d2593f2cb0492 Author: Ben McGinnes Date: Wed Aug 17 02:11:12 2016 +1000 Historical Record * Minor grammatical fixes. * Added paragraph on Justus' updates. * Rewrote PyPI section as it is now available there (as pyme3). diff --git a/lang/python/docs/Short_History.rst b/lang/python/docs/Short_History.rst index 126c121..2fa03c9 100644 --- a/lang/python/docs/Short_History.rst +++ b/lang/python/docs/Short_History.rst @@ -27,14 +27,20 @@ decision to fold the Python 3 port back into the original GPGME release in the languages subdirectory for non-C bindings. Ben is the maintainer of the Python 3 port within GPGME. +In 2016 Justus Winter updated a number of the Python 3 PyME SWIG +bindings during the course of GnuPG 2.1 development. During the +course of this process the port was added to PyPI under the +alternative name of pyme3 (so as not to clash with the original +package for Python 2.6 and 2.7). + --------------------- The Annoyances of Git --------------------- -As anyone who has ever worked with git knows, submodules are horrible +As anyone who has ever worked with git knows, submodules are a horrible way to deal with pretty much anything. In the interests of avoiding -migraines, that is being skipped with addition of PyME to GPGME. +migraines, that is being skipped with the addition of PyME to GPGME. Instead the files will be added to the subdirectory, along with a copy of the entire git log up to that point as a separate file within the docs directory (old-commits.log). As the log for PyME is nearly 100KB @@ -49,7 +55,21 @@ possible to implement this better in the future. The Perils of PyPI ------------------ -At the current time the Python 3 fork is not available via PyPI and -the pip installer. The recommended installation method is to follow -the instructions in lang/py3-pyme/INSTALL. This will build the -necessary SWIG portions against the installed version of GPGME. +This port is currently available in PyPI as pyme3 and uses the GPGME +version number from build time. + +Alternatively compiling GPGME and installing it from source will also +install the current version of PyME if Python 3 is detected. If +multiple versions of Python 3 are installed then it will install in +the site-packages directory of the first installation located. + +The version installed through either method can be checked like this: + +:: + >>> from pyme import core + >>> print(core.check_version()) + 1.7.0-beta257 + >>> + +Installing from PyPI should still result in the module being named +pyme when importing. commit 5eb79cce0c05c28bde228f4b5b5a72506bcc32c5 Author: Ben McGinnes Date: Wed Aug 17 01:27:07 2016 +1000 Spelling fix * Changed binginds to bindings. :) diff --git a/lang/python/README b/lang/python/README index 7ce8894..8b8fc73 100644 --- a/lang/python/README +++ b/lang/python/README @@ -7,7 +7,7 @@ https://www.gnupg.org/related_software/gpgme/ PyMe uses SWIG to create wrapper functions with automatic type conversions. This way most of the functions and types are converted from C into Python 3 automatically by SWIG, reducing the maintenance -cost of the binginds. +cost of the bindings. * Authors ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 05:17:03 2016 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 17 Aug 2016 05:17:03 +0200 Subject: [git] GPGME - branch, ben/minor-docs-fixes, updated. gpgme-1.6.0-292-g14402ec 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, ben/minor-docs-fixes has been updated via 14402ece2fdd7219b0113f5f1132ae49f88f1705 (commit) via 8c09dd9989bcd434a8cb5997770cb8414b96bd5c (commit) via b7b0e7b5bfefd51c8092ea54f262b18aebf78128 (commit) from 71d8536f624948a48f9fdda1384363a41a470b69 (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 14402ece2fdd7219b0113f5f1132ae49f88f1705 Merge: 71d8536 8c09dd9 Author: Ben McGinnes Date: Wed Aug 17 13:14:44 2016 +1000 Merge branch 'master' into ben-minor-fixes ----------------------------------------------------------------------- Summary of changes: NEWS | 2 ++ doc/gpgme.texi | 16 +++++++---- src/engine-assuan.c | 4 +-- src/engine-spawn.c | 4 +-- src/engine-uiserver.c | 5 ++-- src/engine.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++----- src/engine.h | 2 ++ src/gpgme.c | 2 ++ src/version.c | 2 +- tests/run-keylist.c | 10 ++++++- 10 files changed, 103 insertions(+), 20 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 07:25:02 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 17 Aug 2016 07:25:02 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-289-g64194b0 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 64194b0f8df1afe6135cd119fd3216fc8db68033 (commit) from 8c09dd9989bcd434a8cb5997770cb8414b96bd5c (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 64194b0f8df1afe6135cd119fd3216fc8db68033 Author: Andre Heinecke Date: Wed Aug 17 07:23:05 2016 +0200 Cpp: Fix some pedantic warnings * lang/cpp/src/context.cpp, lang/cpp/src/context.h (Context::getKeysFromRecipients): Remove ignored / invalid const qualifier. * lang/cpp/src/result.h: Don't shadow error function in ctor. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 1a2741e..11080cf 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1109,7 +1109,7 @@ static gpgme_encrypt_flags_t encryptflags2encryptflags(Context::EncryptionFlags return static_cast(result); } -gpgme_key_t *const Context::getKeysFromRecipients(const std::vector &recipients) +gpgme_key_t *Context::getKeysFromRecipients(const std::vector &recipients) { if (recipients.empty()) { return nullptr; diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 7d7f53a..29eba91 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -371,7 +371,7 @@ public: private: // Helper functions that need to be context because they rely // on the "Friendlyness" of context to access the gpgme types. - gpgme_key_t *const getKeysFromRecipients(const std::vector &recipients); + gpgme_key_t *getKeysFromRecipients(const std::vector &recipients); private: Private *const d; diff --git a/lang/cpp/src/result.h b/lang/cpp/src/result.h index 1eae5b1..a86d81f 100644 --- a/lang/cpp/src/result.h +++ b/lang/cpp/src/result.h @@ -35,8 +35,8 @@ class GPGMEPP_EXPORT Result { protected: explicit Result() : mError() {} - explicit Result(int error) : mError(error) {} - explicit Result(const Error &error) : mError(error) {} + explicit Result(int err) : mError(err) {} + explicit Result(const Error &err) : mError(err) {} void swap(Result &other) { ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/context.cpp | 2 +- lang/cpp/src/context.h | 2 +- lang/cpp/src/result.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 13:43:44 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 13:43:44 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-7-BRANCH, updated. libgcrypt-1.7.2-12-gbf3388a 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, LIBGCRYPT-1-7-BRANCH has been updated via bf3388a17d1871b03c630b5a66b31e2e44b44edf (commit) via f8241874971478bdcd2bc2082d901d05db7b256d (commit) via 8dd45ad957b54b939c288a68720137386c7f6501 (commit) via 2f62103b4bb6d6f9ce806e01afb7fdc58aa33513 (commit) via f38199dbc290003898a1799adc367265267784c2 (commit) via a4d1595a2638db63ac4c73e722c8ba95fdd85ff7 (commit) via 05a4cecae0c02d2b4ee1cadd9c08115beae3a94a (commit) via 962b15470663db11e5c35b86768f1b5d8e600017 (commit) via 34c64eb03178fbfd34190148fec5a189df2b8f83 (commit) via 3d6334f8d94c2a4df10eed203ae928298a4332ef (commit) via eee78f6e1fbce7d54c43fb7efc5aa8be9f52755f (commit) from 62642c4be0653a94fdec0c0b1f9d38673250a156 (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 bf3388a17d1871b03c630b5a66b31e2e44b44edf Author: Werner Koch Date: Wed Aug 17 13:40:19 2016 +0200 Post release updates -- diff --git a/NEWS b/NEWS index c64983b..cdf1ef4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.7.4 (unreleased) [C21/A1/R_] +------------------------------------------------ + + Noteworthy changes in version 1.7.3 (2016-08-17) [C21/A1/R3] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 273a7d2..7f415bf 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.14" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [7]) -m4_define(mym4_version_micro, [3]) +m4_define(mym4_version_micro, [4]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit f8241874971478bdcd2bc2082d901d05db7b256d Author: Werner Koch Date: Wed Aug 17 13:31:12 2016 +0200 Release 1.7.3 * configure.ac: Set LT version to C21/A1/R3. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index bca3e66..c64983b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,19 @@ -Noteworthy changes in version 1.7.3 (unreleased) [C21/A1/R_] +Noteworthy changes in version 1.7.3 (2016-08-17) [C21/A1/R3] ------------------------------------------------ + * Bug fixes: + + - Fix critical security bug in the RNG [CVE-2016-6313]. An + attacker who obtains 580 bytes from the standard RNG can + trivially predict the next 20 bytes of output. Problem + detected by Felix D?rre and Vladimir Klebanov, KIT. + + - Fix building of some asm modules with older compilers and CPUs. + + * Performance: + + - ARMv8/AArch32 improvements for AES, GCM, SHA-256, and SHA-1. + Noteworthy changes in version 1.7.2 (2016-07-14) [C21/A1/R2] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 92d3074..273a7d2 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=21 LIBGCRYPT_LT_AGE=1 -LIBGCRYPT_LT_REVISION=2 +LIBGCRYPT_LT_REVISION=3 # If the API is changed in an incompatible way: increment the next counter. commit 8dd45ad957b54b939c288a68720137386c7f6501 Author: Werner Koch Date: Mon Aug 8 12:54:08 2016 +0200 random: Hash continuous areas in the csprng pool. * random/random-csprng.c (mix_pool): Store the first hash at the end of the pool. -- This fixes a long standing bug (since 1998) in Libgcrypt and GnuPG. An attacker who obtains 580 bytes of the random number from the standard RNG can trivially predict the next 20 bytes of output. For use in GnuPG this bug does not affect the default generation of keys because running gpg for key creation creates at most 2 keys from the pool: For a single 4096 bit RSA key 512 byte of random are required and thus for the second key (encryption subkey), 20 bytes could be predicted from the the first key. However, the security of an OpenPGP key depends on the primary key (which was generated first) and thus the 20 predictable bytes should not be a problem. For the default key length of 2048 bit nothing will be predictable. For the former default of DSA+Elgamal key it is complicate to give an answer: For 2048 bit keys a pool of 30 non-secret candidate primes of about 300 bits each are first created. This reads at least 1140 bytes from the pool and thus parts could be predicted. At some point a 256 bit secret is read from the pool; which in the worst case might be partly predictable. The bug was found and reported by Felix D?rre and Vladimir Klebanov, Karlsruhe Institute of Technology. A paper describing the problem in detail will shortly be published. CVE-id: CVE-2016-6313 Signed-off-by: Werner Koch diff --git a/random/random-csprng.c b/random/random-csprng.c index 54ec277..5a771c2 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -553,23 +553,22 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * bytes. * <................600...............> <.64.> * pool |------------------------------------| |------| - * <..44..> <20> - * | | - * | +-----+ - * +-----------------------------------|--+ - * v v + * <20><.24.> <20> + * | | +-----+ + * +-----|-------------------------------|-+ + * +-------------------------------|-|-+ + * v v v * |------| * - * | * +---------------------------------------+ * v * <20> * pool' |------------------------------------| - * <20><20><..44..> - * | | - * | +------------------------------+ - * +-------------------------------------+ | - * v v + * <20><20><.24.> + * +---|-----|---------------------------+ + * +-----|---------------------------|-+ + * +---------------------------|-|-+ + * v v v * |------| * * | @@ -577,13 +576,11 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * v * <20> * pool'' |------------------------------------| - * <20><20><20><..44..> - * | | - * | +--------------------------+ - * +---------------------------------+ | - * v v - * |------| - * + * <20><20><20><.24.> + * +---|-----|-----------------------+ + * +-----|-----------------------|-+ + * +-----------------------|-|-+ + * v v v * * and so on until we did this for all 30 blocks. * @@ -611,9 +608,9 @@ mix_pool(unsigned char *pool) gcry_assert (pool_is_locked); _gcry_sha1_mixblock_init (&md); - /* Loop over the pool. */ + /* pool_0 -> pool'. */ pend = pool + POOLSIZE; - memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN); memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); nburn = _gcry_sha1_mixblock (&md, hashbuf); memcpy (pool, hashbuf, DIGESTLEN); @@ -624,19 +621,17 @@ mix_pool(unsigned char *pool) pool[i] ^= failsafe_digest[i]; } + /* Loop for the remaining iterations. */ p = pool; for (n=1; n < POOLBLOCKS; n++) { - memcpy (hashbuf, p, DIGESTLEN); - - p += DIGESTLEN; - if (p+DIGESTLEN+BLOCKLEN < pend) - memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); + if (p + BLOCKLEN < pend) + memcpy (hashbuf, p, BLOCKLEN); else { - unsigned char *pp = p + DIGESTLEN; + unsigned char *pp = p; - for (i=DIGESTLEN; i < BLOCKLEN; i++ ) + for (i=0; i < BLOCKLEN; i++ ) { if ( pp >= pend ) pp = pool; @@ -645,7 +640,8 @@ mix_pool(unsigned char *pool) } _gcry_sha1_mixblock (&md, hashbuf); - memcpy(p, hashbuf, DIGESTLEN); + p += DIGESTLEN; + memcpy (p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) commit 2f62103b4bb6d6f9ce806e01afb7fdc58aa33513 Author: Werner Koch Date: Mon Aug 8 12:08:43 2016 +0200 random: Improve the diagram showing the random mixing * random/random-csprng.c (mix_pool): Use DIGESTLEN instead of 20. Signed-off-by: Werner Koch diff --git a/random/random-csprng.c b/random/random-csprng.c index a0bfc78..54ec277 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -548,41 +548,49 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, /* - Mix the pool: - - |........blocks*20byte........|20byte|..44byte..| - <..44byte..> <20byte> - | | - | +------+ - +---------------------------|----------+ - v v - |........blocks*20byte........|20byte|..44byte..| - <.....64bytes.....> - | - +----------------------------------+ - Hash - v - |.............................|20byte|..44byte..| - <20byte><20byte><..44byte..> - | | - | +---------------------+ - +-----------------------------+ | - v v - |.............................|20byte|..44byte..| - <.....64byte......> - | - +-------------------------+ - Hash - v - |.............................|20byte|..44byte..| - <20byte><20byte><..44byte..> - - and so on until we did this for all blocks. - - To better protect against implementation errors in this code, we - xor a digest of the entire pool into the pool before mixing. - - Note: this function must only be called with a locked pool. + * Mix the 600 byte pool. Note that the 64 byte scratch area directly + * follows the pool. The numbers in the diagram give the number of + * bytes. + * <................600...............> <.64.> + * pool |------------------------------------| |------| + * <..44..> <20> + * | | + * | +-----+ + * +-----------------------------------|--+ + * v v + * |------| + * + * | + * +---------------------------------------+ + * v + * <20> + * pool' |------------------------------------| + * <20><20><..44..> + * | | + * | +------------------------------+ + * +-------------------------------------+ | + * v v + * |------| + * + * | + * +-----------------------------------+ + * v + * <20> + * pool'' |------------------------------------| + * <20><20><20><..44..> + * | | + * | +--------------------------+ + * +---------------------------------+ | + * v v + * |------| + * + * + * and so on until we did this for all 30 blocks. + * + * To better protect against implementation errors in this code, we + * xor a digest of the entire pool into the pool before mixing. + * + * Note: this function must only be called with a locked pool. */ static void mix_pool(unsigned char *pool) @@ -605,14 +613,14 @@ mix_pool(unsigned char *pool) /* Loop over the pool. */ pend = pool + POOLSIZE; - memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); - memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); nburn = _gcry_sha1_mixblock (&md, hashbuf); - memcpy(pool, hashbuf, 20 ); + memcpy (pool, hashbuf, DIGESTLEN); if (failsafe_digest_valid && pool == rndpool) { - for (i=0; i < 20; i++) + for (i=0; i < DIGESTLEN; i++) pool[i] ^= failsafe_digest[i]; } @@ -637,7 +645,7 @@ mix_pool(unsigned char *pool) } _gcry_sha1_mixblock (&md, hashbuf); - memcpy(p, hashbuf, 20 ); + memcpy(p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) ----------------------------------------------------------------------- Summary of changes: NEWS | 19 +- cipher/Makefile.am | 5 +- cipher/cipher-gcm-armv8-aarch32-ce.S | 235 ++++++ cipher/cipher-gcm.c | 37 +- cipher/cipher-internal.h | 10 + cipher/crc-intel-pclmul.c | 20 +- cipher/rijndael-aesni.c | 33 +- cipher/rijndael-armv8-aarch32-ce.S | 1483 ++++++++++++++++++++++++++++++++++ cipher/rijndael-armv8-ce.c | 469 +++++++++++ cipher/rijndael-internal.h | 14 + cipher/rijndael.c | 120 ++- cipher/sha1-armv7-neon.S | 1 + cipher/sha1-armv8-aarch32-ce.S | 219 +++++ cipher/sha1.c | 26 +- cipher/sha1.h | 1 + cipher/sha256-armv8-aarch32-ce.S | 231 ++++++ cipher/sha256.c | 30 + configure.ac | 158 +++- random/random-csprng.c | 100 +-- src/g10lib.h | 4 + src/hwf-arm.c | 139 +++- src/hwfeatures.c | 6 +- 22 files changed, 3247 insertions(+), 113 deletions(-) create mode 100644 cipher/cipher-gcm-armv8-aarch32-ce.S create mode 100644 cipher/rijndael-armv8-aarch32-ce.S create mode 100644 cipher/rijndael-armv8-ce.c create mode 100644 cipher/sha1-armv8-aarch32-ce.S create mode 100644 cipher/sha256-armv8-aarch32-ce.S hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 13:44:56 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 13:44:56 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.7.3-1-gbf3388a 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 bf3388a17d1871b03c630b5a66b31e2e44b44edf (commit) via f8241874971478bdcd2bc2082d901d05db7b256d (commit) via 8dd45ad957b54b939c288a68720137386c7f6501 (commit) via 2f62103b4bb6d6f9ce806e01afb7fdc58aa33513 (commit) from f38199dbc290003898a1799adc367265267784c2 (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: NEWS | 19 +++++++++- configure.ac | 4 +- random/random-csprng.c | 100 +++++++++++++++++++++++++------------------------ 3 files changed, 72 insertions(+), 51 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 13:58:09 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 13:58:09 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.5-14-g7ee6bbb 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, LIBGCRYPT-1-6-BRANCH has been updated via 7ee6bbb64f2a6e8351a20ea42d5a544dde429c27 (commit) via e28f3f3d7b694cf440700a49d5927b3311cdd071 (commit) via c748f87436d693f092a4484571a3cc7f650b5c81 (commit) via 190b0429b70eb4a3573377e95755d9cc13c38461 (commit) from 16a4ec65a636a00a0a234900c3a29b23a918c72f (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 7ee6bbb64f2a6e8351a20ea42d5a544dde429c27 Author: Werner Koch Date: Wed Aug 17 13:52:42 2016 +0200 Post release updates -- diff --git a/NEWS b/NEWS index 0686dff..f978703 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.6.7 (unreleased) [C20/A0/R_] +------------------------------------------------ + + Noteworthy changes in version 1.6.6 (2016-08-17) [C20/A0/R6] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index d427903..12379c8 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.14" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [6]) -m4_define(mym4_version_micro, [6]) +m4_define(mym4_version_micro, [7]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit e28f3f3d7b694cf440700a49d5927b3311cdd071 Author: Werner Koch Date: Wed Aug 17 13:46:32 2016 +0200 Release 1.6.6 * configure.ac: Set LT version to C20/A0/R6. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 22ce582..0686dff 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,11 @@ -Noteworthy changes in version 1.6.6 (unreleased) [C20/A0/R_] +Noteworthy changes in version 1.6.6 (2016-08-17) [C20/A0/R6] ------------------------------------------------ + * Fix critical security bug in the RNG [CVE-2016-6313]. An attacker + who obtains 580 bytes from the standard RNG can trivially predict + the next 20 bytes of output. Problem detected by Felix D?rre and + Vladimir Klebanov, KIT. + Noteworthy changes in version 1.6.5 (2016-02-09) [C20/A0/R5] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 75d3a06..d427903 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=20 LIBGCRYPT_LT_AGE=0 -LIBGCRYPT_LT_REVISION=5 +LIBGCRYPT_LT_REVISION=6 # If the API is changed in an incompatible way: increment the next counter. commit c748f87436d693f092a4484571a3cc7f650b5c81 Author: Werner Koch Date: Mon Aug 8 12:54:08 2016 +0200 random: Hash continuous areas in the csprng pool. * random/random-csprng.c (mix_pool): Store the first hash at the end of the pool. -- This fixes a long standing bug (since 1998) in Libgcrypt and GnuPG. An attacker who obtains 580 bytes of the random number from the standard RNG can trivially predict the next 20 bytes of output. For use in GnuPG this bug does not affect the default generation of keys because running gpg for key creation creates at most 2 keys from the pool: For a single 4096 bit RSA key 512 byte of random are required and thus for the second key (encryption subkey), 20 bytes could be predicted from the the first key. However, the security of an OpenPGP key depends on the primary key (which was generated first) and thus the 20 predictable bytes should not be a problem. For the default key length of 2048 bit nothing will be predictable. For the former default of DSA+Elgamal key it is complicate to give an answer: For 2048 bit keys a pool of 30 non-secret candidate primes of about 300 bits each are first created. This reads at least 1140 bytes from the pool and thus parts could be predicted. At some point a 256 bit secret is read from the pool; which in the worst case might be partly predictable. The bug was found and reported by Felix D?rre and Vladimir Klebanov, Karlsruhe Institute of Technology. A paper describing the problem in detail will shortly be published. CVE-id: CVE-2016-6313 Signed-off-by: Werner Koch diff --git a/random/random-csprng.c b/random/random-csprng.c index b3fc984..bc3ae50 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -571,23 +571,22 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * bytes. * <................600...............> <.64.> * pool |------------------------------------| |------| - * <..44..> <20> - * | | - * | +-----+ - * +-----------------------------------|--+ - * v v + * <20><.24.> <20> + * | | +-----+ + * +-----|-------------------------------|-+ + * +-------------------------------|-|-+ + * v v v * |------| * - * | * +---------------------------------------+ * v * <20> * pool' |------------------------------------| - * <20><20><..44..> - * | | - * | +------------------------------+ - * +-------------------------------------+ | - * v v + * <20><20><.24.> + * +---|-----|---------------------------+ + * +-----|---------------------------|-+ + * +---------------------------|-|-+ + * v v v * |------| * * | @@ -595,13 +594,11 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * v * <20> * pool'' |------------------------------------| - * <20><20><20><..44..> - * | | - * | +--------------------------+ - * +---------------------------------+ | - * v v - * |------| - * + * <20><20><20><.24.> + * +---|-----|-----------------------+ + * +-----|-----------------------|-+ + * +-----------------------|-|-+ + * v v v * * and so on until we did this for all 30 blocks. * @@ -628,9 +625,9 @@ mix_pool(unsigned char *pool) gcry_assert (pool_is_locked); _gcry_rmd160_init( &md ); - /* Loop over the pool. */ + /* pool_0 -> pool'. */ pend = pool + POOLSIZE; - memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN); memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); _gcry_rmd160_mixblock (&md, hashbuf); memcpy (pool, hashbuf, DIGESTLEN); @@ -641,19 +638,17 @@ mix_pool(unsigned char *pool) pool[i] ^= failsafe_digest[i]; } + /* Loop for the remaining iterations. */ p = pool; for (n=1; n < POOLBLOCKS; n++) { - memcpy (hashbuf, p, DIGESTLEN); - - p += DIGESTLEN; - if (p+DIGESTLEN+BLOCKLEN < pend) - memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); + if (p + BLOCKLEN < pend) + memcpy (hashbuf, p, BLOCKLEN); else { - unsigned char *pp = p + DIGESTLEN; + unsigned char *pp = p; - for (i=DIGESTLEN; i < BLOCKLEN; i++ ) + for (i=0; i < BLOCKLEN; i++ ) { if ( pp >= pend ) pp = pool; @@ -662,7 +657,8 @@ mix_pool(unsigned char *pool) } _gcry_rmd160_mixblock (&md, hashbuf); - memcpy(p, hashbuf, DIGESTLEN); + p += DIGESTLEN; + memcpy (p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) commit 190b0429b70eb4a3573377e95755d9cc13c38461 Author: Werner Koch Date: Mon Aug 8 12:08:43 2016 +0200 random: Improve the diagram showing the random mixing * random/random-csprng.c (mix_pool): Use DIGESTLEN instead of 20. -- Signed-off-by: Werner Koch diff --git a/random/random-csprng.c b/random/random-csprng.c index d3b6614..b3fc984 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -566,41 +566,49 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, /* - Mix the pool: - - |........blocks*20byte........|20byte|..44byte..| - <..44byte..> <20byte> - | | - | +------+ - +---------------------------|----------+ - v v - |........blocks*20byte........|20byte|..44byte..| - <.....64bytes.....> - | - +----------------------------------+ - Hash - v - |.............................|20byte|..44byte..| - <20byte><20byte><..44byte..> - | | - | +---------------------+ - +-----------------------------+ | - v v - |.............................|20byte|..44byte..| - <.....64byte......> - | - +-------------------------+ - Hash - v - |.............................|20byte|..44byte..| - <20byte><20byte><..44byte..> - - and so on until we did this for all blocks. - - To better protect against implementation errors in this code, we - xor a digest of the entire pool into the pool before mixing. - - Note: this function must only be called with a locked pool. + * Mix the 600 byte pool. Note that the 64 byte scratch area directly + * follows the pool. The numbers in the diagram give the number of + * bytes. + * <................600...............> <.64.> + * pool |------------------------------------| |------| + * <..44..> <20> + * | | + * | +-----+ + * +-----------------------------------|--+ + * v v + * |------| + * + * | + * +---------------------------------------+ + * v + * <20> + * pool' |------------------------------------| + * <20><20><..44..> + * | | + * | +------------------------------+ + * +-------------------------------------+ | + * v v + * |------| + * + * | + * +-----------------------------------+ + * v + * <20> + * pool'' |------------------------------------| + * <20><20><20><..44..> + * | | + * | +--------------------------+ + * +---------------------------------+ | + * v v + * |------| + * + * + * and so on until we did this for all 30 blocks. + * + * To better protect against implementation errors in this code, we + * xor a digest of the entire pool into the pool before mixing. + * + * Note: this function must only be called with a locked pool. */ static void mix_pool(unsigned char *pool) @@ -622,14 +630,14 @@ mix_pool(unsigned char *pool) /* Loop over the pool. */ pend = pool + POOLSIZE; - memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); - memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); - _gcry_rmd160_mixblock( &md, hashbuf); - memcpy(pool, hashbuf, 20 ); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); + _gcry_rmd160_mixblock (&md, hashbuf); + memcpy (pool, hashbuf, DIGESTLEN); if (failsafe_digest_valid && pool == rndpool) { - for (i=0; i < 20; i++) + for (i=0; i < DIGESTLEN; i++) pool[i] ^= failsafe_digest[i]; } @@ -653,8 +661,8 @@ mix_pool(unsigned char *pool) } } - _gcry_rmd160_mixblock ( &md, hashbuf); - memcpy(p, hashbuf, 20 ); + _gcry_rmd160_mixblock (&md, hashbuf); + memcpy(p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) ----------------------------------------------------------------------- Summary of changes: NEWS | 11 +++++- configure.ac | 4 +- random/random-csprng.c | 104 +++++++++++++++++++++++++------------------------ 3 files changed, 66 insertions(+), 53 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 14:22:04 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 14:22:04 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.5-7-g7104edf 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, LIBGCRYPT-1-5-BRANCH has been updated via 7104edfcd17a51f48a2ed72640ed308f245c0942 (commit) via 6e481d6bf0a69f8c9bd2866eb491e1e4e9b0717f (commit) via 6199cd963d1fba86e0b7b9e2de4b6c00b945193a (commit) via 98980e2fd29ad62903c78fa6521489fce651cdda (commit) via 93869fe52c4e24a0e3284addd37e1c78dc0c8cf1 (commit) from 74504ac9b0af567fe5b8f6ac5c7e7a9e59f0b348 (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 7104edfcd17a51f48a2ed72640ed308f245c0942 Author: Werner Koch Date: Wed Aug 17 14:19:20 2016 +0200 Post release updates -- diff --git a/NEWS b/NEWS index 69f5e71..14db249 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.5.7 (unreleased) [C19/A8/R_] +------------------------------------------------ + + Noteworthy changes in version 1.5.6 (2016-08-17) [C19/A8/R5] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index a3fb586..8fc66f9 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.11" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [5]) -m4_define(mym4_version_micro, [6]) +m4_define(mym4_version_micro, [7]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit 6e481d6bf0a69f8c9bd2866eb491e1e4e9b0717f Author: Werner Koch Date: Wed Aug 17 14:13:21 2016 +0200 Release 1.5.6 * configure.ac: Set LT version to C19/A8/R5. diff --git a/NEWS b/NEWS index 13ac832..69f5e71 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,11 @@ -Noteworthy changes in version 1.5.6 (unreleased) [C19/A8/R_] +Noteworthy changes in version 1.5.6 (2016-08-17) [C19/A8/R5] ------------------------------------------------ + * Fix critical security bug in the RNG [CVE-2016-6313]. An attacker + who obtains 580 bytes from the standard RNG can trivially predict + the next 20 bytes of output. Problem detected by Felix D?rre and + Vladimir Klebanov, KIT. + Noteworthy changes in version 1.5.5 (2016-02-18) [C19/A8/R4] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 367acd2..a3fb586 100644 --- a/configure.ac +++ b/configure.ac @@ -59,7 +59,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # LIBGCRYPT_LT_CURRENT=19 LIBGCRYPT_LT_AGE=8 -LIBGCRYPT_LT_REVISION=4 +LIBGCRYPT_LT_REVISION=5 # If the API is changed in an incompatible way: increment the next counter. commit 6199cd963d1fba86e0b7b9e2de4b6c00b945193a Author: Werner Koch Date: Mon Aug 8 12:54:08 2016 +0200 random: Hash continuous areas in the csprng pool. * random/random-csprng.c (mix_pool): Store the first hash at the end of the pool. -- This fixes a long standing bug (since 1998) in Libgcrypt and GnuPG. An attacker who obtains 580 bytes of the random number from the standard RNG can trivially predict the next 20 bytes of output. For use in GnuPG this bug does not affect the default generation of keys because running gpg for key creation creates at most 2 keys from the pool: For a single 4096 bit RSA key 512 byte of random are required and thus for the second key (encryption subkey), 20 bytes could be predicted from the the first key. However, the security of an OpenPGP key depends on the primary key (which was generated first) and thus the 20 predictable bytes should not be a problem. For the default key length of 2048 bit nothing will be predictable. For the former default of DSA+Elgamal key it is complicate to give an answer: For 2048 bit keys a pool of 30 non-secret candidate primes of about 300 bits each are first created. This reads at least 1140 bytes from the pool and thus parts could be predicted. At some point a 256 bit secret is read from the pool; which in the worst case might be partly predictable. The bug was found and reported by Felix D?rre and Vladimir Klebanov, Karlsruhe Institute of Technology. A paper describing the problem in detail will shortly be published. CVE-id: CVE-2016-6313 Signed-off-by: Werner Koch diff --git a/random/random-csprng.c b/random/random-csprng.c index 10952d5..0fdfa6c 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -566,23 +566,22 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * bytes. * <................600...............> <.64.> * pool |------------------------------------| |------| - * <..44..> <20> - * | | - * | +-----+ - * +-----------------------------------|--+ - * v v + * <20><.24.> <20> + * | | +-----+ + * +-----|-------------------------------|-+ + * +-------------------------------|-|-+ + * v v v * |------| * - * | * +---------------------------------------+ * v * <20> * pool' |------------------------------------| - * <20><20><..44..> - * | | - * | +------------------------------+ - * +-------------------------------------+ | - * v v + * <20><20><.24.> + * +---|-----|---------------------------+ + * +-----|---------------------------|-+ + * +---------------------------|-|-+ + * v v v * |------| * * | @@ -590,13 +589,11 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * v * <20> * pool'' |------------------------------------| - * <20><20><20><..44..> - * | | - * | +--------------------------+ - * +---------------------------------+ | - * v v - * |------| - * + * <20><20><20><.24.> + * +---|-----|-----------------------+ + * +-----|-----------------------|-+ + * +-----------------------|-|-+ + * v v v * * and so on until we did this for all 30 blocks. * @@ -623,9 +620,9 @@ mix_pool(unsigned char *pool) gcry_assert (pool_is_locked); _gcry_rmd160_init( &md ); - /* Loop over the pool. */ + /* pool_0 -> pool'. */ pend = pool + POOLSIZE; - memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN); memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); _gcry_rmd160_mixblock (&md, hashbuf); memcpy (pool, hashbuf, DIGESTLEN); @@ -636,19 +633,17 @@ mix_pool(unsigned char *pool) pool[i] ^= failsafe_digest[i]; } + /* Loop for the remaining iterations. */ p = pool; for (n=1; n < POOLBLOCKS; n++) { - memcpy (hashbuf, p, DIGESTLEN); - - p += DIGESTLEN; - if (p+DIGESTLEN+BLOCKLEN < pend) - memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); + if (p + BLOCKLEN < pend) + memcpy (hashbuf, p, BLOCKLEN); else { - unsigned char *pp = p + DIGESTLEN; + unsigned char *pp = p; - for (i=DIGESTLEN; i < BLOCKLEN; i++ ) + for (i=0; i < BLOCKLEN; i++ ) { if ( pp >= pend ) pp = pool; @@ -657,7 +652,8 @@ mix_pool(unsigned char *pool) } _gcry_rmd160_mixblock (&md, hashbuf); - memcpy(p, hashbuf, DIGESTLEN); + p += DIGESTLEN; + memcpy (p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) commit 98980e2fd29ad62903c78fa6521489fce651cdda Author: Werner Koch Date: Mon Aug 8 12:08:43 2016 +0200 random: Improve the diagram showing the random mixing * random/random-csprng.c (mix_pool): Use DIGESTLEN instead of 20. -- Signed-off-by: Werner Koch diff --git a/random/random-csprng.c b/random/random-csprng.c index 096a674..10952d5 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -561,41 +561,49 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, /* - Mix the pool: - - |........blocks*20byte........|20byte|..44byte..| - <..44byte..> <20byte> - | | - | +------+ - +---------------------------|----------+ - v v - |........blocks*20byte........|20byte|..44byte..| - <.....64bytes.....> - | - +----------------------------------+ - Hash - v - |.............................|20byte|..44byte..| - <20byte><20byte><..44byte..> - | | - | +---------------------+ - +-----------------------------+ | - v v - |.............................|20byte|..44byte..| - <.....64byte......> - | - +-------------------------+ - Hash - v - |.............................|20byte|..44byte..| - <20byte><20byte><..44byte..> - - and so on until we did this for all blocks. - - To better protect against implementation errors in this code, we - xor a digest of the entire pool into the pool before mixing. - - Note: this function must only be called with a locked pool. + * Mix the 600 byte pool. Note that the 64 byte scratch area directly + * follows the pool. The numbers in the diagram give the number of + * bytes. + * <................600...............> <.64.> + * pool |------------------------------------| |------| + * <..44..> <20> + * | | + * | +-----+ + * +-----------------------------------|--+ + * v v + * |------| + * + * | + * +---------------------------------------+ + * v + * <20> + * pool' |------------------------------------| + * <20><20><..44..> + * | | + * | +------------------------------+ + * +-------------------------------------+ | + * v v + * |------| + * + * | + * +-----------------------------------+ + * v + * <20> + * pool'' |------------------------------------| + * <20><20><20><..44..> + * | | + * | +--------------------------+ + * +---------------------------------+ | + * v v + * |------| + * + * + * and so on until we did this for all 30 blocks. + * + * To better protect against implementation errors in this code, we + * xor a digest of the entire pool into the pool before mixing. + * + * Note: this function must only be called with a locked pool. */ static void mix_pool(unsigned char *pool) @@ -617,14 +625,14 @@ mix_pool(unsigned char *pool) /* Loop over the pool. */ pend = pool + POOLSIZE; - memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); - memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); - _gcry_rmd160_mixblock( &md, hashbuf); - memcpy(pool, hashbuf, 20 ); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); + _gcry_rmd160_mixblock (&md, hashbuf); + memcpy (pool, hashbuf, DIGESTLEN); if (failsafe_digest_valid && pool == rndpool) { - for (i=0; i < 20; i++) + for (i=0; i < DIGESTLEN; i++) pool[i] ^= failsafe_digest[i]; } @@ -648,8 +656,8 @@ mix_pool(unsigned char *pool) } } - _gcry_rmd160_mixblock ( &md, hashbuf); - memcpy(p, hashbuf, 20 ); + _gcry_rmd160_mixblock (&md, hashbuf); + memcpy(p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) commit 93869fe52c4e24a0e3284addd37e1c78dc0c8cf1 Author: Werner Koch Date: Wed Aug 17 10:58:22 2016 +0200 doc: Update AUTHORS -- diff --git a/AUTHORS b/AUTHORS index e7ffaea..45acb15 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,8 +7,12 @@ End-of-life: 2016-12-31 License (library): LGPLv2.1+ License (manual and tools): GPLv2+ -Libgcrypt used to be part of GnuPG but has been taken out into its own -package on 2000-12-21. +Libgcrypt is free software. See the files COPYING.LIB and COPYING for +copying conditions. License copyright years may be listed using range +notation, e.g., 2000-2013, indicating that every year in the range, +inclusive, is a copyrightable year that would otherwise be listed +individually. Libgcrypt used to be part of GnuPG but has been taken +out into its own package on 2000-12-21. Authors with a FSF copyright assignment ----------------------------------------------------------------------- Summary of changes: AUTHORS | 8 +++- NEWS | 11 +++++- configure.ac | 4 +- random/random-csprng.c | 104 +++++++++++++++++++++++++------------------------ 4 files changed, 72 insertions(+), 55 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 15:34:32 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 15:34:32 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-28-g06db04b 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 06db04ba666c130e5068d29cf771f73040646912 (commit) via 47531220e57bf5093dcf2312884124f0a79e15db (commit) via 5e1843fc47457a9a0525ed7d3e55961d342ef1e2 (commit) via 03376ed88acc91967ca276301bd2ffbbc135166f (commit) via 56792b1191a31c8409d7dcdb33b87a92f0e65ab2 (commit) via 96fe65bc46243d9c40da74e9e3884fcc321b92f2 (commit) via 851a9de23ac0977c66f5ef56f08d8ca5eae92930 (commit) via c6dbfe89903d0c8191cf50ecf1abb3c8458b427a (commit) via e23eec8c9a602eee0a09851a54db0f5d611f125c (commit) from 61539efc2bc4ba9a9faceaced12660d588c1be7a (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 06db04ba666c130e5068d29cf771f73040646912 Author: Werner Koch Date: Wed Aug 17 15:29:13 2016 +0200 Post release updates -- diff --git a/NEWS b/NEWS index 9b84c17..26f70cf 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.4.22 (unreleased) +------------------------------------------------- + + Noteworthy changes in version 1.4.21 (2016-08-17) ------------------------------------------------- diff --git a/configure.ac b/configure.ac index 8133537..f03859c 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,7 @@ min_automake_version="1.14" # (git tag -s gnupg-1.n.m) and run "./autogen.sh --force". Please # bump the version number immediately *after* the release and do # another commit and push so that the git magic is able to work. -m4_define([mym4_version], [1.4.21]) +m4_define([mym4_version], [1.4.22]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a commit 47531220e57bf5093dcf2312884124f0a79e15db Author: Werner Koch Date: Wed Aug 17 15:07:57 2016 +0200 Release 1.4.21 diff --git a/NEWS b/NEWS index 7de62d9..9b84c17 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,15 @@ -Noteworthy changes in version 1.4.21 (unreleased) +Noteworthy changes in version 1.4.21 (2016-08-17) ------------------------------------------------- + * Fix critical security bug in the RNG [CVE-2016-6313]. An attacker + who obtains 580 bytes from the standard RNG can trivially predict + the next 20 bytes of output. Problem detected by Felix D??rre and + Vladimir Klebanov, KIT. + + * Tweak default options for gpgv. + + * By default do not anymore emit the GnuPG version with --armor. + Noteworthy changes in version 1.4.20 (2015-12-20) ------------------------------------------------- diff --git a/README b/README index 1a331fb..55b2f03 100644 --- a/README +++ b/README @@ -307,6 +307,12 @@ card. To see the fingerprints of the secondary keys, you can give the command twice; but this is normally not needed. + NEVER use the keyid to verify a key - always use the complete + fingerprint. The keyid is just a convenience handle to identify a + key by a short semi-unique name which is trivial to spoof. You + may want to put the line "keyid-format long" into your gpg.conf to + tell gpg to print the long keyid (which is still spoof-able). + If you don't know the owner of the public key you are in trouble. Suppose however that friend of yours knows someone who knows someone who has met the owner of the public key at some computer conference. @@ -403,28 +409,28 @@ There are several ways to specify a user ID, here are some examples. - * Only by the short keyid (prepend a zero if it begins with A..F): + * By a fingerprint: - "234567C4" - "0F34E556E" - "01347A56A" - "0xAB123456 + "1234343434343434C434343434343434" + "123434343434343C3434343434343734349A3434" + "0E12343434343434343434EAB3484343434343434" + + The first one is a short fingerprint for PGP 2.x style keys. + The others are long fingerprints for OpenPGP keys. - * By a complete keyid: + * By a complete keyid (prepend a zero if it begins with A..F): "234AABBCC34567C4" "0F323456784E56EAB" "01AB3FED1347A5612" "0x234AABBCC34567C4" - * By a fingerprint: - - "1234343434343434C434343434343434" - "123434343434343C3434343434343734349A3434" - "0E12343434343434343434EAB3484343434343434" + * By the short keyid: - The first one is a short fingerprint for PGP 2.x style keys. - The others are long fingerprints for OpenPGP keys. + "234567C4" + "0F34E556E" + "01347A56A" + "0xAB123456 * By an exact string: commit 5e1843fc47457a9a0525ed7d3e55961d342ef1e2 Author: Werner Koch Date: Wed Aug 17 14:50:35 2016 +0200 gpg: Add dummy option --with-subkey-fingerprint. * g10/gpg.c (opts): Add dummy option. Signed-off-by: Werner Koch diff --git a/g10/gpg.c b/g10/gpg.c index 236ea1e..416d44e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -742,6 +742,11 @@ static ARGPARSE_OPTS opts[] = { { oNoRequireCrossCert, "no-require-cross-certification", 0, "@"}, { oAutoKeyLocate, "auto-key-locate", 2, "@"}, { oNoAutoKeyLocate, "no-auto-key-locate", 0, "@"}, + + /* Options from later gpg versions which we ignore. */ + { oNoop, "with-subkey-fingerprint", 0, "@" }, + + {0,NULL,0,NULL} }; commit 03376ed88acc91967ca276301bd2ffbbc135166f Author: Werner Koch Date: Wed Aug 17 14:41:16 2016 +0200 po: Auto update -- diff --git a/po/be.po b/po/be.po index 2d20e7a..fdaa5e1 100644 --- a/po/be.po +++ b/po/be.po @@ -4410,14 +4410,14 @@ msgstr "" msgid "trustdb transaction too large\n" msgstr "" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "?????????????????? ?????????????? %s: %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "?????????????????? ?????????????? %s: %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "" diff --git a/po/ca.po b/po/ca.po index a8ae1c6..13d4132 100644 --- a/po/ca.po +++ b/po/ca.po @@ -4948,16 +4948,16 @@ msgstr "" msgid "trustdb transaction too large\n" msgstr "la transacci?? de la base de dades de confian??a ??s massa gran\n" +#, c-format +msgid "%s: directory does not exist!\n" +msgstr "%s: el directori no existeix!\n" + # No em passe! ;) ivb #, fuzzy, c-format msgid "can't access `%s': %s\n" msgstr "no s'ha pogut tancar ??%s??: %s\n" #, c-format -msgid "%s: directory does not exist!\n" -msgstr "%s: el directori no existeix!\n" - -#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: no s'ha pogut crear un registre de versi??: %s" diff --git a/po/cs.po b/po/cs.po index 5e38930..d4d04d6 100644 --- a/po/cs.po +++ b/po/cs.po @@ -4642,14 +4642,14 @@ msgid "trustdb transaction too large\n" msgstr "transakce s datab??z?? d??v??ry je p????li?? dlouh??\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "nemohu otev????t `%s': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: adres???? neexistuje!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "nemohu otev????t `%s': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: nepoda??ilo se vytvo??it z??znam verze: %s" diff --git a/po/da.po b/po/da.po index 33fd087..8f3af6f 100644 --- a/po/da.po +++ b/po/da.po @@ -4654,14 +4654,14 @@ msgid "trustdb transaction too large\n" msgstr "transaktion for trustdb er for stor\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "kan ikke tilg?? ??%s??: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: mappe findes ikke!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "kan ikke tilg?? ??%s??: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: kunne ikke oprette versionspost: %s" diff --git a/po/de.po b/po/de.po index 760627e..a745205 100644 --- a/po/de.po +++ b/po/de.po @@ -4764,14 +4764,14 @@ msgid "trustdb transaction too large\n" msgstr "trustdb Transaktion zu gro??\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "kann aus `%s' nicht zugreifen: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: Verzeichnis existiert nicht!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "kann aus `%s' nicht zugreifen: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: Fehler beim Erzeugen des Versionsatzes: %s" diff --git a/po/el.po b/po/el.po index 078e132..a6a9a46 100644 --- a/po/el.po +++ b/po/el.po @@ -4841,14 +4841,14 @@ msgstr "trustdb rec %lu: msgid "trustdb transaction too large\n" msgstr "???? ?????? ????????? trustdb\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "???????? ??????????? ??? `%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ? ??????? ??? ???????!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "???????? ??????????? ??? `%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: ???????? ??????????? ???? ???????? ???????: %s" diff --git a/po/eo.po b/po/eo.po index 9f4dcc4..5ab4beb 100644 --- a/po/eo.po +++ b/po/eo.po @@ -4780,14 +4780,14 @@ msgstr "fido-datenaro loko %lu: skribo malsukcesis (n=%d): %s\n" msgid "trustdb transaction too large\n" msgstr "fido-datenaro-transakcio tro granda\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "ne povas fermi '%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: dosierujo ne ekzistas!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "ne povas fermi '%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: malsukcesis krei versiregistron: %s" diff --git a/po/es.po b/po/es.po index 9aa6700..ba65dd1 100644 --- a/po/es.po +++ b/po/es.po @@ -4692,14 +4692,14 @@ msgid "trustdb transaction too large\n" msgstr "transacci??n en la base de datos de confianza demasiado grande\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "no se puede acceder a `%s': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ??el directorio no existe!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "no se puede acceder a `%s': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: fallo al crear el registro de versi??n: %s" diff --git a/po/et.po b/po/et.po index 072f5ff..a42bcb8 100644 --- a/po/et.po +++ b/po/et.po @@ -4753,14 +4753,14 @@ msgstr "trustdb rec %lu: write failed (n=%d): %s\n" msgid "trustdb transaction too large\n" msgstr "trustdb transaktsioon on liiga suur\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "`%s' ei ?nnestu sulgeda: %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: kataloogi ei ole!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "`%s' ei ?nnestu sulgeda: %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: versioonikirje loomine ei ?nnestu: %s" diff --git a/po/fi.po b/po/fi.po index e5b473e..203bedb 100644 --- a/po/fi.po +++ b/po/fi.po @@ -4827,14 +4827,14 @@ msgstr "trustdb rec %lu: kirjoittaminen ep??onnistuin (n=%d): %s\n" msgid "trustdb transaction too large\n" msgstr "trustdb-tapahtuma on liian suuri\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: hakemistoa ei ole olemassa!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: versiotietueen luonti ep??onnistui: %s" diff --git a/po/fr.po b/po/fr.po index b1b9dbf..a664e59 100644 --- a/po/fr.po +++ b/po/fr.po @@ -4775,14 +4775,14 @@ msgid "trustdb transaction too large\n" msgstr "transaction de base de confiance trop grande\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "impossible d'acc??der ?? ????%s??????: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s??: le r??pertoire n'existe pas.\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "impossible d'acc??der ?? ????%s??????: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s??: impossible de cr??er un enregistrement de version??: %s" diff --git a/po/gl.po b/po/gl.po index 806d934..58a680c 100644 --- a/po/gl.po +++ b/po/gl.po @@ -4820,14 +4820,14 @@ msgstr "" msgid "trustdb transaction too large\n" msgstr "transacci?n da base de datos de confianza demasiado grande\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "non se pode pechar `%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ?o directorio non existe!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "non se pode pechar `%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: non se puido crea-lo rexistro de versi?n: %s" diff --git a/po/hu.po b/po/hu.po index 6346267..20c6c8b 100644 --- a/po/hu.po +++ b/po/hu.po @@ -4794,14 +4794,14 @@ msgstr "Bizalmi adatb msgid "trustdb transaction too large\n" msgstr "Bizalmi adatb?zis tranzakci?ja t?l nagy.\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "Nem tudom bez?rni a(z) \"%s\" ?llom?nyt: %s.\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: K?nyvt?r nem l?tezik!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "Nem tudom bez?rni a(z) \"%s\" ?llom?nyt: %s.\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: Nem siker?lt verzi?rekordot l?trehoznom: %s" diff --git a/po/id.po b/po/id.po index 2c3691d..b0022c0 100644 --- a/po/id.po +++ b/po/id.po @@ -4794,14 +4794,14 @@ msgstr "trustdb rec %lu: write failed (n=%d): %s\n" msgid "trustdb transaction too large\n" msgstr "transaksi trustdb terlalu besar\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "tidak dapat menutup `%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: direktori tidak ada!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "tidak dapat menutup `%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: gagal membuat catatan versi: %s" diff --git a/po/it.po b/po/it.po index fdeed8f..1108836 100644 --- a/po/it.po +++ b/po/it.po @@ -4712,14 +4712,14 @@ msgid "trustdb transaction too large\n" msgstr "transazione del trustdb troppo grande\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "impossibile accedere a \"%s\": %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: la directory non esiste.\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "impossibile accedere a \"%s\": %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: creazione del record della versione non riuscita: %s" diff --git a/po/ja.po b/po/ja.po index fc36029..76383a3 100644 --- a/po/ja.po +++ b/po/ja.po @@ -3717,7 +3717,8 @@ msgstr "?????????" #, c-format msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n" -msgstr "*??????*: ???????????????????????????????????????????????????%s??????????????????*??????????????????*!\n" +msgstr "" +"*??????*: ???????????????????????????????????????????????????%s??????????????????*??????????????????*!\n" #, c-format msgid "Can't check signature: %s\n" @@ -4531,14 +4532,14 @@ msgid "trustdb transaction too large\n" msgstr "????????????????????????????????????????????????????????????????????????\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "???%s?????????????????????????????????: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ????????????????????????????????????!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "???%s?????????????????????????????????: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: ????????????????????????????????????????????????????????????: %s" diff --git a/po/nb.po b/po/nb.po index 81fbffe..eafef85 100644 --- a/po/nb.po +++ b/po/nb.po @@ -4503,14 +4503,14 @@ msgid "trustdb transaction too large\n" msgstr "" #, c-format -msgid "can't access `%s': %s\n" -msgstr "kan ikke aksere ?%s?: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "" #, c-format +msgid "can't access `%s': %s\n" +msgstr "kan ikke aksere ?%s?: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "" diff --git a/po/nl.po b/po/nl.po index 70f0953..b24ce55 100644 --- a/po/nl.po +++ b/po/nl.po @@ -4843,14 +4843,14 @@ msgid "trustdb transaction too large\n" msgstr "betrouwbaarheidsdatabank (trustdb): transactie is te groot\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "krijg geen toegang tot `%s': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: map bestaat niet!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "krijg geen toegang tot `%s': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: het registreren van de versie is mislukt: %s" diff --git a/po/pl.po b/po/pl.po index a77c979..62531c6 100644 --- a/po/pl.po +++ b/po/pl.po @@ -4663,14 +4663,14 @@ msgid "trustdb transaction too large\n" msgstr "zbyt du??e zlecenie dla bazy zaufania\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "nie ma dost??pu do ,,%s'': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: katalog nie istnieje!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "nie ma dost??pu do ,,%s'': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: stworzenie zapisu o wersji nie powiod??o si??: %s" diff --git a/po/pt.po b/po/pt.po index 480eff3..1cde13d 100644 --- a/po/pt.po +++ b/po/pt.po @@ -4789,14 +4789,14 @@ msgstr "base de dados de confian msgid "trustdb transaction too large\n" msgstr "transa??o de base de dados de confian?a muito grande\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "imposs?vel fechar `%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: diretoria inexistente!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "imposs?vel fechar `%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: falha ao criar registo de vers?o: %s" diff --git a/po/pt_BR.po b/po/pt_BR.po index c9a4cdb..c42a774 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -4740,14 +4740,14 @@ msgstr "banco de dados de confiabilidade rec %lu: escrita falhou (n=%d): %s\n" msgid "trustdb transaction too large\n" msgstr "transa??o de banco de dados de confiabilidade muito grande\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "imposs?vel abrir `%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: diret?rio inexistente!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "imposs?vel abrir `%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: falha ao criar registro de vers?o: %s" diff --git a/po/ro.po b/po/ro.po index 68fae3f..9e02f26 100644 --- a/po/ro.po +++ b/po/ro.po @@ -4689,14 +4689,14 @@ msgid "trustdb transaction too large\n" msgstr "tranzac??ia trustdb prea mare\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "nu pot accesa `%s': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: directorul nu exist??!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "nu pot accesa `%s': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: am e??uat s?? creez ??nregistrare versiune: %s" diff --git a/po/ru.po b/po/ru.po index 23c092d..1394d98 100644 --- a/po/ru.po +++ b/po/ru.po @@ -4628,14 +4628,14 @@ msgid "trustdb transaction too large\n" msgstr "?????????????? ?????????????? ???????????????????? ?????????????? ??????????????\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "?????? ?????????????? ?? `%s': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ?????????????? ???? ????????????????????!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "?????? ?????????????? ?? `%s': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: ???????? ???????????????? ???????????? ?? ????????????: %s" diff --git a/po/sk.po b/po/sk.po index cd8d96c..7820c9c 100644 --- a/po/sk.po +++ b/po/sk.po @@ -4802,14 +4802,14 @@ msgstr "z msgid "trustdb transaction too large\n" msgstr "transakcia s datab?zou d?very je pr?li? dlh?\n" -#, fuzzy, c-format -msgid "can't access `%s': %s\n" -msgstr "nem??em zavrie? `%s': %s\n" - #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: adres?r neexistuje!\n" +#, fuzzy, c-format +msgid "can't access `%s': %s\n" +msgstr "nem??em zavrie? `%s': %s\n" + #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: nepodarilo sa vytvori? z?znam verzie: %s" diff --git a/po/sv.po b/po/sv.po index 82d73f6..4945b76 100644 --- a/po/sv.po +++ b/po/sv.po @@ -4767,14 +4767,14 @@ msgid "trustdb transaction too large\n" msgstr "tillitsdatabastransaktion f??r stor\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "kan inte komma ??t \"%s\": %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: katalogen finns inte!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "kan inte komma ??t \"%s\": %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: misslyckades med att skapa versionspost: %s" diff --git a/po/tr.po b/po/tr.po index b46a9b1..f162a53 100644 --- a/po/tr.po +++ b/po/tr.po @@ -4688,14 +4688,14 @@ msgid "trustdb transaction too large\n" msgstr "g??vence veritaban?? i??lemi ??ok uzun\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "'%s' eri??ilemiyor: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: dizin yok!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "'%s' eri??ilemiyor: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: s??r??m kayd?? olu??turmada ba??ar??s??z: %s" diff --git a/po/uk.po b/po/uk.po index 4bfc8f3..de46213 100644 --- a/po/uk.po +++ b/po/uk.po @@ -4719,14 +4719,14 @@ msgid "trustdb transaction too large\n" msgstr "?????????????? ???????????? ???????????????? trustdb\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "?????????? ?????????????? ???? ??%s??: %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ???????????????? ???? ??????????!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "?????????? ?????????????? ???? ??%s??: %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: ???? ?????????????? ???????????????? ?????????? ???????? ????????????: %s" diff --git a/po/zh_CN.po b/po/zh_CN.po index de0167c..e6d5f78 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -4514,14 +4514,14 @@ msgid "trustdb transaction too large\n" msgstr "?????????????????????????????????\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "???????????????%s??????%s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s?????????????????????\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "???????????????%s??????%s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s??????????????????????????????%s" diff --git a/po/zh_TW.po b/po/zh_TW.po index 6d600db..dc61180 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -4526,14 +4526,14 @@ msgid "trustdb transaction too large\n" msgstr "??????????????????????????????\n" #, c-format -msgid "can't access `%s': %s\n" -msgstr "???????????? `%s': %s\n" - -#, c-format msgid "%s: directory does not exist!\n" msgstr "%s: ???????????????!\n" #, c-format +msgid "can't access `%s': %s\n" +msgstr "???????????? `%s': %s\n" + +#, c-format msgid "%s: failed to create version record: %s" msgstr "%s: ????????????????????????: %s" commit 56792b1191a31c8409d7dcdb33b87a92f0e65ab2 Author: Werner Koch Date: Wed Aug 17 14:39:26 2016 +0200 build: Create a swdb file during "make distcheck". * Makefile.am (distcheck-hook): New. Signed-off-by: Werner Koch diff --git a/Makefile.am b/Makefile.am index 1c6311b..44adf6a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,6 +77,19 @@ dist-hook: gen-ChangeLog > $(distdir)/gnupg.spec echo "$(VERSION)" > $(distdir)/VERSION +distcheck-hook: + set -e; ( \ + pref="#+macro: gnupg1_" ;\ + reldate="$$(date -u +%Y-%m-%d)" ;\ + echo "$${pref}ver $(PACKAGE_VERSION)" ;\ + echo "$${pref}date $${reldate}" ;\ + list='$(DIST_ARCHIVES)'; for i in $$list; do \ + case "$$i" in *.tar.bz2) \ + echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ + echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ + echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ + esac;\ + done ) | tee $(distdir).swdb gen_start_date = 2011-12-01T06:00:00 .PHONY: gen-ChangeLog commit 96fe65bc46243d9c40da74e9e3884fcc321b92f2 Author: Werner Koch Date: Wed Aug 17 14:36:25 2016 +0200 build: Update config.{guess,sub} to {2016-05-15,2016-06-20}. -- diff --git a/scripts/config.guess b/scripts/config.guess index 1f5c50c..c4bd827 100755 --- a/scripts/config.guess +++ b/scripts/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2014-03-23' +timestamp='2016-05-15' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -24,12 +24,12 @@ timestamp='2014-03-23' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # -# Please send patches with a ChangeLog entry to config-patches at gnu.org. +# Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -168,19 +168,29 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ @@ -197,6 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in os=netbsd ;; esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need @@ -207,13 +224,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` @@ -223,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; @@ -235,6 +256,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -251,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -359,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build - SUN_ARCH="i386" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` @@ -393,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} @@ -579,8 +603,9 @@ EOF else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi @@ -617,13 +642,13 @@ EOF sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi @@ -662,11 +687,11 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build @@ -679,12 +704,12 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} @@ -789,14 +814,14 @@ EOF echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -878,7 +903,7 @@ EOF exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix @@ -901,7 +926,7 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) @@ -932,6 +957,9 @@ EOF crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -944,6 +972,9 @@ EOF ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -1020,7 +1051,7 @@ EOF echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -1099,7 +1130,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1248,6 +1279,9 @@ EOF SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1261,9 +1295,9 @@ EOF UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in @@ -1285,7 +1319,7 @@ EOF exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi @@ -1316,7 +1350,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" @@ -1358,7 +1392,7 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos @@ -1369,23 +1403,25 @@ EOF x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac cat >&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches at gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp diff --git a/scripts/config.sub b/scripts/config.sub index bba4efb..9feb73b 100755 --- a/scripts/config.sub +++ b/scripts/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2014-09-11' +timestamp='2016-06-20' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ timestamp='2014-09-11' # of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches with a ChangeLog entry to config-patches at gnu.org. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -33,7 +33,7 @@ timestamp='2014-09-11' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,8 +53,7 @@ timestamp='2014-09-11' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. @@ -68,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -117,7 +116,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os @@ -255,12 +254,13 @@ case $basic_machine in | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ @@ -305,7 +305,7 @@ case $basic_machine in | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -313,6 +313,7 @@ case $basic_machine in | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -327,6 +328,9 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none @@ -372,12 +376,13 @@ case $basic_machine in | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ + | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ @@ -424,12 +429,13 @@ case $basic_machine in | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -437,6 +443,7 @@ case $basic_machine in | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ + | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -513,6 +520,9 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; + asmjs) + basic_machine=asmjs-unknown + ;; aux) basic_machine=m68k-apple os=-aux @@ -633,6 +643,14 @@ case $basic_machine in basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -774,6 +792,9 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; m68knommu) basic_machine=m68k-unknown os=-linux @@ -1365,18 +1386,18 @@ case $os in | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ @@ -1385,7 +1406,8 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1517,6 +1539,8 @@ case $os in ;; -nacl*) ;; + -ios) + ;; -none) ;; *) commit 851a9de23ac0977c66f5ef56f08d8ca5eae92930 Author: Ineiev Date: Wed Aug 17 14:31:12 2016 +0200 po: Update Russian translation diff --git a/po/ru.po b/po/ru.po index 15689a7..23c092d 100644 --- a/po/ru.po +++ b/po/ru.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: GnuPG 1.4.18\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2015-06-25 17:16+0200\n" +"PO-Revision-Date: 2015-12-21 17:16+0200\n" "Last-Translator: Ineiev \n" "Language-Team: Russian \n" "Language: ru\n" @@ -263,7 +263,7 @@ msgstr "?????????????????? ???? ?????????? ???? ?????????????????? ?? ?????????? #, c-format msgid "card does not support digest algorithm %s\n" -msgstr "?????????? ???? ???????????????????????? ??????-?????????????? %s\n" +msgstr "?????????? ???? ???????????????????????? ??????-?????????????? %s\n" #, c-format msgid "signatures created so far: %lu\n" @@ -540,10 +540,10 @@ msgid "unknown key protection algorithm\n" msgstr "?????????????????????? ???????????????? ???????????? ??????????\n" msgid "secret parts of key are not available\n" -msgstr "???????????????? ?????????? ?????????? ????????????????????\n" +msgstr "?????????????????? ?????????? ?????????? ????????????????????\n" msgid "secret key already stored on a card\n" -msgstr "???????????????? ???????? ?????? ???????????????? ???? ??????????\n" +msgstr "?????????????????? ???????? ?????? ???????????????? ???? ??????????\n" #, c-format msgid "error writing key to card: %s\n" @@ -676,7 +676,7 @@ msgid "Delete this key from the keyring? (y/N) " msgstr "?????????????? ???????????? ???????? ???? ??????????????? (y/N) " msgid "This is a secret key! - really delete? (y/N) " -msgstr "?????? ???????????????? ????????! - ?????? ?????????? ??????????????? (y/N) " +msgstr "?????? ?????????????????? ????????! - ?????? ?????????? ??????????????? (y/N) " #, c-format msgid "deleting keyblock failed: %s\n" @@ -687,7 +687,7 @@ msgstr "???????????????? ?? ?????????????? ?????????????????? ????????????????\n #, c-format msgid "there is a secret key for public key \"%s\"!\n" -msgstr "?????????????? ???????????????? ???????? ?????? ?????????????????? ?????????? \"%s\"!\n" +msgstr "?????? ?????????????????? ?????????? \"%s\" ???????? ?????????????????? ????????!\n" msgid "use option \"--delete-secret-keys\" to delete it first.\n" msgstr "?????????????? ?????????????? ?????? ???????????????? \"--delete-secret-keys\".\n" @@ -832,7 +832,7 @@ msgid "remove as much as possible from key during export" msgstr "?????????????? ?????? ?????????? ???????????? ???? ?????????? ?????? ????????????????" msgid "exporting secret keys not allowed\n" -msgstr "?????????????? ???????????????? ???????????? ???? ????????????????\n" +msgstr "?????????????? ?????????????????? ???????????? ???? ????????????????\n" #, c-format msgid "key %s: not protected - skipped\n" @@ -855,7 +855,7 @@ msgstr "???????? ???????????? ???????????? ?? ??????????: %s\n" #, c-format msgid "WARNING: secret key %s does not have a simple SK checksum\n" -msgstr "????????????????: ???????????????? ???????? %s ???? ?????????? ?????????????? ?????????????????????? ?????????? SK\n" +msgstr "????????????????: ?? ???????????????????? ?????????? %s ?????? ?????????????? ?????????????????????? ?????????? SK\n" msgid "WARNING: nothing exported\n" msgstr "????????????????: ???????????? ????????????????????????????\n" @@ -901,7 +901,7 @@ msgid "list keys and fingerprints" msgstr "?????????????? ???????????? ???????????? ?? ???? ????????????????????" msgid "list secret keys" -msgstr "?????????????? ???????????? ???????????????? ????????????" +msgstr "?????????????? ???????????? ?????????????????? ????????????" msgid "generate a new key pair" msgstr "?????????????? ?????????? ???????? ????????????" @@ -910,7 +910,7 @@ msgid "remove keys from the public keyring" msgstr "?????????????? ?????????? ???? ?????????????? ???????????????? ????????????" msgid "remove keys from the secret keyring" -msgstr "?????????????? ?????????? ???? ?????????????? ???????????????? ????????????" +msgstr "?????????????? ?????????? ???? ?????????????? ?????????????????? ????????????" msgid "sign a key" msgstr "?????????????????? ????????" @@ -955,7 +955,7 @@ msgid "update the trust database" msgstr "???????????????? ?????????????? ??????????????" msgid "|algo [files]|print message digests" -msgstr "|algo [files]|?????????????? ???????? ????????????" +msgstr "|algo [files]|?????????????? ???????? ????????????" msgid "" "@\n" @@ -1304,13 +1304,13 @@ msgid "selected cipher algorithm is invalid\n" msgstr "???????????? ???????????????? ???????????????? ????????????????????\n" msgid "selected digest algorithm is invalid\n" -msgstr "?????????????? ???????????????? ??????-??????????????\n" +msgstr "?????????????? ???????????????? ??????-??????????????\n" msgid "selected compression algorithm is invalid\n" msgstr "???????????? ???????????????? ???????????????? ????????????\n" msgid "selected certification digest algorithm is invalid\n" -msgstr "?????????????? ???????????????? ??????-?????????????? ?????? ????????????????????????\n" +msgstr "?????????????? ???????????????? ??????-?????????????? ?????? ????????????????????????\n" msgid "completes-needed must be greater than 0\n" msgstr "completes-needed ???????????? ???????? ???????????? 0\n" @@ -1340,7 +1340,7 @@ msgid "invalid personal cipher preferences\n" msgstr "???????????????????????? ???????????????????????? ???????????????????????? ??????????\n" msgid "invalid personal digest preferences\n" -msgstr "???????????????????????? ???????????????????????? ???????????????????????? ??????-??????????????\n" +msgstr "???????????????????????? ???????????????????????? ???????????????????????? ??????-??????????????\n" msgid "invalid personal compress preferences\n" msgstr "???????????????????????? ???????????????????????? ???????????????????????? ???????????????????? ????????????\n" @@ -1355,7 +1355,7 @@ msgstr "???? ???? ???????????? ???????????????????????? ???????????????????? `%s #, c-format msgid "you may not use digest algorithm `%s' while in %s mode\n" -msgstr "???? ???? ???????????? ???????????????????????? ??????-?????????????? `%s' ?? ???????????? %s\n" +msgstr "???? ???? ???????????? ???????????????????????? ??????-?????????????? `%s' ?? ???????????? %s\n" #, c-format msgid "you may not use compression algorithm `%s' while in %s mode\n" @@ -1461,7 +1461,7 @@ msgstr "???????????? ???????????????????????????? ?? ?????????????????? ???????? #, c-format msgid "invalid hash algorithm `%s'\n" -msgstr "???????????????????????? ??????-?????????????? `%s'\n" +msgstr "???????????????????????? ??????-?????????????? `%s'\n" msgid "[filename]" msgstr "[????????]" @@ -1486,7 +1486,7 @@ msgstr "[ID ???????????????????????? ???? ????????????]" #, c-format msgid "key %s: secret key without public key - skipped\n" -msgstr "???????? %s: ???????????????? ???????? ?????? ?????????????????? ?????????? - ????????????????\n" +msgstr "???????? %s: ?????????????????? ???????? ?????? ?????????????????? ?????????? - ????????????????\n" #, c-format msgid "automatically retrieved `%s' via %s\n" @@ -1499,7 +1499,7 @@ msgstr "" #, c-format msgid "no secret subkey for public subkey %s - ignoring\n" -msgstr "?????? ?????????????????? ???????????????? ?????? ?????????????????? ???????????????? %s - ????????????????????\n" +msgstr "?????? ???????????????????? ???????????????? ?????? ?????????????????? ???????????????? %s - ????????????????????\n" #, c-format msgid "using subkey %s instead of primary key %s\n" @@ -1544,7 +1544,7 @@ msgid "" msgstr "" "?????? ???????????????????? ???????? ?????????????? GnuPG ???????????? ??????????, ?? ?????????? ????????????\n" "?????????????? ???????????????????? ?????????????? - ???????????? ?????? ??????????, ?????? ?????????????? ?? ?????? ????????\n" -"???????????????? ????????. ???????????????? \"yes\" ?????? ???????????????????? ?????????????????????? ??????????????\n" +"?????????????????? ????????. ???????????????? \"yes\" ?????? ???????????????????? ?????????????????????? ??????????????\n" "?????????????? ??????????\n" msgid "If you want to use this untrusted key anyway, answer \"yes\"." @@ -1801,7 +1801,7 @@ msgstr "" "???????????????? ???? ???????????? ?????????????? ???????? ???? ?????????????????? ??????????????????:\n" " \"???????? ?????? ????????????????????????????????\"\n" " ????????????????, ???????? ???? ??????????????????, ?????? ?????????????????????? ??????????????\n" -" ?????????????? ???????????? ?? ???????????? ?????????????????? ??????????.\n" +" ?????????????? ???????????? ?? ???????????? ???????????????????? ??????????.\n" " \"???????? ?????????????? ????????????\"\n" " ????????????????, ???????? ???? ???????????????? ???????????? ???????? ???? ????????????.\n" " \"???????? ???????????? ???? ????????????????????????\"\n" @@ -1840,7 +1840,7 @@ msgid "do not update the trustdb after import" msgstr "???? ?????????????????? ?????????????? ?????????????? ?????????? ??????????????" msgid "create a public key when importing a secret key" -msgstr "?????????????? ???????????????? ???????? ?????? ?????????????? ?????????????????? ??????????" +msgstr "?????????????? ???????????????? ???????? ?????? ?????????????? ???????????????????? ??????????" msgid "only accept updates to existing keys" msgstr "?????????????????? ???????????? ???????????????????????? ??????????" @@ -1898,15 +1898,15 @@ msgstr " ?????????? ?????????????? ????????????: %lu\n" #, c-format msgid " secret keys read: %lu\n" -msgstr " ?????????????? ???????????????? ????????????: %lu\n" +msgstr " ?????????????? ?????????????????? ????????????: %lu\n" #, c-format msgid " secret keys imported: %lu\n" -msgstr "?????????????????????????? ???????????????? ????????????: %lu\n" +msgstr "?????????????????????????? ?????????????????? ????????????: %lu\n" #, c-format msgid " secret keys unchanged: %lu\n" -msgstr " ???????????????????????? ???????????????? ????????????: %lu\n" +msgstr " ???????????????????????? ?????????????????? ????????????: %lu\n" #, c-format msgid " not imported: %lu\n" @@ -1935,7 +1935,7 @@ msgstr " \"%s\": ???????????????????????? ???????? %s\n" #, c-format msgid " \"%s\": preference for digest algorithm %s\n" -msgstr " \"%s\": ???????????????????????? ??????-?????????????? %s\n" +msgstr " \"%s\": ???????????????????????? ??????-?????????????? %s\n" #, c-format msgid " \"%s\": preference for compression algorithm %s\n" @@ -2061,30 +2061,30 @@ msgstr "???????? %s: \"%s\" ???? ??????????????\n" #, c-format msgid "secret key %s: %s\n" -msgstr "???????????????? ???????? %s: %s\n" +msgstr "?????????????????? ???????? %s: %s\n" msgid "importing secret keys not allowed\n" -msgstr "???????????? ?????????????????? ?????????? ???? ??????????????????????\n" +msgstr "???????????? ???????????????????? ?????????? ???? ??????????????????????\n" #, c-format msgid "key %s: secret key with invalid cipher %d - skipped\n" -msgstr "???????? %s: ???????????????? ???????? ?? ???????????????????????? ???????????? %d - ????????????????\n" +msgstr "???????? %s: ?????????????????? ???????? ?? ???????????????????????? ???????????? %d - ????????????????\n" #, c-format msgid "no default secret keyring: %s\n" -msgstr "?????? ???????????????? ?????????????? ???????????????? ????????????: %s\n" +msgstr "?????? ???????????????? ?????????????? ?????????????????? ????????????: %s\n" #, c-format msgid "key %s: secret key imported\n" -msgstr "???????? %s: ???????????????????????? ???????????????? ????????\n" +msgstr "???????? %s: ???????????????????????? ?????????????????? ????????\n" #, c-format msgid "key %s: already in secret keyring\n" -msgstr "???????? %s: ?????? ???????? ?? ?????????????? ???????????????? ????????????\n" +msgstr "???????? %s: ?????? ???????? ?? ?????????????? ?????????????????? ????????????\n" #, c-format msgid "key %s: secret key not found: %s\n" -msgstr "???????? %s: ???????????????? ???????? ???? ????????????: %s\n" +msgstr "???????? %s: ?????????????????? ???????? ???? ????????????: %s\n" #, c-format msgid "key %s: no public key - can't apply revocation certificate\n" @@ -2452,10 +2452,10 @@ msgid "This key is not protected.\n" msgstr "???????????? ???????? ???? ??????????????.\n" msgid "Secret parts of primary key are not available.\n" -msgstr "???????????????? ?????????? ???????????????? ?????????? ??????????????????????.\n" +msgstr "?????????????????? ?????????? ???????????????? ?????????? ??????????????????????.\n" msgid "Secret parts of primary key are stored on-card.\n" -msgstr "???????????????? ?????????? ???????????????? ?????????? ?????????????????? ???? ??????????.\n" +msgstr "?????????????????? ?????????? ???????????????? ?????????? ?????????????????? ???? ??????????.\n" msgid "Key is protected.\n" msgstr "???????? ??????????????.\n" @@ -2468,7 +2468,7 @@ msgid "" "Enter the new passphrase for this secret key.\n" "\n" msgstr "" -"?????????????? ?????????? ??????????-???????????? ?????? ?????????????? ?????????????????? ??????????.\n" +"?????????????? ?????????? ??????????-???????????? ?????? ?????????????? ???????????????????? ??????????.\n" "\n" msgid "passphrase not correctly repeated; try again" @@ -2554,7 +2554,7 @@ msgid "flag the selected user ID as primary" msgstr "???????????????? ?????????????????? ID ???????????????????????? ?????? ??????????????" msgid "toggle between the secret and public key listings" -msgstr "???????????????????????? ?????????? ???????????????????? ???????????????? ?? ???????????????? ????????????" +msgstr "???????????????????????? ?????????? ???????????????????? ???????????????? ?? ?????????????????? ????????????" msgid "list preferences (expert)" msgstr "???????????? ???????????????????????? (??????????????????)" @@ -2605,13 +2605,13 @@ msgstr "?????????? ?????????????????????? ID ?????????????????????????? ?? ???? #, c-format msgid "error reading secret keyblock \"%s\": %s\n" -msgstr "???????????? ???????????? ?????????????????? ?????????? ?????????? \"%s\": %s\n" +msgstr "???????????? ???????????? ???????????????????? ?????????? ?????????? \"%s\": %s\n" msgid "Secret key is available.\n" -msgstr "???????????????? ???????? ????????????????.\n" +msgstr "?????????????????? ???????? ????????????????.\n" msgid "Need the secret key to do this.\n" -msgstr "?????? ?????????????? ???????????????? ?????????? ???????????????? ????????.\n" +msgstr "?????? ?????????????? ???????????????? ?????????? ?????????????????? ????????.\n" msgid "Please use the command \"toggle\" first.\n" msgstr "?????????????? ???????????????????????????? ???????????????? \"toggle\".\n" @@ -2723,7 +2723,7 @@ msgstr "???????? ?????? ????????????????????: %s\n" #, c-format msgid "update secret failed: %s\n" -msgstr "???????? ?????? ???????????????????? ?????????????????? ??????????: %s\n" +msgstr "???????? ?????? ???????????????????? ???????????????????? ??????????: %s\n" msgid "Key not changed so no update needed.\n" msgstr "???????? ???? ?????????????????? - ???????????????????? ???? ??????????.\n" @@ -2911,7 +2911,7 @@ msgid "" msgstr "???? ??????????????, ?????? ???????????? ?????????????????? ???????????? ???????? ????????????????????? (y/N) " msgid "Please remove selections from the secret keys.\n" -msgstr "?????????????? ?????????????????? ?? ???????????????? ????????????.\n" +msgstr "?????????????? ?????????????????? ?? ?????????????????? ????????????.\n" msgid "Please select at most one subkey.\n" msgstr "???????????????? ???? ?????????? ???????????? ????????????????.\n" @@ -2926,7 +2926,7 @@ msgid "You can't change the expiration date of a v3 key\n" msgstr "???????????? ???????????????? ???????? ???????????????? ?????????? v3\n" msgid "No corresponding signature in secret ring\n" -msgstr "?????? ?????????????????????????????? ?????????????? ?? ?????????????? ???????????????? ????????????\n" +msgstr "?????? ?????????????????????????????? ?????????????? ?? ?????????????? ?????????????????? ????????????\n" #, c-format msgid "signing subkey %s is already cross-certified\n" @@ -2964,7 +2964,7 @@ msgstr "?????? ID ???????????????????????? ?? ???????????????? %d\n" #, c-format msgid "No user ID with hash %s\n" -msgstr "?????? ID ???????????????????????? ?? ?????????? %s\n" +msgstr "?????? ID ???????????????????????? ?? ?????????? %s\n" # c-format #, c-format @@ -3013,7 +3013,7 @@ msgid "Really create the revocation certificates? (y/N) " msgstr "?????????????????????????? ?????????????? ???????????????????? ????????????? (y/N) " msgid "no secret key\n" -msgstr "?????? ?????????????????? ??????????\n" +msgstr "?????? ???????????????????? ??????????\n" #, c-format msgid "user ID \"%s\" is already revoked\n" @@ -3043,7 +3043,7 @@ msgid "too many cipher preferences\n" msgstr "?????????????? ?????????? ???????????????? ????????????????????????\n" msgid "too many digest preferences\n" -msgstr "?????????????? ?????????? ???????????????????????? ?????? ??????-??????????????\n" +msgstr "?????????????? ?????????? ???????????????????????? ?????? ??????-??????????????\n" msgid "too many compression preferences\n" msgstr "?????????????? ?????????? ???????????????????????? ?????? ?????????????? ????????????\n" @@ -3315,7 +3315,7 @@ msgid "" "You need a Passphrase to protect your secret key.\n" "\n" msgstr "" -"?????? ???????????? ?????????????????? ?????????? ???????????????????? ??????????-????????????.\n" +"?????? ???????????? ???????????????????? ?????????? ???????????????????? ??????????-????????????.\n" "\n" #, c-format @@ -3354,11 +3354,11 @@ msgstr "???????????????????? ?????????????????? ?????????? ?? `%s'\n" #, c-format msgid "writing secret key stub to `%s'\n" -msgstr "???????????????????? ?????????????????? ?????????????????? ?????????? ?? `%s'\n" +msgstr "???????????????????? ?????????????????? ???????????????????? ?????????? ?? `%s'\n" #, c-format msgid "writing secret key to `%s'\n" -msgstr "???????????????????? ?????????????????? ?????????? ?? `%s'\n" +msgstr "???????????????????? ???????????????????? ?????????? ?? `%s'\n" #, c-format msgid "no writable public keyring found: %s\n" @@ -3366,7 +3366,7 @@ msgstr "?????? ?????????????????? ?????? ???????????? ?????????????? ?????????? #, c-format msgid "no writable secret keyring found: %s\n" -msgstr "?????? ?????????????????? ?????? ???????????? ?????????????? ???????????????? ????????????: %s\n" +msgstr "?????? ?????????????????? ?????? ???????????? ?????????????? ?????????????????? ????????????: %s\n" #, c-format msgid "error writing public keyring `%s': %s\n" @@ -3374,10 +3374,10 @@ msgstr "???????????? ???????????? ?????????????? ???????????????? ???????????? ` #, c-format msgid "error writing secret keyring `%s': %s\n" -msgstr "???????????? ???????????? ?????????????? ???????????????? ???????????? `%s': %s\n" +msgstr "???????????? ???????????? ?????????????? ?????????????????? ???????????? `%s': %s\n" msgid "public and secret key created and signed.\n" -msgstr "???????????????? ?? ???????????????? ?????????? ?????????????? ?? ??????????????????.\n" +msgstr "???????????????? ?? ?????????????????? ?????????? ?????????????? ?? ??????????????????.\n" msgid "" "Note that this key cannot be used for encryption. You may want to use\n" @@ -3647,7 +3647,7 @@ msgstr "?????????????????? ???????? ???????????????????? %s\n" #, c-format msgid "passphrase generated with unknown digest algorithm %d\n" -msgstr "??????????-???????????? ?????????????? ?? ???????????????????? ??????-???????????????? %d\n" +msgstr "??????????-???????????? ?????????????? ?? ???????????????????? ??????-???????????????? %d\n" #, c-format msgid "public key is %s\n" @@ -3766,7 +3766,7 @@ msgstr "?????????????? ?????????????????????????? ???? %s\n" #, c-format msgid "%s signature, digest algorithm %s\n" -msgstr "?????????????? ?? %s ??????????, ??????-?????????????? %s\n" +msgstr "?????????????? ?? %s ??????????, ??????-?????????????? %s\n" msgid "binary" msgstr "????????????????" @@ -3832,11 +3832,11 @@ msgstr "" #, c-format msgid "WARNING: using experimental digest algorithm %s\n" -msgstr "????????????????: ???????????????????????? ?????????????????????????????????? ??????-?????????????? %s\n" +msgstr "????????????????: ???????????????????????? ?????????????????????????????????? ??????-?????????????? %s\n" #, c-format msgid "WARNING: digest algorithm %s is deprecated\n" -msgstr "????????????????: ??????-?????????????? %s ???? ??????????????????????????\n" +msgstr "????????????????: ??????-?????????????? %s ???? ??????????????????????????\n" #, c-format msgid "please see %s for more information\n" @@ -3882,10 +3882,9 @@ msgstr "?????????????????????????? ???????????????? `%s'\n" msgid "unknown option `%s'\n" msgstr "?????????????????????? ???????????????? `%s'\n" -#, fuzzy, c-format -#| msgid "Unknown signature type `%s'\n" +#, c-format msgid "Unknown weak digest '%s'\n" -msgstr "?????????????????????? ?????? ?????????????? `%s'\n" +msgstr "?????????????????????? ???????????? ?????? '%s'\n" #, c-format msgid "File `%s' exists. " @@ -3960,7 +3959,7 @@ msgid "" "\"%.*s\"\n" "%u-bit %s key, ID %s, created %s%s\n" msgstr "" -"???????????????????? ??????????-???????????? ?????? ?????????????? ?? ?????????????????? ?????????? ????????????????????????:\n" +"???????????????????? ??????????-???????????? ?????? ?????????????? ?? ???????????????????? ?????????? ????????????????????????:\n" "\"%.*s\"\n" "%u-?????? %s ????????, ID %s, ???????????? %s ??????????????????????????%s\n" @@ -3984,7 +3983,7 @@ msgid "" "You need a passphrase to unlock the secret key for\n" "user: \"%s\"\n" msgstr "" -"???????????????????? ??????????-???????????? ?????? ?????????????? ?? ?????????????????? ?????????? ????????????????????????: \"%s\"\n" +"???????????????????? ??????????-???????????? ?????? ?????????????? ?? ???????????????????? ?????????? ????????????????????????: \"%s\"\n" #, c-format msgid "%u-bit %s key, ID %s, created %s" @@ -4283,7 +4282,7 @@ msgstr "???? ???????? ?????????????? ?????????????????????? ???????????? `%s'\n" #, c-format msgid "anonymous recipient; trying secret key %s ...\n" -msgstr "?????????????????? ????????????????????; ???????????? ???????????????? ???????? %s ...\n" +msgstr "?????????????????? ????????????????????; ???????????? ?????????????????? ???????? %s ...\n" msgid "okay, we are the anonymous recipient.\n" msgstr "??????????????, ???? - ?????????????????? ????????????????????.\n" @@ -4302,7 +4301,7 @@ msgstr "" #, c-format msgid "NOTE: secret key %s expired at %s\n" -msgstr "??????????????????: ???????????????? ???????? %s ?????????????????? ?? %s\n" +msgstr "??????????????????: ?????????????????? ???????? %s ?????????????????? ?? %s\n" msgid "NOTE: key has been revoked" msgstr "??????????????????: ???????? ?????? ??????????????" @@ -4341,14 +4340,14 @@ msgstr "?????????? ???????????? ?????? \"%s\" ???? ??????????????\n" #, c-format msgid "secret key \"%s\" not found: %s\n" -msgstr "???????????????? ???????? \"%s\" ???? ????????????: %s\n" +msgstr "?????????????????? ???????? \"%s\" ???? ????????????: %s\n" #, c-format msgid "no corresponding public key: %s\n" msgstr "?????? ???????????????????????????????? ?????????????????? ??????????: %s\n" msgid "public key does not match secret key!\n" -msgstr "???????????????? ???????? ???? ?????????????????????????? ??????????????????!\n" +msgstr "???????????????? ???????? ???? ?????????????????????????? ????????????????????!\n" msgid "Create a revocation certificate for this key? (y/N) " msgstr "?????????????? ???????????????????? ???????????? ?????????????? ??????????? (y/N) " @@ -4401,7 +4400,7 @@ msgid "Is this okay? (y/N) " msgstr "?????? ??????????????????? (y/N) " msgid "secret key parts are not available\n" -msgstr "???????????????? ?????????? ?????????? ????????????????????\n" +msgstr "?????????????????? ?????????? ?????????? ????????????????????\n" #, c-format msgid "protection algorithm %d%s is not supported\n" @@ -4409,7 +4408,7 @@ msgstr "?????????? ???????????? %d%s ???? ????????????????????????????\n" #, c-format msgid "protection digest %d is not supported\n" -msgstr "?????????? ???????????? %d ???? ????????????????????????????\n" +msgstr "?????????? ???????????? ???????? %d ???? ????????????????????????????\n" msgid "Invalid passphrase; please try again" msgstr "???????????????? ??????????-????????????; ???????????????????? ?????? ??????" @@ -4434,18 +4433,18 @@ msgstr "" "???????????????????? ???????????????? ?????????????? ?????????? ?????? ?????????????????????????? ??????????; %d ??????????????!\n" msgid "DSA requires the hash length to be a multiple of 8 bits\n" -msgstr "DSA ?????????????? ?????????? ????????, ?????????????? 8 ??????????\n" +msgstr "DSA ?????????????? ?????????? ????????, ?????????????? 8 ??????????\n" #, c-format msgid "DSA key %s uses an unsafe (%u bit) hash\n" -msgstr "???????? DSA %s ???????????????????? ???????????????????????? (%u-????????????) ??????\n" +msgstr "???????? DSA %s ???????????????????? ???????????????????????? (%u-????????????) ??????\n" #, c-format msgid "DSA key %s requires a %u bit or larger hash\n" -msgstr "???????? DSA %s ?????????????? %u-?????????????? ?????? ?????????? ???????????????? ????????\n" +msgstr "???????? DSA %s ?????????????? %u-?????????????? ?????? ?????????? ???????????????? ????????\n" msgid "WARNING: signature digest conflict in message\n" -msgstr "????????????????: ???????????????? ?????????? ???????????????? ?? ??????????????????\n" +msgstr "????????????????: ???????????????? ?????????? ???????????????? ?? ??????????????????\n" #, c-format msgid "WARNING: signing subkey %s is not cross-certified\n" @@ -4481,10 +4480,9 @@ msgstr "" msgid "NOTE: signature key %s expired %s\n" msgstr "??????????????????: ???????? ???????????????? ???????????????????????? ?????????? %s ?????????? %s\n" -#, fuzzy, c-format -#| msgid "%s signature, digest algorithm %s\n" +#, c-format msgid "Note: signatures using the %s algorithm are rejected\n" -msgstr "?????????????? ?? %s ??????????, ??????-?????????????? %s\n" +msgstr "??????????????????: ?????????????? ?? ???????????????????????????? ?????????????????? %s ???? ??????????????????????\n" #, c-format msgid "assuming bad signature from key %s due to an unknown critical bit\n" @@ -4536,7 +4534,7 @@ msgstr "" msgid "" "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n" msgstr "" -"????????????????: ?????????????????????????? ??????-?????????????? %s (%d) ???????????????? ???????????????????????? " +"????????????????: ?????????????????????????? ??????-?????????????? %s (%d) ???????????????? ???????????????????????? " "????????????????????\n" msgid "signing:" @@ -4564,7 +4562,7 @@ msgid "skipped \"%s\": %s\n" msgstr "?????????????????? \"%s\": %s\n" msgid "skipped: secret key already present\n" -msgstr "??????????????????: ???????????????? ???????? ?????? ??????????????\n" +msgstr "??????????????????: ?????????????????? ???????? ?????? ??????????????\n" msgid "this is a PGP generated Elgamal key which is not secure for signatures!" msgstr "" @@ -4658,7 +4656,7 @@ msgstr "%s: ?????????????????????? ?????????????? ??????????????\n" #, c-format msgid "%s: failed to create hashtable: %s\n" -msgstr "%s: ???????? ???????????????? ?????????????? ??????????: %s\n" +msgstr "%s: ???????? ???????????????? ?????????????? ??????????: %s\n" #, c-format msgid "%s: error updating version record: %s\n" @@ -4890,13 +4888,13 @@ msgid "unknown pubkey algorithm" msgstr "?????????????????????? ???????????????? ?? ???????????????? ????????????" msgid "unknown digest algorithm" -msgstr "?????????????????????? ??????-??????????????" +msgstr "?????????????????????? ??????-??????????????" msgid "bad public key" msgstr "???????????? ???????????????? ????????" msgid "bad secret key" -msgstr "???????????? ???????????????? ????????" +msgstr "???????????? ?????????????????? ????????" msgid "bad signature" msgstr "?????????????? ??????????????" @@ -4926,10 +4924,10 @@ msgid "no such user id" msgstr "?????? ???????????? ID ????????????????????????" msgid "secret key not available" -msgstr "???????????????? ???????? ???? ????????????" +msgstr "?????????????????? ???????? ???? ????????????" msgid "wrong secret key used" -msgstr "?????????????????????? ???????????????????????? ???????????????? ????????" +msgstr "?????????????????????? ???????????????????????? ?????????????????? ????????" msgid "not supported" msgstr "???? ????????????????????????????" @@ -5028,7 +5026,7 @@ msgid "unusable public key" msgstr "?????????????????????? ???????????????? ????????" msgid "unusable secret key" -msgstr "?????????????????????? ???????????????? ????????" +msgstr "?????????????????????? ?????????????????? ????????" msgid "keyserver error" msgstr "???????????? ?????????????? ????????????" @@ -5163,7 +5161,7 @@ msgstr "(????????????????, ???? ?????????????????????? ?????? ???????? ???????? #~ msgstr "???????????? ?????????????? URL ???????????? ?? v3 (PGP 2.x ??????????) ??????????????\n" #~ msgid "DSA requires the use of a 160 bit hash algorithm\n" -#~ msgstr "DSA ?????????????? ?????????????????????????? 160-???????????? ??????-??????????????\n" +#~ msgstr "DSA ?????????????? ?????????????????????????? 160-???????????? ??????-??????????????\n" #~ msgid "" #~ "please see http://www.gnupg.org/why-not-idea.html for more information\n" commit c6dbfe89903d0c8191cf50ecf1abb3c8458b427a Author: Werner Koch Date: Wed Aug 17 11:15:50 2016 +0200 random: Hash continuous areas in the csprng pool. * cipher/random.c (mix_pool): Store the first hash at the end of the pool. -- This fixes a long standing bug (since 1998) in Libgcrypt and GnuPG. An attacker who obtains 580 bytes of the random number from the standard RNG can trivially predict the next 20 bytes of output. This bug does not affect the default generation of keys because running gpg for key creation creates at most 2 keys from the pool: For a single 4096 bit RSA key 512 byte of random are required and thus for the second key (encryption subkey), 20 bytes could be predicted from the the first key. However, the security of an OpenPGP key depends on the primary key (which was generated first) and thus the 20 predictable bytes should not be a problem. For the default key length of 2048 bit nothing will be predictable. For the former default of DSA+Elgamal key it is complicate to give an answer: For 2048 bit keys a pool of 30 non-secret candidate primes of about 300 bits each are first created. This reads at least 1140 bytes from the pool and thus parts could be predicted. At some point a 256 bit secret is read from the pool; which in the worst case might be partly predictable. The bug was found and reported by Felix D??rre and Vladimir Klebanov, Karlsruhe Institute of Technology. A paper describing the problem in detail will shortly be published. CVE-id: CVE-2016-6313 Signed-off-by: Werner Koch diff --git a/cipher/random.c b/cipher/random.c index be2f51a..5f7de51 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -360,23 +360,21 @@ mix_pool(byte *pool) #if DIGESTLEN != 20 #error must have a digest length of 20 for ripe-md-160 #endif - /* loop over the pool */ + /* pool -> pool' */ pend = pool + POOLSIZE; memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); rmd160_mixblock( &md, hashbuf); memcpy(pool, hashbuf, DIGESTLEN); + /* Loop for the remaining iterations. */ p = pool; for( n=1; n < POOLBLOCKS; n++ ) { - memcpy(hashbuf, p, DIGESTLEN ); - - p += DIGESTLEN; - if( p+DIGESTLEN+BLOCKLEN < pend ) - memcpy(hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); + if( p + BLOCKLEN < pend ) + memcpy(hashbuf, p, BLOCKLEN); else { - char *pp = p+DIGESTLEN; - for(i=DIGESTLEN; i < BLOCKLEN; i++ ) { + char *pp = p; + for(i=0; i < BLOCKLEN; i++ ) { if( pp >= pend ) pp = pool; hashbuf[i] = *pp++; @@ -384,6 +382,7 @@ mix_pool(byte *pool) } rmd160_mixblock( &md, hashbuf); + p += DIGESTLEN; memcpy(p, hashbuf, DIGESTLEN); } burn_stack (384); /* for the rmd160_mixblock() */ commit e23eec8c9a602eee0a09851a54db0f5d611f125c Author: Werner Koch Date: Wed Aug 17 11:03:07 2016 +0200 cipher: Improve readability by using a macro. * cipher/random.c (mix_pool): Use DIGESTLEN instead of 20. Signed-off-by: Werner Koch diff --git a/cipher/random.c b/cipher/random.c index 7549517..be2f51a 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -365,7 +365,7 @@ mix_pool(byte *pool) memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); rmd160_mixblock( &md, hashbuf); - memcpy(pool, hashbuf, 20 ); + memcpy(pool, hashbuf, DIGESTLEN); p = pool; for( n=1; n < POOLBLOCKS; n++ ) { @@ -384,7 +384,7 @@ mix_pool(byte *pool) } rmd160_mixblock( &md, hashbuf); - memcpy(p, hashbuf, 20 ); + memcpy(p, hashbuf, DIGESTLEN); } burn_stack (384); /* for the rmd160_mixblock() */ } ----------------------------------------------------------------------- Summary of changes: Makefile.am | 13 ++++ NEWS | 15 ++++- README | 32 ++++++---- cipher/random.c | 19 +++--- configure.ac | 2 +- g10/gpg.c | 5 ++ po/be.po | 8 +-- po/ca.po | 8 +-- po/cs.po | 8 +-- po/da.po | 8 +-- po/de.po | 8 +-- po/el.po | 8 +-- po/eo.po | 8 +-- po/es.po | 8 +-- po/et.po | 8 +-- po/fi.po | 8 +-- po/fr.po | 8 +-- po/gl.po | 8 +-- po/hu.po | 8 +-- po/id.po | 8 +-- po/it.po | 8 +-- po/ja.po | 11 ++-- po/nb.po | 8 +-- po/nl.po | 8 +-- po/pl.po | 8 +-- po/pt.po | 8 +-- po/pt_BR.po | 8 +-- po/ro.po | 8 +-- po/ru.po | 170 +++++++++++++++++++++++++-------------------------- po/sk.po | 8 +-- po/sv.po | 8 +-- po/tr.po | 8 +-- po/uk.po | 8 +-- po/zh_CN.po | 8 +-- po/zh_TW.po | 8 +-- scripts/config.guess | 168 ++++++++++++++++++++++++++++++-------------------- scripts/config.sub | 58 ++++++++++++------ 37 files changed, 402 insertions(+), 307 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 15:40:20 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 15:40:20 +0200 Subject: [git] gnupg-doc - branch, master, updated. a8c31f231624437360bf3f82a1b55ac7db79caeb 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 a8c31f231624437360bf3f82a1b55ac7db79caeb (commit) from c6d8a1bfeed3328af23815c9b9e8eebda6d819b4 (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 a8c31f231624437360bf3f82a1b55ac7db79caeb Author: Werner Koch Date: Wed Aug 17 15:36:53 2016 +0200 swdb: New releases of gnupg 1.4 and Libgcrypt. diff --git a/web/swdb.mac b/web/swdb.mac index e2b2988..e65bffe 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -38,17 +38,16 @@ # # GnuPG-1 # -#+macro: gnupg1_ver 1.4.20 -#+macro: gnupg1_date 2015-12-20 +#+macro: gnupg1_ver 1.4.21 +#+macro: gnupg1_date 2016-08-17 #+macro: gnupg1_branch STABLE-BRANCH-1-4 -#+macro: gnupg1_size 3606k -#+macro: gnupg1_size_gz 5036k -#+macro: gnupg1_sha1 cbc9d960e3d8488c32675019a79fbfbf8680387e -#+macro: gnupg1_sha1_gz 359e464bcabbe370696e3dba45a1d63968c06ab3 +#+macro: gnupg1_size 3602k +#+macro: gnupg1_sha1 e3bdb585026f752ae91360f45c28e76e4a15d338 +#+macro: gnupg1_sha2 6b47a3100c857dcab3c60e6152e56a997f2c7862c1b8b2b25adf3884a1ae2276 # -#+macro: gnupg1_w32cli_ver 1.4.20 -#+macro: gnupg1_w32cli_size 2359k -#+macro: gnupg1_w32cli_sha1 8f0c4760c9f38102f64a156744ec8a428298b92d +#+macro: gnupg1_w32cli_ver 1.4.21 +#+macro: gnupg1_w32cli_size 2363k +#+macro: gnupg1_w32cli_sha 8edea5cda7dc9e39d12b24cf12164b28b832918d # @@ -82,11 +81,11 @@ # # LIBGCRYPT # -#+macro: libgcrypt_ver 1.7.2 -#+macro: libgcrypt_date 2016-07-14 -#+macro: libgcrypt_size 2778k -#+macro: libgcrypt_sha1 85a6a936bcab4c3c05f5efbf6ce847f23d35c0c4 -#+macro: libgcrypt_sha2 3d35df906d6eab354504c05d749a9b021944cb29ff5f65c8ef9c3dd5f7b6689f +#+macro: libgcrypt_ver 1.7.3 +#+macro: libgcrypt_date 2016-08-17 +#+macro: libgcrypt_size 2794k +#+macro: libgcrypt_sha1 5a034291e7248592605db448481478e6c963aa9c +#+macro: libgcrypt_sha2 ddac6111077d0a1612247587be238c5294dd0ee4d76dc7ba783cc55fb0337071 # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 18:15:22 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 18:15:22 +0200 Subject: [git] gnupg-doc - branch, master, updated. 66f497fb58d5312945f7a8dd861a0e5212b12a66 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 66f497fb58d5312945f7a8dd861a0e5212b12a66 (commit) from a8c31f231624437360bf3f82a1b55ac7db79caeb (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 66f497fb58d5312945f7a8dd861a0e5212b12a66 Author: Werner Koch Date: Wed Aug 17 18:13:01 2016 +0200 web: Announcing Libgcrypt and GnUPG security fixes. diff --git a/web/index.org b/web/index.org index c11c0af..d4945e3 100644 --- a/web/index.org +++ b/web/index.org @@ -79,6 +79,12 @@ The latest release news:\\ # 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 # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** Security fixes for Libgcrypt and GnuPG 1.4 :important: + +A bug in the random number generator of Libgcrypt and in GnuPG 1.4 has +been found. Updating the software is highly suggested. Please read +this [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000395.html][mail]] for details. + ** GnuPG 2.1.14 released (2016-07-14) A new version of the /modern/ branch of GnuPG has been released. ----------------------------------------------------------------------- Summary of changes: web/index.org | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 19:03:34 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 19:03:34 +0200 Subject: [git] gnupg-doc - branch, master, updated. 779fd17acf7dd046212204b58fabce58ff5c1f9e 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 779fd17acf7dd046212204b58fabce58ff5c1f9e (commit) from 66f497fb58d5312945f7a8dd861a0e5212b12a66 (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 779fd17acf7dd046212204b58fabce58ff5c1f9e Author: Werner Koch Date: Wed Aug 17 19:01:09 2016 +0200 web: Fix CVE id. diff --git a/web/index.org b/web/index.org index d4945e3..d183616 100644 --- a/web/index.org +++ b/web/index.org @@ -83,7 +83,8 @@ The latest release news:\\ A bug in the random number generator of Libgcrypt and in GnuPG 1.4 has been found. Updating the software is highly suggested. Please read -this [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000395.html][mail]] for details. +this [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000395.html][mail]] for details. Note that the CVE id in that mail is not +correct, the correct one is CVE-2016-6313. ** GnuPG 2.1.14 released (2016-07-14) ----------------------------------------------------------------------- Summary of changes: web/index.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 17 19:37:48 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 17 Aug 2016 19:37:48 +0200 Subject: [git] gnupg-doc - branch, master, updated. 502288add2508d8b86bda0f547bc47e323b8221d 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 502288add2508d8b86bda0f547bc47e323b8221d (commit) from 779fd17acf7dd046212204b58fabce58ff5c1f9e (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 502288add2508d8b86bda0f547bc47e323b8221d Author: Werner Koch Date: Wed Aug 17 19:35:27 2016 +0200 web: Remove bogus local variables line. diff --git a/web/faq/gnupg-faq.org b/web/faq/gnupg-faq.org index 16f6472..7698b83 100644 --- a/web/faq/gnupg-faq.org +++ b/web/faq/gnupg-faq.org @@ -2220,7 +2220,3 @@ PGP 2.6 support. (setq h (downcase h)) (org-entry-put nil "CUSTOM_ID" h))) #+end_src - - -# End: -# Local Variables: ----------------------------------------------------------------------- Summary of changes: web/faq/gnupg-faq.org | 4 ---- 1 file changed, 4 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 12:04:01 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 12:04:01 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-85-gd83ba48 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 d83ba4897bf217d1045c58d1b99e52bd31c58812 (commit) via de6e3217cde81df370926571e0fd65e468619803 (commit) from b5d63e81d5c472647decc7687cef91fee0378eb8 (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 d83ba4897bf217d1045c58d1b99e52bd31c58812 Author: Werner Koch Date: Thu Aug 18 11:23:40 2016 +0200 dirmngr: Remove all system daemon features. * dirmngr/dirmngr.h (opts): Remove fields 'system_service' and 'system_daemon'. * common/homedir.c (dirmngr_sys_socket_name): Remove. (dirmngr_user_socket_name): Rename to ... (dirmngr_socket_name): this. Change call callers. * common/asshelp.c (start_new_dirmngr): Remove the system socket feature. * tools/gpgconf.c (list_dirs): Do not print "dirmngr-sys-socket". * sm/server.c (gpgsm_server): Adjust for removed system socket feature. * dirmngr/server.c (cmd_getinfo): Ditto. (cmd_killdirmngr): Remove check for system daemon. (cmd_reloaddirmngr): Ditto. * dirmngr/dirmngr.c (USE_W32_SERVICE): Remove macro. (aService): Remove. (opts): Remove --service. (w32_service_control): Remove. (real_main, call_real_main) [W32]: Remove wrapper. (main): Remove Windows system service feature. Remove system dameon feature. Use only the "~/.gnupg/dirmngr_ldapservers.conf" file. * dirmngr/certcache.c (load_certs_from_dir): Remove warning in the system dameon case. * dirmngr/crlcache.c (DBDIR_D): Always use "~/.gnupg/crls.d". * dirmngr/ocsp.c (validate_responder_cert): Do not call validate_cert_chain which was used only in system daemon mode. * dirmngr/validate.c (validate_cert_chain): Always use the code. -- We are now starting dirmngr as needed as a user daemon. The deprecated system daemon mode does not anymore make sense. In case a system wide daemon is required, it is better to setup a dedicated account to run dirmngr and tweak socket permissions accordingly. Signed-off-by: Werner Koch diff --git a/common/asshelp.c b/common/asshelp.c index 5c32c6e..c03e67b 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -564,18 +564,7 @@ start_new_dirmngr (assuan_context_t *r_ctx, return err; } - sockname = dirmngr_user_socket_name (); - if (sockname) - { - /* First try the local socket name and only if that fails try - the system socket. */ - err = assuan_socket_connect (ctx, sockname, 0, 0); - if (err) - sockname = dirmngr_sys_socket_name (); - } - else - sockname = dirmngr_sys_socket_name (); - + sockname = dirmngr_socket_name (); err = assuan_socket_connect (ctx, sockname, 0, 0); #ifdef USE_DIRMNGR_AUTO_START @@ -583,22 +572,9 @@ start_new_dirmngr (assuan_context_t *r_ctx, { lock_spawn_t lock; const char *argv[4]; - int try_system_daemon = 0; char *abs_homedir; - /* No connection: Try start a new Dirmngr. On Windows this will - fail because the Dirmngr is expected to be a system service. - However on WinCE we don't distinguish users and thus we can - start it. */ - - /* We prefer to start it as a user daemon. */ - sockname = dirmngr_user_socket_name (); - if (!sockname) - { - sockname = dirmngr_sys_socket_name (); - try_system_daemon = 1; - } - + /* No connection: Try start a new Dirmngr. */ if (!dirmngr_program || !*dirmngr_program) dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); @@ -631,20 +607,11 @@ start_new_dirmngr (assuan_context_t *r_ctx, } argv[0] = "--daemon"; - if (try_system_daemon) - argv[1] = NULL; - else - { /* Try starting as user daemon - dirmngr does this if the - home directory is given on the command line. */ - argv[1] = "--homedir"; - argv[2] = abs_homedir; - argv[3] = NULL; - } - - /* On the use of HOMEDIR for locking: Under Windows HOMEDIR is - not used thus it does not matter. Under Unix we should - TRY_SYSTEM_DAEMON should never be true because - dirmngr_user_socket_name() won't return NULL. */ + /* Try starting the daemon. Versions of dirmngr < 2.1.15 do + * this only if the home directory is given on the command line. */ + argv[1] = "--homedir"; + argv[2] = abs_homedir; + argv[3] = NULL; if (!(err = lock_spawning (&lock, gnupg_homedir (), "dirmngr", verbose)) && assuan_socket_connect (ctx, sockname, 0, 0)) diff --git a/common/homedir.c b/common/homedir.c index 9a69022..574561a 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -812,55 +812,9 @@ gnupg_cachedir (void) } -/* Return the system socket name used by DirMngr. */ +/* Return the user socket name used by DirMngr. */ const char * -dirmngr_sys_socket_name (void) -{ -#ifdef HAVE_W32_SYSTEM - static char *name; - - if (!name) - { - char *p; -# ifdef HAVE_W32CE_SYSTEM - const char *s1, *s2; - - s1 = default_homedir (); -# else - char s1buf[MAX_PATH]; - const char *s1, *s2; - - s1 = default_homedir (); - if (!w32_portable_app) - { - /* We need something akin CSIDL_COMMON_PROGRAMS, but local - (non-roaming). This is because the file needs to be on - the local machine and makes only sense on that machine. - CSIDL_WINDOWS seems to be the only location which - guarantees that. */ - if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1buf) < 0) - strcpy (s1buf, "C:\\WINDOWS"); - s1 = s1buf; - } -# endif - s2 = DIRSEP_S DIRMNGR_SOCK_NAME; - name = xmalloc (strlen (s1) + strlen (s2) + 1); - strcpy (stpcpy (name, s1), s2); - for (p=name; *p; p++) - if (*p == '/') - *p = '\\'; - } - return name; -#else /*!HAVE_W32_SYSTEM*/ - return GNUPG_LOCALSTATEDIR "/run/" PACKAGE_NAME "/"DIRMNGR_SOCK_NAME; -#endif /*!HAVE_W32_SYSTEM*/ -} - - -/* Return the user socket name used by DirMngr. If a user specific - dirmngr installation is not supported, NULL is returned. */ -const char * -dirmngr_user_socket_name (void) +dirmngr_socket_name (void) { static char *name; diff --git a/common/util.h b/common/util.h index 6680414..1c3cce9 100644 --- a/common/util.h +++ b/common/util.h @@ -227,8 +227,7 @@ const char *gnupg_libdir (void); const char *gnupg_datadir (void); const char *gnupg_localedir (void); const char *gnupg_cachedir (void); -const char *dirmngr_sys_socket_name (void); -const char *dirmngr_user_socket_name (void); +const char *dirmngr_socket_name (void); char *_gnupg_socketdir_internal (int skip_checks, unsigned *r_info); diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 45be1f2..9e741c1 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -348,9 +348,6 @@ load_certs_from_dir (const char *dirname, int are_trusted) dir = opendir (dirname); if (!dir) { - if (opt.system_daemon) - log_info (_("can't access directory '%s': %s\n"), - dirname, strerror (errno)); return 0; /* We do not consider this a severe error. */ } diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index af2a956..388754b 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -115,7 +115,7 @@ #include "cdb.h" /* Change this whenever the format changes */ -#define DBDIR_D (opt.system_daemon? "crls.d" : "dirmngr-cache.d") +#define DBDIR_D "crls.d" #define DBDIRFILE "DIR.txt" #define DBDIRVERSION 1 diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index cb17420..0667e59 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -70,15 +70,6 @@ #include "gc-opt-flags.h" #include "dns-stuff.h" -/* The plain Windows version uses the windows service system. For - example to start the service you may use "sc start dirmngr". - WindowsCE does not support this; the service system over there is - based on a single process with all services being DLLs - we can't - support this easily. */ -#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM) -# define USE_W32_SERVICE 1 -#endif - #ifndef ENAMETOOLONG # define ENAMETOOLONG EINVAL #endif @@ -94,7 +85,6 @@ enum cmd_and_opt_values { aServer, aDaemon, - aService, aListCRLs, aLoadCRL, aFetchCRL, @@ -155,9 +145,6 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aServer, "server", N_("run in server mode (foreground)") ), ARGPARSE_c (aDaemon, "daemon", N_("run in daemon mode (background)") ), -#ifdef USE_W32_SERVICE - ARGPARSE_c (aService, "service", N_("run as windows service (background)")), -#endif ARGPARSE_c (aListCRLs, "list-crls", N_("list the contents of the CRL cache")), ARGPARSE_c (aLoadCRL, "load-crl", N_("|FILE|load CRL from FILE into cache")), ARGPARSE_c (aFetchCRL, "fetch-crl", N_("|URL|fetch a CRL from URL")), @@ -635,42 +622,6 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) } -#ifdef USE_W32_SERVICE -/* The global status of our service. */ -SERVICE_STATUS_HANDLE service_handle; -SERVICE_STATUS service_status; - -DWORD WINAPI -w32_service_control (DWORD control, DWORD event_type, LPVOID event_data, - LPVOID context) -{ - (void)event_type; - (void)event_data; - (void)context; - - /* event_type and event_data are not used here. */ - switch (control) - { - case SERVICE_CONTROL_SHUTDOWN: - /* For shutdown we will try to force termination. */ - service_status.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus (service_handle, &service_status); - shutdown_pending = 3; - break; - - case SERVICE_CONTROL_STOP: - service_status.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus (service_handle, &service_status); - shutdown_pending = 1; - break; - - default: - break; - } - return 0; -} -#endif /*USE_W32_SERVICE*/ - #ifndef HAVE_W32_SYSTEM static int pid_suffix_callback (unsigned long *r_suffix) @@ -685,15 +636,9 @@ pid_suffix_callback (unsigned long *r_suffix) #endif /*!HAVE_W32_SYSTEM*/ -#ifdef USE_W32_SERVICE -# define main real_main -#endif int main (int argc, char **argv) { -#ifdef USE_W32_SERVICE -# undef main -#endif enum cmd_and_opt_values cmd = 0; ARGPARSE_ARGS pargs; int orig_argc; @@ -714,34 +659,9 @@ main (int argc, char **argv) #endif /*USE_LDAP*/ int debug_wait = 0; int rc; - int homedir_seen = 0; struct assuan_malloc_hooks malloc_hooks; early_system_init (); - -#ifdef USE_W32_SERVICE - /* The option will be set by main() below if we should run as a - system daemon. */ - if (opt.system_service) - { - service_handle - = RegisterServiceCtrlHandlerEx ("DirMngr", - &w32_service_control, NULL /*FIXME*/); - if (service_handle == 0) - log_error ("failed to register service control handler: ec=%d", - (int) GetLastError ()); - service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - service_status.dwCurrentState = SERVICE_START_PENDING; - service_status.dwControlsAccepted - = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - service_status.dwWin32ExitCode = NO_ERROR; - service_status.dwServiceSpecificExitCode = NO_ERROR; - service_status.dwCheckPoint = 0; - service_status.dwWaitHint = 10000; /* 10 seconds timeout. */ - SetServiceStatus (service_handle, &service_status); - } -#endif /*USE_W32_SERVICE*/ - set_strusage (my_strusage); log_set_prefix (DIRMNGR_NAME, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID); @@ -830,44 +750,10 @@ main (int argc, char **argv) else if (pargs.r_opt == oHomedir) { gnupg_set_homedir (pargs.r.ret_str); - homedir_seen = 1; } - else if (pargs.r_opt == aDaemon) - opt.system_daemon = 1; - else if (pargs.r_opt == aService) - { - /* Redundant. The main function takes care of it. */ - opt.system_service = 1; - opt.system_daemon = 1; - } -#ifdef HAVE_W32_SYSTEM - else if (pargs.r_opt == aGPGConfList || pargs.r_opt == aGPGConfTest) - /* We set this so we switch to the system configuration - directory below. This is a crutch to solve the problem - that the user configuration is never used on Windows. Also - see below at aGPGConfList. */ - opt.system_daemon = 1; -#endif - } - - /* If --daemon has been given on the command line but not --homedir, - we switch to /etc/gnupg as default home directory. Note, that - this also overrides the GNUPGHOME environment variable. */ - if (opt.system_daemon && !homedir_seen) - { -#ifdef HAVE_W32CE_SYSTEM - gnupg_set_homedir (DIRSEP_S "gnupg"); -#else - gnupg_set_homedir (gnupg_sysconfdir ()); -#endif - opt.homedir_cache = gnupg_cachedir (); - socket_name = dirmngr_sys_socket_name (); } - else if (dirmngr_user_socket_name ()) - socket_name = dirmngr_user_socket_name (); - else - socket_name = dirmngr_sys_socket_name (); + socket_name = dirmngr_socket_name (); if (default_config) configname = make_filename (gnupg_homedir (), DIRMNGR_NAME".conf", NULL ); @@ -911,7 +797,6 @@ main (int argc, char **argv) { case aServer: case aDaemon: - case aService: case aShutdown: case aFlush: case aListCRLs: @@ -1039,8 +924,7 @@ main (int argc, char **argv) if (!ldapfile) { ldapfile = make_filename (gnupg_homedir (), - opt.system_daemon? - "ldapservers.conf":"dirmngr_ldapservers.conf", + "dirmngr_ldapservers.conf", NULL); opt.ldapservers = parse_ldapserver_file (ldapfile); xfree (ldapfile); @@ -1058,9 +942,7 @@ main (int argc, char **argv) #endif /* Ready. Now to our duties. */ - if (!cmd && opt.system_service) - cmd = aDaemon; - else if (!cmd) + if (!cmd) cmd = aServer; rc = 0; @@ -1288,23 +1170,9 @@ main (int argc, char **argv) cert_cache_init (); crl_cache_init (); -#ifdef USE_W32_SERVICE - if (opt.system_service) - { - service_status.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus (service_handle, &service_status); - } -#endif handle_connections (fd); assuan_sock_close (fd); shutdown_reaper (); -#ifdef USE_W32_SERVICE - if (opt.system_service) - { - service_status.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus (service_handle, &service_status); - } -#endif } else if (cmd == aListCRLs) { @@ -1416,8 +1284,7 @@ main (int argc, char **argv) also only usable on the command line. --batch is unused. */ filename = make_filename (gnupg_homedir (), - opt.system_daemon? - "ldapservers.conf":"dirmngr_ldapservers.conf", + "dirmngr_ldapservers.conf", NULL); filename_esc = percent_escape (filename, NULL); es_printf ("ldapserverlist-file:%lu:\"%s\n", flags | GC_OPT_FLAG_DEFAULT, @@ -1457,45 +1324,6 @@ main (int argc, char **argv) } -#ifdef USE_W32_SERVICE -static void WINAPI -call_real_main (DWORD argc, LPSTR *argv) -{ - real_main (argc, argv); -} - -int -main (int argc, char *argv[]) -{ - int i; - - /* Find out if we run in daemon mode or on the command line. */ - for (i = 1; i < argc; i++) - if (!strcmp (argv[i], "--service")) - { - opt.system_service = 1; - opt.system_daemon = 1; - break; - } - - if (!opt.system_service) - return real_main (argc, argv); - else - { - SERVICE_TABLE_ENTRY DispatchTable [] = - { - { "DirMngr", &call_real_main }, - { NULL, NULL } - }; - - if (!StartServiceCtrlDispatcher (DispatchTable)) - return 1; - return 0; - } -} -#endif /*USE_W32_SERVICE*/ - - static void cleanup (void) { diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 8d90ae4..6127386 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -89,8 +89,6 @@ struct char *http_wrapper_program; /* Override value for the HTTP wrapper program. */ - int system_service; /* We are running as W32 service (implies daemon). */ - int system_daemon; /* We are running in system daemon mode. */ int running_detached; /* We are running in detached mode. */ int use_tor; /* Tor mode has been enabled. */ diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index 561b7d7..8c893aa 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -330,10 +330,6 @@ validate_responder_cert (ctrl_t ctrl, ksba_cert_t cert, } xfree (fpr); } - else if (opt.system_daemon) - { - err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_OCSP, NULL); - } else { /* We avoid duplicating the entire certificate validation code diff --git a/dirmngr/server.c b/dirmngr/server.c index db6f5a8..3ac4160 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2217,15 +2217,8 @@ cmd_getinfo (assuan_context_t ctx, char *line) } else if (!strcmp (line, "socket_name")) { - const char *s = dirmngr_user_socket_name (); - - if (!s) - s = dirmngr_sys_socket_name (); - - if (s) - err = assuan_send_data (ctx, s, strlen (s)); - else - err = gpg_error (GPG_ERR_NO_DATA); + const char *s = dirmngr_socket_name (); + err = assuan_send_data (ctx, s, strlen (s)); } else if (!strcmp (line, "tor")) { @@ -2269,29 +2262,12 @@ static gpg_error_t cmd_killdirmngr (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - gpg_error_t err; (void)line; - if (opt.system_daemon) - { - if (opt.system_service) - err = set_error (GPG_ERR_NOT_SUPPORTED, - "can't do that whilst running as system service"); - else - err = check_owner_permission (ctx, - "no permission to kill this process"); - } - else - err = 0; - - if (!err) - { - ctrl->server_local->stopme = 1; - assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1); - err = gpg_error (GPG_ERR_EOF); - } - return err; + ctrl->server_local->stopme = 1; + assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1); + return gpg_error (GPG_ERR_EOF); } @@ -2306,20 +2282,6 @@ cmd_reloaddirmngr (assuan_context_t ctx, char *line) (void)ctx; (void)line; - if (opt.system_daemon) - { -#ifndef HAVE_W32_SYSTEM - { - gpg_error_t err; - - err = check_owner_permission (ctx, - "no permission to reload this process"); - if (err) - return err; - } -#endif - } - dirmngr_sighup_action (); return 0; } diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 1a851b6..b3dc9d8 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -354,6 +354,10 @@ is_root_cert (ksba_cert_t cert, const char *issuerdn, const char *subjectdn) return the closest expiration time in R_EXPTIME (this is useful for caching issues). MODE is one of the VALIDATE_MODE_* constants. + Note that VALIDATE_MODE_OCSP is not used due to the removal of the + system service in 2.1.15. Instead only the callback to gpgsm to + validate a certificate is used. + If R_TRUST_ANCHOR is not NULL and the validation would fail only because the root certificate is not trusted, the hexified fingerprint of that root certificate is stored at R_TRUST_ANCHOR @@ -382,14 +386,6 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (r_trust_anchor) *r_trust_anchor = NULL; - if (!opt.system_daemon) - { - /* For backward compatibility we only do this in daemon mode. */ - log_info (_("running in compatibility mode - " - "certificate chain not checked!\n")); - return 0; /* Okay. */ - } - if (DBG_X509) dump_cert ("subject", cert); diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 033b5d3..d52fb89 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -34,11 +34,6 @@ providing access to OCSP providers. Dirmngr is invoked internally by @command{gpg}, @command{gpgsm}, or via the @command{gpg-connect-agent} tool. -For historical reasons it is also possible to start @command{dirmngr} -in a system daemon mode which uses a different directory layout. -However, this mode is deprecated and may eventually be removed. - - @manpause @noindent @xref{Option Index},for an index to @command{DIRMNGR}'s commands and @@ -468,9 +463,7 @@ Dirmngr makes use of several directories when running in daemon mode: @table @file @item ~/.gnupg - at itemx /etc/gnupg -The first is the standard home directory for all configuration files. -In the deprecated system daemon mode the second directory is used instead. +This is the standard home directory for all configuration files. @item /etc/gnupg/trusted-certs This directory should be filled with certificates of Root CAs you @@ -501,20 +494,10 @@ These certificates are first tried before going out to the net to look for them. These certificates must also be @acronym{DER} encoded and suffixed with @file{.crt} or @file{.der}. - at item @value{LOCALRUNDIR} -This directory is only used in the deprecated system daemon mode. It -keeps the socket file for accessing @command{dirmngr} services. The -name of the socket file will be @file{S.dirmngr}. Make sure that this -directory has the proper permissions to let @command{dirmngr} create -the socket file and that eligible users may read and write to that -socket. - @item ~/.gnupg/crls.d - at itemx @value{LOCALCACHEDIR}/crls.d -The first directory is used to store cached CRLs. The @file{crls.d} +This directory is used to store cached CRLs. The @file{crls.d} part will be created by dirmngr if it does not exists but you need to -make sure that the upper directory exists. The second directory is -used instead in the deprecated systems daemon mode. +make sure that the upper directory exists. @end table @manpause @@ -1040,10 +1023,6 @@ as a binary blob. @c works. Note that mainly testing purposes this functionality may be @c called directly using @cmd{dirmngr-client --validate @file{foo.crt}}. @c - at c For backward compatibility this function returns success if Dirmngr is - at c not used as a system daemon. Thus not validating the certicates at - at c all. FIXME: This is definitely not correct and should be fixed ASAP. - at c @c The function takes the target certificate and a mode argument as @c parameters and returns an error code and optionally the closes @c expiration time of all certificates in the chain. diff --git a/sm/server.c b/sm/server.c index cdccff3..ce8085d 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1318,9 +1318,7 @@ gpgsm_server (certlist_t default_recplist) "%s", gnupg_homedir (), opt.config_filename, - (dirmngr_user_socket_name () - ? dirmngr_user_socket_name () - : dirmngr_sys_socket_name ()), + dirmngr_socket_name (), hello) > 0) { assuan_set_hello_line (ctx, tmp); diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 69ea9c9..221e3e2 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -156,7 +156,6 @@ list_dirs (estream_t fp, char **names) const char *name; const char *(*fnc)(void); const char *extra; - int special; } list[] = { { "sysconfdir", gnupg_sysconfdir, NULL }, { "bindir", gnupg_bindir, NULL }, @@ -164,9 +163,7 @@ list_dirs (estream_t fp, char **names) { "libdir", gnupg_libdir, NULL }, { "datadir", gnupg_datadir, NULL }, { "localedir", gnupg_localedir, NULL }, - { "dirmngr-socket", dirmngr_user_socket_name, NULL, 1 }, - { "dirmngr-socket", dirmngr_sys_socket_name, NULL, 2 }, - { "dirmngr-sys-socket", dirmngr_sys_socket_name, NULL, 1 }, + { "dirmngr-socket", dirmngr_socket_name, NULL,}, { "agent-ssh-socket", gnupg_socketdir, GPG_AGENT_SSH_SOCK_NAME }, { "agent-socket", gnupg_socketdir, GPG_AGENT_SOCK_NAME }, { "homedir", gnupg_homedir, NULL } @@ -178,13 +175,6 @@ list_dirs (estream_t fp, char **names) for (idx = 0; idx < DIM (list); idx++) { - if (list[idx].special == 1 && dirmngr_user_socket_name ()) - ; - else if (list[idx].special == 2 && !dirmngr_user_socket_name ()) - ; - else if (list[idx].special == 1 || list[idx].special == 2) - continue; - s = list[idx].fnc (); if (list[idx].extra) { commit de6e3217cde81df370926571e0fd65e468619803 Author: Werner Koch Date: Thu Aug 18 10:08:34 2016 +0200 gpg: New option --sender * g10/options.h (struct opt): Add field 'sender_list'. * g10/gpg.c: Include mbox-util.h. (oSender): New. (opts): Add option "--sender". (main): Parse option. -- This option will eventually be used for more advanced purposes. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 894d384..b9a3ddc 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2087,6 +2087,15 @@ Remove all entries from the @option{--group} list. Use @var{name} as the key to sign with. Note that this option overrides @option{--default-key}. + at item --sender @var{mbox} + at opindex sender +This option has two purposes. @var{mbox} must either be a complete +user id with a proper mail address or just a mail address. When +creating a signature this option tells gpg the user id of a key used +to make a signature if the key was not directly specified by a user +id. When verifying a signature the @var{mbox} is used to restrict the +information printed by the TOFU code to matching user ids. + @item --try-secret-key @var{name} @opindex try-secret-key For hidden recipients GPG needs to know the keys to use for trial diff --git a/g10/gpg.c b/g10/gpg.c index 891c85f..e02efe4 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -60,6 +60,7 @@ #include "call-dirmngr.h" #include "tofu.h" #include "../common/init.h" +#include "../common/mbox-util.h" #include "../common/shareddefs.h" #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) @@ -406,6 +407,7 @@ enum cmd_and_opt_values oUnwrap, oOnlySignTextIDs, oDisableSignerUID, + oSender, oNoop }; @@ -525,6 +527,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oEncryptToDefaultKey, "encrypt-to-default-key", "@"), ARGPARSE_s_s (oLocalUser, "local-user", N_("|USER-ID|use USER-ID to sign or decrypt")), + ARGPARSE_s_s (oSender, "sender", "@"), ARGPARSE_s_s (oTrySecretKey, "try-secret-key", "@"), @@ -2907,6 +2910,19 @@ main (int argc, char **argv) if (configfp) sl->flags |= PK_LIST_CONFIG; break; + case oSender: + { + char *mbox = mailbox_from_userid (pargs.r.ret_str); + if (!mbox) + log_error (_("\"%s\" is not a proper mail address\n"), + pargs.r.ret_str); + else + { + add_to_strlist (&opt.sender_list, mbox); + xfree (mbox); + } + } + break; case oCompress: /* this is the -z command line option */ opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int; diff --git a/g10/options.h b/g10/options.h index 230c96a..6b8f649 100644 --- a/g10/options.h +++ b/g10/options.h @@ -101,6 +101,10 @@ struct int def_recipient_self; strlist_t secret_keys_to_try; + /* A list of mail addresses (addr-spec) provided by the user with + * the option --sender. */ + strlist_t sender_list; + int def_cert_level; int min_cert_level; int ask_cert_level; diff --git a/g10/sign.c b/g10/sign.c index 217196d..e5fbd9d 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -158,6 +158,21 @@ mk_notation_policy_etc (PKT_signature *sig, build_sig_subpkt (sig, SIGSUBPKT_SIGNERS_UID, mbox, strlen (mbox)); xfree (mbox); } + else if (opt.sender_list) + { + /* If a list of --sender was given we scan that list and use + * the first one matching a user id of the current key. */ + + /* FIXME: We need to get the list of user ids for the PKSK + * packet. That requires either a function to look it up + * again or we need to extend the key packet struct to link + * to the primary key which in turn could link to the user + * ids. Too much of a change right now. Let's take just + * one from the supplied list and hope that the caller + * passed a matching one. */ + build_sig_subpkt (sig, SIGSUBPKT_SIGNERS_UID, + opt.sender_list->d, strlen (opt.sender_list->d)); + } } } ----------------------------------------------------------------------- Summary of changes: common/asshelp.c | 47 ++------------ common/homedir.c | 50 +-------------- common/util.h | 3 +- dirmngr/certcache.c | 3 - dirmngr/crlcache.c | 2 +- dirmngr/dirmngr.c | 180 ++-------------------------------------------------- dirmngr/dirmngr.h | 2 - dirmngr/ocsp.c | 4 -- dirmngr/server.c | 48 ++------------ dirmngr/validate.c | 12 ++-- doc/dirmngr.texi | 27 +------- doc/gpg.texi | 9 +++ g10/gpg.c | 16 +++++ g10/options.h | 4 ++ g10/sign.c | 15 +++++ sm/server.c | 4 +- tools/gpgconf.c | 12 +--- 17 files changed, 73 insertions(+), 365 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 12:45:23 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 12:45:23 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-86-gd25db3c 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 d25db3c903e3b54ab04e87650ee5bfdb4844f310 (commit) from d83ba4897bf217d1045c58d1b99e52bd31c58812 (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 d25db3c903e3b54ab04e87650ee5bfdb4844f310 Author: Werner Koch Date: Thu Aug 18 12:41:55 2016 +0200 doc: Add comments on how to parse --list-colons output. -- GnuPG-bug-id: 2437 diff --git a/doc/DETAILS b/doc/DETAILS index 794026b..dc8ba1f 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -31,11 +31,18 @@ sub:r:1536:20:5CE086B5B5A18FF4:899817788:1025961788:::::esc: fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4: #+end_example +Note that new version of GnuPG or the use of certain options may add +new fields to the output. Parsers should not assume a limit on the +number of fields per line. Some fields are not yet used or only used +with certain record types; parsers should ignore fields they are not +aware of. + The double =--with-fingerprint= prints the fingerprint for the subkeys 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. + ** Description of the fields *** Field 1 - Type of record @@ -337,8 +344,8 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: Every line is prefixed with "[GNUPG:] ", followed by a keyword with the type of the status line and some arguments depending on the type - (maybe none); an application should always be prepared to see more - arguments in future versions. + (maybe none); an application should always be prepared to see new + keyworkds or more arguments in future versions. ** General status codes *** NEWSIG [] diff --git a/doc/gpg.texi b/doc/gpg.texi index b9a3ddc..52a50f5 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -348,9 +348,10 @@ if the keyid format has been set to "none". @item --list-packets @opindex list-packets -List only the sequence of packets. This is mainly useful for +List only the sequence of packets. This command is only useful for debugging. When used with option @option{--verbose} the actual MPI -values are dumped and not only their lengths. +values are dumped and not only their lengths. Note that the output of +this command may change with new releases. @item --card-edit ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 11 +++++++++-- doc/gpg.texi | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 15:00:22 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 18 Aug 2016 15:00:22 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-26-gc032ea2 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 c032ea2dcb4ac3ce970e62eae88fd24bec822f9c (commit) from 300755c1a10eec1f8bccd4182ed15c569473982c (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 c032ea2dcb4ac3ce970e62eae88fd24bec822f9c Author: Andre Heinecke Date: Thu Aug 18 14:55:27 2016 +0200 Qt: Add SetWindowPos based foreground hack for Win * qt/pinentrydialog.cpp(raiseWindow): Add another fallback for our foreground window hacks. -- Even if SetForegroundWindow or SetForegroundWindowEx do not report failures we are not always brought to front. So additionally afterwards we also set our Window Position to be absolutely in foreground and afterards remove that (so that a user may still but us in the background). This fixes the weird behavior that repeated pinentries for symmetric encryption open in background. diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index 009cd31..12f7718 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -79,16 +79,28 @@ void raiseWindow(QWidget *w) * this is enough on windows too*/ w->raise(); #ifdef Q_OS_WIN + HWND wid = (HWND)w->effectiveWinId(); /* In the meantime we do our own attention grabbing */ - if (!SetForegroundWindow((HWND)w->winId()) && - !SetForegroundWindowEx((HWND)w->winId())) { + if (!SetForegroundWindow(wid) && !SetForegroundWindowEx(wid)) { OutputDebugString("SetForegroundWindow (ex) failed"); /* Yet another fallback which will not work on some * versions and is not recommended by msdn */ - if (!ShowWindow((HWND)w->winId(), SW_SHOWNORMAL)) { + if (!ShowWindow(wid, SW_SHOWNORMAL)) { OutputDebugString("ShowWindow failed."); } } + /* Even if SetForgeoundWindow / SetForegroundWinowEx don't fail + * we sometimes are still not in the foreground. So we try yet + * another hack by using SetWindowPos */ + if (!SetWindowPos(wid, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)) { + OutputDebugString("SetWindowPos failed."); + } else { + /* Without moving back to NOTOPMOST we just stay on top. + * Even if the user changes focus. */ + SetWindowPos(wid, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } #endif } ----------------------------------------------------------------------- Summary of changes: qt/pinentrydialog.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 16:19:56 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 16:19:56 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-87-g1b55e86 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 1b55e864421f88b8c8088639682767076abbeab0 (commit) from d25db3c903e3b54ab04e87650ee5bfdb4844f310 (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 1b55e864421f88b8c8088639682767076abbeab0 Author: Werner Koch Date: Thu Aug 18 16:15:49 2016 +0200 gpg: Add import filter "drop-sig". * g10/import.c (import_drop_sig): New variable. (cleanup_import_globals): Release that. (parse_and_set_import_filter): Add filter "drop-sig". (filter_getval): Implement properties for drop-sig. (apply_drop_sig_filter): New. (import_one): Apply that filter. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 52a50f5..fbcaa15 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2254,6 +2254,11 @@ The available filter types are: This filter will keep a user id packet and its dependent packets in the keyblock if the expression evaluates to true. + @item drop-sig + This filter drops the selected key signatures on user ids. + Self-signatures are not consideres. + Currently only implemented for --import-filter. + @end table For the syntax of the expression see the chapter "FILTER EXPRESSIONS". @@ -2274,6 +2279,18 @@ The available properties are: @item primary Boolean indicating whether the user id is the primary one. (keep-uid) + @item sig_created + @itemx sig_created_d + The first is the timestamp a signature packet was created. The + second is the same but given as an ISO string, + e.g. "2016-08-17". (drop-sig) + + @item sig_algo + A number with the public key algorithm of a signature packet. (drop-sig) + + @item sig_digest_algo + A number with the digest algorithm of a signature packet. (drop-sig) + @end table @item --export-options @code{parameters} diff --git a/g10/import.c b/g10/import.c index 3c7edd7..f7cb923 100644 --- a/g10/import.c +++ b/g10/import.c @@ -76,13 +76,15 @@ struct import_stats_s #define NODE_FLAG_A 8 -/* A global variable to store the selector created from +/* Global variables to store selector created from * --import-filter keep-uid=EXPR. + * --import-filter drop-sig=EXPR. * * FIXME: We should put this into the CTRL object but that requires a * lot more changes right now. */ static recsel_expr_t import_keep_uid; +static recsel_expr_t import_drop_sig; @@ -122,6 +124,8 @@ cleanup_import_globals (void) { recsel_release (import_keep_uid); import_keep_uid = NULL; + recsel_release (import_drop_sig); + import_drop_sig = NULL; } @@ -198,6 +202,8 @@ parse_and_set_import_filter (const char *string) if (!strncmp (string, "keep-uid=", 9)) err = recsel_parse_expr (&import_keep_uid, string+9); + else if (!strncmp (string, "drop-sig=", 9)) + err = recsel_parse_expr (&import_drop_sig, string+9); else err = gpg_error (GPG_ERR_INV_NAME); @@ -1097,11 +1103,13 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock) } -/* Helper for apply_keep_uid_filter. */ +/* Helper for apply_keep_uid_filter and apply_drop_sig_filter. */ static const char * filter_getval (void *cookie, const char *propname) { + /* FIXME: Malloc our static buffers and access them via the cookie. */ kbnode_t node = cookie; + static char numbuf[20]; const char *result; if (node->pkt->pkttype == PKT_USER_ID) @@ -1115,19 +1123,47 @@ filter_getval (void *cookie, const char *propname) node->pkt->pkt.user_id->mbox = mailbox_from_userid (node->pkt->pkt.user_id->name); } - return node->pkt->pkt.user_id->mbox; + result = node->pkt->pkt.user_id->mbox; } else if (!strcmp (propname, "primary")) result = node->pkt->pkt.user_id->is_primary? "1":"0"; else result = NULL; } + else if (node->pkt->pkttype == PKT_SIGNATURE + || node->pkt->pkttype == PKT_ATTRIBUTE) + { + PKT_signature *sig = node->pkt->pkt.signature; + + if (!strcmp (propname, "sig_created")) + { + snprintf (numbuf, sizeof numbuf, "%lu", (ulong)sig->timestamp); + result = numbuf; + } + else if (!strcmp (propname, "sig_created_d")) + { + result = datestr_from_sig (sig); + } + else if (!strcmp (propname, "sig_algo")) + { + snprintf (numbuf, sizeof numbuf, "%d", sig->pubkey_algo); + result = numbuf; + } + else if (!strcmp (propname, "sig_digest_algo")) + { + snprintf (numbuf, sizeof numbuf, "%d", sig->digest_algo); + result = numbuf; + } + else + result = NULL; + } else result = NULL; return result; } + /* * Apply the keep-uid filter to the keyblock. The deleted nodes are * marked and thus the caller should call commit_kbnode afterwards. @@ -1166,6 +1202,49 @@ apply_keep_uid_filter (kbnode_t keyblock, recsel_expr_t selector) /* + * Apply the drop-sig filter to the keyblock. The deleted nodes are + * marked and thus the caller should call commit_kbnode afterwards. + * KEYBLOCK must not have any blocks marked as deleted. + */ +static void +apply_drop_sig_filter (kbnode_t keyblock, recsel_expr_t selector) +{ + kbnode_t node; + int active = 0; + u32 main_keyid[2]; + PKT_signature *sig; + + keyid_from_pk (keyblock->pkt->pkt.public_key, main_keyid); + + /* Loop over all signatures for user id and attribute packets which + * are not self signatures. */ + for (node = keyblock->next; node; node = node->next ) + { + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) + break; /* ready. */ + if (node->pkt->pkttype == PKT_USER_ID) + active = 1; + if (!active) + continue; + if (node->pkt->pkttype != PKT_SIGNATURE + && node->pkt->pkttype != PKT_ATTRIBUTE) + continue; + + sig = node->pkt->pkt.signature; + if (main_keyid[0] == sig->keyid[0] || main_keyid[1] == sig->keyid[1]) + continue; /* Skip self-signatures. */ + + if (IS_UID_SIG(sig) || IS_UID_REV(sig)) + { + if (recsel_select (selector, filter_getval, node)) + delete_kbnode (node); + } + } +} + + +/* * Try to import one keyblock. Return an error only in serious cases, * but never for an invalid keyblock. It uses log_error to increase * the internal errorcount, so that invalid input can be detected by @@ -1306,6 +1385,11 @@ import_one (ctrl_t ctrl, apply_keep_uid_filter (keyblock, import_keep_uid); commit_kbnode (&keyblock); } + if (import_drop_sig) + { + apply_drop_sig_filter (keyblock, import_drop_sig); + commit_kbnode (&keyblock); + } /* Show the key in the form it is merged or inserted. We skip this ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 17 ++++++++++++ g10/import.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 17:03:00 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 17:03:00 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.1.14-93-gc0f1dbd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via c0f1dbd54a98ab40bded2729b7fc2b4a47793cde (commit) via 74c641fa743934c0f3000864fd5a2945673256a6 (commit) via e33d073cb9b9117e607951e2ebef9a62e9c72d30 (commit) via 0a32153316855224acda268edb60b80d4e64b12f (commit) via ec88d7c8a9af864fad8ab5e0b9c4eb90ddcdd630 (commit) via 6f6bfbf175653faa5cf560a7174e81a599247e80 (commit) via 1b55e864421f88b8c8088639682767076abbeab0 (commit) via d25db3c903e3b54ab04e87650ee5bfdb4844f310 (commit) via d83ba4897bf217d1045c58d1b99e52bd31c58812 (commit) via de6e3217cde81df370926571e0fd65e468619803 (commit) via b5d63e81d5c472647decc7687cef91fee0378eb8 (commit) via f02ceb6c6e94c6fbfaeeafe728397be38107de4d (commit) via b781113cf1391926dedf8dc943624d3bb9726318 (commit) via c9a0bccc77c93c08d6980a1718dfaf238a559eb9 (commit) via 700920640211168ae1c97d0adef74ba8615d90bb (commit) via 37e932658cbd873ac96ff7e2067a97dffc2e0507 (commit) via b57f55321295846d47144bd6b39fbbcac0127421 (commit) via 3a75ff65fba24ea2d024bd8fef633ab7d8f7d520 (commit) via 61c2a1fa6d6cb345f9d81f4bdd3f8f8ddac1ea3e (commit) via 70b5d7c43a57a44dad60c2c700a263610748d8f4 (commit) via 0698324cde3e0cef7eeb6cfd1640c5eefdf13698 (commit) via 72fa314b71e4ce8780f59b16d32cabf5d4bd5451 (commit) via 14479e2515439c73e385f37e8c2b3fc517b038b9 (commit) via 9e6503b7ce019aa417099ded1dda87b68c33f912 (commit) via ed5c1b0b8a4790c4fb36a3129387f7c2ef5db302 (commit) via f2ea7e539c9a22081e3159dcbca84f57f30724ca (commit) via a6acf1f6b39c5a607f61f643a5d21309ba58685d (commit) via 5b59999ce0dd1650ebe47a74a30ded6af00eeed3 (commit) via a27410a251cd25ca96cd6743969c4db0a0fd553f (commit) via 194b1e979c7c547afd0dfea5b2496bdfa34b20f1 (commit) via d9240a3a4688c263632b4168ae2e04363bc91a3a (commit) via efe973dab7f69e2b1309446b2fbcd47ce0305399 (commit) via e13f1ea8fff3964dc3008432f5c0f26aaa2eaa35 (commit) via b2b21580b68f3a9069562f99675b389a0d044713 (commit) via f14795d57f6c81709e9225dd3c5dfd3495cf1b2b (commit) via e630f904993725c54ec63be00369589b7b7234d2 (commit) via 16feb1e0ea9b5d3966f22f4ae047335b9d1b60e1 (commit) via 49829c29e541546084950b8a153067db371d101a (commit) via ebf24e3b29766595204355d82f435a3e675bfbbc (commit) via 491d6fdabb3d95905cd96d905e1f965ce8ff07e1 (commit) via 5b614973fe2d4b5ef402a3057c31c3ef3042a483 (commit) via 591a8373a5d9567db9b1a1a48205e8a206c7b669 (commit) via 7dcad0d3503ac0d75e09efb16246dd78518986fc (commit) via 40d16029ed8b334c371fa7f24ac762d47302826e (commit) via 894789c3299dc47a8c1ccaaa7070382f0fae0262 (commit) via c9387e41db7520d176edd3d6613b85875bdeb32c (commit) via c8cc804f56bfefba46641f2c7078fcd67b494bae (commit) via 54a1ed20e203dcafeacbe21eb147efa08255dbf5 (commit) via 0c2a745a2bc21e8f439930f7c0e5d1521c2fd44c (commit) via db6f3eb926619dfe6ed2a9be197c51f9a1b6198c (commit) via 05cb30052cdf1d308ff7da901cfa5a809cd49479 (commit) via 3566544d04a4b81e5dd8a2883304673b2cc2f108 (commit) via 89234f7f3643bad2daddc94569f1d651ec5c835e (commit) via 573e0f36190346e0263bea3ae12a389f4f598d55 (commit) via 6f284e6ed63f514b15fe610f490ffcefc87a2164 (commit) via 993f36e23cf8c2216a40d3e51b922a1edd871e1b (commit) via e3358b246d9380008a4ba7c8f2fe03659901adaf (commit) via dc107b78509807db375d3a382eb3376cd2183357 (commit) via 436b28c23194fa77919967338d5a61a82d242153 (commit) via cd45cf782b91ff0f6b023913963e5258ffcbf464 (commit) via 48a2c93a1886589d1a0e2a4a2173e0e81311200b (commit) via 3a2421c94015432caa49e166bc5bf5c4f80ab7c7 (commit) via 40365b28c3fdf087fd58401f5a6f42f9d7d29d20 (commit) via c971ff0823d9a649b32fd9f169a12abc3095246e (commit) via 9e799b0e4f131126b80a5d3272c36d52b8ba1720 (commit) via 583a464c62ce8f7d70f5fdab2c7ea73ec3348d69 (commit) via b2572b0c386fd12ac6581fcce72f8d48cbfd27c7 (commit) via 046338b8494c036a5e717130d3eadce0291126fc (commit) via 66c0dab3c722c2766828515120775b106286334e (commit) via f17aecbcd98103fcd2ece537be96930f354de656 (commit) via b3610badf691178bbbf0831af9aa6b6658c1948a (commit) via 35132a8b119dbc3393ceb0d0874917905d1a6354 (commit) via fe40e9c53dc0710ff73e72d05ba8040874465b55 (commit) via 4ba11251aff578394000bf480f47160f0879c763 (commit) via 9ee23a715d5dad6bf568a2deb1c55bf15601cf51 (commit) via d9839c9d303a01dc1032a6de311e034fe14e81da (commit) via 45bb9a2a46e11bc13c6b39e7b4748b7de199018e (commit) via 8a6f8e1e397a2d676b211f2dbc6df4a80b67442d (commit) via 699c6c9f4b44441ab3db7f942df5b81f4cd88b06 (commit) via 7207b2fe45bcf884e029366a2677a570234bed2e (commit) via 1af2fd44f0a66fd0d94c224319db0b128d42a288 (commit) via 1598a4476466822e7e9c757ac471089d3db4b545 (commit) via 270f7f7b8b235cc93516566702e2a1d256605cca (commit) via d7a405de8325aa945ab791dcd3bc48272af33b86 (commit) via 0c1fd4e9884ed7c1edd1819762b9e8a77f606ed3 (commit) via f474249366e8e143c8e6eb7f7b1a74056e46fa1f (commit) via 7f4dd24b880323a5b772719dafae829c288303a8 (commit) via b7b37716b9d2cd1b71b5f7f0e4fb2c1a43eee90a (commit) via c49c43d7e4229fd9f1bc55e17fa32fdc334dbef6 (commit) via d21efa398874be4a15e8283c5fc382fb90f562fd (commit) via 12a887050a560c4cacaf95e4cdb0cc42d8b87aa1 (commit) via 1ab8d36b83845d8366eeca67767eb2f3e5259ca9 (commit) from 495fecaf7d850304142f3ca4daa140105579ccd2 (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: NEWS | 49 +- README | 13 +- agent/Makefile.am | 2 +- agent/agent.h | 1 + agent/cache.c | 13 +- agent/command-ssh.c | 289 ++----- agent/command.c | 13 +- agent/cvt-openpgp.c | 2 +- agent/gpg-agent.c | 21 +- agent/keyformat.txt | 2 +- agent/learncard.c | 6 +- agent/preset-passphrase.c | 10 +- agent/protect-tool.c | 9 +- common/Makefile.am | 7 +- common/asshelp.c | 47 +- common/exechelp-posix.c | 4 +- common/exectool.c | 72 +- common/fwddecl.h | 2 +- common/homedir.c | 50 +- common/i18n.c | 6 +- common/init.c | 8 + common/iobuf.c | 20 +- common/keyserver.h | 4 +- common/logging.c | 5 +- common/miscellaneous.c | 68 +- common/sexputil.c | 50 ++ common/simple-pwquery.c | 429 +++------- common/simple-pwquery.h | 43 - common/status.h | 1 + common/stringhelp.c | 79 +- common/stringhelp.h | 5 +- common/t-exectool.c | 223 ++++++ common/util.h | 11 +- common/{recsel.h => utilproto.h} | 25 +- common/w32-afunix.c | 148 ---- common/w32-afunix.h | 63 -- configure.ac | 4 +- dirmngr/Makefile.am | 4 +- dirmngr/cdblib.c | 2 +- dirmngr/certcache.c | 3 - dirmngr/crlcache.c | 4 +- dirmngr/dirmngr.c | 188 +---- dirmngr/dirmngr.h | 2 - dirmngr/http.c | 13 +- dirmngr/ldap-wrapper.c | 4 +- dirmngr/ocsp.c | 6 +- dirmngr/server.c | 48 +- dirmngr/t-http.c | 2 +- dirmngr/validate.c | 12 +- doc/DETAILS | 72 +- doc/TRANSLATE | 4 +- doc/announce-2.1.txt | 8 +- doc/dirmngr.texi | 41 +- doc/gpg-agent.texi | 10 +- doc/gpg.texi | 74 +- doc/gpgsm.texi | 4 +- doc/scdaemon.texi | 10 +- doc/tools.texi | 10 +- doc/whats-new-in-2.1.txt | 185 +++-- g10/encrypt.c | 7 +- g10/export.c | 2 +- g10/getkey.c | 2 +- g10/gpg.c | 69 +- g10/gpg.h | 2 + g10/gpgcompose.c | 2 +- g10/gpgv.c | 25 +- g10/import.c | 109 ++- g10/keydb.h | 6 +- g10/keyedit.c | 2 +- g10/keylist.c | 56 +- g10/keyring.c | 18 +- g10/mainproc.c | 38 +- g10/options.h | 17 +- g10/packet.h | 3 +- g10/parse-packet.c | 5 +- g10/passphrase.c | 233 +----- g10/pkclist.c | 4 + g10/progress.c | 22 +- g10/sig-check.c | 4 +- g10/sign.c | 17 +- g10/tdbio.c | 4 +- g10/test-stubs.c | 18 +- g10/tofu.c | 873 ++++----------------- g10/tofu.h | 4 +- g13/Makefile.am | 2 +- g13/backend.c | 18 + g13/backend.h | 1 + g13/be-dmcrypt.c | 17 + g13/be-dmcrypt.h | 1 + g13/call-syshelp.c | 143 ++++ g13/call-syshelp.h | 6 + g13/g13-syshelp.c | 9 +- g13/g13-syshelp.h | 1 + g13/g13.c | 35 +- g13/keyblob.c | 22 - g13/keyblob.h | 3 - g13/mount.c | 115 ++- g13/server.c | 27 + g13/server.h | 4 + g13/sh-cmd.c | 161 +++- g13/sh-dmcrypt.c | 93 +++ g13/suspend.c | 1 + kbx/kbxutil.c | 10 +- kbx/keybox-update.c | 38 +- kbx/keybox-util.c | 92 ++- kbx/keybox.h | 3 +- m4/ksba.m4 | 6 +- m4/libgcrypt.m4 | 6 +- m4/ntbtls.m4 | 8 +- po/POTFILES.in | 2 +- po/ca.po | 162 ++-- po/cs.po | 149 ++-- po/da.po | 154 ++-- po/de.po | 154 ++-- po/el.po | 142 ++-- po/eo.po | 138 ++-- po/es.po | 154 ++-- po/et.po | 140 ++-- po/fi.po | 138 ++-- po/fr.po | 154 ++-- po/gl.po | 140 ++-- po/hu.po | 146 ++-- po/id.po | 140 ++-- po/it.po | 140 ++-- po/ja.po | 176 ++--- po/nb.po | 298 ++++--- po/pl.po | 154 ++-- po/pt.po | 142 ++-- po/ro.po | 142 ++-- po/ru.po | 171 ++-- po/sk.po | 140 ++-- po/sv.po | 154 ++-- po/tr.po | 154 ++-- po/uk.po | 152 ++-- po/zh_CN.po | 133 ++-- po/zh_TW.po | 148 ++-- scd/app-p15.c | 4 +- scd/app.c | 4 + scd/ccid-driver.c | 2 +- scd/command.c | 96 +-- scd/scdaemon.c | 12 +- sm/gpgsm.c | 11 +- sm/keylist.c | 1 - sm/server.c | 6 +- sm/sign.c | 2 +- tests/gpgscm/Makefile.am | 2 +- tests/gpgscm/ffi-private.h | 2 +- tests/gpgscm/ffi.c | 29 +- tests/gpgscm/init.scm | 4 +- tests/gpgscm/lib.scm | 3 +- tests/gpgscm/main.c | 2 +- tests/gpgscm/scheme.c | 2 +- tests/gpgscm/tests.scm | 42 +- tests/migrations/Makefile.am | 9 +- tests/migrations/common.scm | 13 + tests/migrations/extended-pkf.scm | 3 + tests/migrations/from-classic.scm | 3 + .../4gb-packet.scm => migrations/issue2276.scm} | 17 +- tests/migrations/issue2276.tar.asc | 326 ++++++++ tests/openpgp/Makefile.am | 46 +- tests/openpgp/README | 2 +- tests/openpgp/armor.scm | 2 +- tests/openpgp/armor.test | 2 +- tests/openpgp/defs.scm | 18 +- tests/openpgp/fake-pinentry.c | 6 +- tests/openpgp/forged-keyring.gpg | Bin 0 -> 970 bytes tests/openpgp/gpg-agent.conf.tmpl | 1 + tests/openpgp/gpgtar.scm | 4 +- tests/openpgp/gpgv-forged-keyring.scm | 67 ++ tests/openpgp/{4gb-packet.scm => issue2015.scm} | 14 +- tests/openpgp/{4gb-packet.scm => issue2346.scm} | 18 +- tests/openpgp/{genkey1024.scm => issue2417.scm} | 49 +- .../openpgp/{armsignencrypt.scm => issue2419.scm} | 16 +- tests/openpgp/run-tests.scm | 14 +- tests/openpgp/samplekeys/issue2346.gpg | 57 ++ tests/openpgp/samplekeys/ssh-dsa.key | 12 + tests/openpgp/samplekeys/ssh-ecdsa.key | 5 + tests/openpgp/samplekeys/ssh-ed25519.key | 7 + tests/openpgp/samplekeys/ssh-rsa.key | 27 + tests/openpgp/samplemsgs/issue2419.asc | 7 + tests/openpgp/setup.scm | 8 - tests/openpgp/ssh.scm | 66 ++ tests/openpgp/tofu.scm | 2 +- tools/Makefile.am | 19 +- tools/gpg-check-pattern.c | 9 +- tools/gpg-connect-agent.c | 2 +- tools/gpg-wks-client.c | 5 +- tools/gpg-wks-server.c | 74 +- tools/gpgconf-comp.c | 4 +- tools/gpgconf.c | 22 +- tools/gpgconf.h | 1 + tools/gpgsplit.c | 2 +- tools/gpgtar.c | 2 +- tools/gpgtar.h | 2 +- tools/symcryptrun.c | 11 +- 195 files changed, 5098 insertions(+), 4991 deletions(-) create mode 100644 common/t-exectool.c copy common/{recsel.h => utilproto.h} (65%) delete mode 100644 common/w32-afunix.c delete mode 100644 common/w32-afunix.h copy tests/{openpgp/4gb-packet.scm => migrations/issue2276.scm} (60%) create mode 100644 tests/migrations/issue2276.tar.asc create mode 100644 tests/openpgp/forged-keyring.gpg create mode 100755 tests/openpgp/gpgv-forged-keyring.scm copy tests/openpgp/{4gb-packet.scm => issue2015.scm} (65%) copy tests/openpgp/{4gb-packet.scm => issue2346.scm} (58%) copy tests/openpgp/{genkey1024.scm => issue2417.scm} (52%) copy tests/openpgp/{armsignencrypt.scm => issue2419.scm} (72%) create mode 100644 tests/openpgp/samplekeys/issue2346.gpg create mode 100644 tests/openpgp/samplekeys/ssh-dsa.key create mode 100644 tests/openpgp/samplekeys/ssh-ecdsa.key create mode 100644 tests/openpgp/samplekeys/ssh-ed25519.key create mode 100644 tests/openpgp/samplekeys/ssh-rsa.key create mode 100644 tests/openpgp/samplemsgs/issue2419.asc create mode 100755 tests/openpgp/ssh.scm hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 17:10:09 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 18 Aug 2016 17:10:09 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-290-g9cf983b 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 9cf983b0199950c8f8cccee2cb8e45aafcba9fd1 (commit) from 64194b0f8df1afe6135cd119fd3216fc8db68033 (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 9cf983b0199950c8f8cccee2cb8e45aafcba9fd1 Author: Andre Heinecke Date: Thu Aug 18 16:56:58 2016 +0200 core: Fail loudly in case w32 spawner not found * src/w32-io.c (_gpgme_io_spawn): Show a message box in case gpgme-w32spawn.exe not found. -- Otherwise every engine call will just fail with unsupported protocol. Even in the debug output the problem was not made clear because CreateProcess will fail with error code 87 (Invalid Parameter) because spawnhelper is NULL. The helpful error message for ERROR_INVALID_PARAMETER would have been: "is 'NULL' correctly installed" As GpgME basically becomes useless on Windows without the spawnhelper we want to fail very loud in that case. diff --git a/src/w32-io.c b/src/w32-io.c index 8e7abd3..9aaaeeb 100644 --- a/src/w32-io.c +++ b/src/w32-io.c @@ -50,6 +50,7 @@ #include "sema.h" #include "priv-io.h" #include "debug.h" +#include "sys-util.h" /* FIXME: Optimize. */ @@ -1605,6 +1606,31 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags, cr_flags |= DETACHED_PROCESS; cr_flags |= GetPriorityClass (GetCurrentProcess ()); spawnhelper = _gpgme_get_w32spawn_path (); + if (!spawnhelper) + { + /* This is a common mistake for new users of gpgme not to include + gpgme-w32spawn.exe with their binary. So we want to make + this transparent to developers. If users have somehow messed + up their installation this should also be properly communicated + as otherwise calls to gnupg will result in unsupported protocol + errors that do not explain a lot. */ + char *msg; + gpgrt_asprintf (&msg, "gpgme-w32spawn.exe was not found in the " + "detected installation directory of GpgME" + "\n\t\"%s\"\n\n" + "Crypto operations will not work.\n\n" + "If you see this it indicates a problem " + "with your installation.\n" + "Please report the problem to your " + "distributor of GpgME.\n\n" + "Developers Note: The install dir can be " + "manually set with: gpgme_set_global_flag", + _gpgme_get_inst_dir ()); + MessageBoxA (NULL, msg, "GpgME not installed correctly", MB_OK); + free (msg); + gpg_err_set_errno (EIO); + return TRACE_SYSRES (-1); + } if (!CreateProcessA (spawnhelper, arg_string, &sec_attr, /* process security attributes */ ----------------------------------------------------------------------- Summary of changes: src/w32-io.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 17:22:22 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 18 Aug 2016 17:22:22 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-291-g30f1562 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 30f156280f18500ee522db58aecd40711c8af685 (commit) from 9cf983b0199950c8f8cccee2cb8e45aafcba9fd1 (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 30f156280f18500ee522db58aecd40711c8af685 Author: Andre Heinecke Date: Thu Aug 18 17:14:36 2016 +0200 core: Remove (now) useless diagnostic * src/w32-io.c(_gpgme_io_spawn): Remove spawnhelper not found diagnostic. -- When spawnhelper is not found the error is now catched before the CreateProcess call so the added diagnostic in bb2d11c (which was not helpful because the value for spawnhelper would be NULL in that case) is now no longer needed. diff --git a/src/w32-io.c b/src/w32-io.c index 9aaaeeb..3a69541 100644 --- a/src/w32-io.c +++ b/src/w32-io.c @@ -1644,8 +1644,6 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags, { int lasterr = (int)GetLastError (); TRACE_LOG1 ("CreateProcess failed: ec=%d", lasterr); - if (lasterr == ERROR_INVALID_PARAMETER) - TRACE_LOG1 ("(is '%s' correctly installed?)", spawnhelper); free (arg_string); close (tmp_fd); DeleteFileA (tmp_name); ----------------------------------------------------------------------- Summary of changes: src/w32-io.c | 2 -- 1 file changed, 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 18:26:09 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 18:26:09 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.1.14-95-gd4bd974 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via d4bd9743cfb888ee89d2c42eb681788489f52d47 (commit) via 6bee88dd067e03e7767ceacf6a849d9ba38cc11d (commit) from c0f1dbd54a98ab40bded2729b7fc2b4a47793cde (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 d4bd9743cfb888ee89d2c42eb681788489f52d47 Author: Werner Koch Date: Thu Aug 18 18:23:28 2016 +0200 Post release updates. -- diff --git a/NEWS b/NEWS index cbe6645..995f583 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.1.16 (unreleased) +------------------------------------------------- + + Noteworthy changes in version 2.1.15 (2016-08-18) ------------------------------------------------- diff --git a/configure.ac b/configure.ac index 95a8f17..bd24ea4 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ min_automake_version="1.14" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [1]) -m4_define([mym4_micro], [15]) +m4_define([mym4_micro], [16]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release commit 6bee88dd067e03e7767ceacf6a849d9ba38cc11d Author: Werner Koch Date: Thu Aug 18 17:14:48 2016 +0200 Release 2.1.15 ----------------------------------------------------------------------- Summary of changes: NEWS | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 18:26:39 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 18:26:39 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.14-95-gd4bd974 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 d4bd9743cfb888ee89d2c42eb681788489f52d47 (commit) via 6bee88dd067e03e7767ceacf6a849d9ba38cc11d (commit) from c0f1dbd54a98ab40bded2729b7fc2b4a47793cde (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: NEWS | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 18:39:21 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 18:39:21 +0200 Subject: [git] gnupg-doc - branch, master, updated. 353dac28eb3a807e15504ddaec8cc7a69b2993ab 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 353dac28eb3a807e15504ddaec8cc7a69b2993ab (commit) from 502288add2508d8b86bda0f547bc47e323b8221d (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 353dac28eb3a807e15504ddaec8cc7a69b2993ab Author: Werner Koch Date: Thu Aug 18 18:35:52 2016 +0200 swdb: GnuPG 2.1.15 released. diff --git a/web/swdb.mac b/web/swdb.mac index e65bffe..3ac250a 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -21,17 +21,17 @@ # # GnuPG-2.1 # -#+macro: gnupg21_ver 2.1.14 -#+macro: gnupg21_date 2016-07-14 -#+macro: gnupg21_size 5572k -#+macro: gnupg21_sha1 bc7609a3a0daf0ed0efb22f77b43e82f28e20e34 -#+macro: gnupg21_sha2 9450dee9693b6a12bf0c374dae77b66c30f69ff8f35fc9266ab8dd76998eba42 -# -#+macro: gnupg21_w32_ver 2.1.14_20160714 -#+macro: gnupg21_w32_date 2016-07-14 -#+macro: gnupg21_w32_size 3576k -#+macro: gnupg21_w32_sha1 8871e1b596a208403c7240498fa3d83c33ced4b2 -#+macro: gnupg21_w32_sha2 43ac527c85cc2651d4c96fa7c104caadf303ae88dff3cf8ec27f98ef76fa2d89 +#+macro: gnupg21_ver 2.1.15 +#+macro: gnupg21_date 2016-08-18 +#+macro: gnupg21_size 5589k +#+macro: gnupg21_sha1 908c86dac8e9a1fbf47e1605e570b11391b04ece +#+macro: gnupg21_sha2 c28c1a208f1b8ad63bdb6b88d252f6734ff4d33de6b54e38494b11d49e00ffdd +# +#+macro: gnupg21_w32_ver 2.1.15_20160818 +#+macro: gnupg21_w32_date 2016-08-18 +#+macro: gnupg21_w32_size 3566k +#+macro: gnupg21_w32_sha1 c13fdb4daa2a2c715d86365e6ab6c3b70506340e +#+macro: gnupg21_w32_sha2 4802c8c08fc67964235eddacfd45553363bac0a081e1f38a76008e2bad9617a2 ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 19:31:49 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 19:31:49 +0200 Subject: [git] gnupg-doc - branch, master, updated. 7aff498448d528f1e15504e17418e1f823fc65e5 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 7aff498448d528f1e15504e17418e1f823fc65e5 (commit) from 353dac28eb3a807e15504ddaec8cc7a69b2993ab (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 7aff498448d528f1e15504e17418e1f823fc65e5 Author: Werner Koch Date: Thu Aug 18 19:29:20 2016 +0200 web: Release 2.1.15. Tweak description of modern,stable,classic. diff --git a/web/index.org b/web/index.org index d183616..4580678 100644 --- a/web/index.org +++ b/web/index.org @@ -27,10 +27,11 @@ GnuPG comes in three flavours: - {{{gnupg21_ver}}} is the /modern/ version with support for [[https://en.wikipedia.org/wiki/Elliptic_curve_cryptography][ECC]] and many other new features, - - {{{gnupg_ver}}} is the /stable/ version which is currently mostly - used. + - {{{gnupg_ver}}} is the /stable/ version from the currently mostly + used branch. This branch will reach end-of-life on 2017-12-31, - - and {{{gnupg1_ver}}} is the /classic/ portable version. + - and {{{gnupg1_ver}}} is the /classic/ portable version for use on + very old platforms or to decrypt data created with PGP-2 keys. Project [[https://www.gpg4win.org][Gpg4win]] provides a Windows version of GnuPG /stable/. It is nicely integrated into an installer and features several frontends as @@ -79,6 +80,11 @@ The latest release news:\\ # 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 # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** GnuPG 2.1.15 released (2016-08-18) + +A new version of the /modern/ branch of GnuPG has been released. +Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000396.html][announcement mail]] for details. + ** Security fixes for Libgcrypt and GnuPG 1.4 :important: A bug in the random number generator of Libgcrypt and in GnuPG 1.4 has ----------------------------------------------------------------------- Summary of changes: web/index.org | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 18 19:36:43 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Aug 2016 19:36:43 +0200 Subject: [git] gnupg-doc - branch, master, updated. a8ace532bdab6870e2b3ca8203e0dbd830ebad6a 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 a8ace532bdab6870e2b3ca8203e0dbd830ebad6a (commit) from 7aff498448d528f1e15504e17418e1f823fc65e5 (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 a8ace532bdab6870e2b3ca8203e0dbd830ebad6a Author: Werner Koch Date: Thu Aug 18 19:34:20 2016 +0200 web: Add a date to yesterdays news. diff --git a/web/index.org b/web/index.org index 4580678..0906554 100644 --- a/web/index.org +++ b/web/index.org @@ -85,7 +85,7 @@ The latest release news:\\ A new version of the /modern/ branch of GnuPG has been released. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000396.html][announcement mail]] for details. -** Security fixes for Libgcrypt and GnuPG 1.4 :important: +** Security fixes for Libgcrypt and GnuPG 1.4 (2016-08-17) :important: A bug in the random number generator of Libgcrypt and in GnuPG 1.4 has been found. Updating the software is highly suggested. Please read ----------------------------------------------------------------------- Summary of changes: web/index.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Aug 19 09:09:27 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 19 Aug 2016 09:09:27 +0200 Subject: [git] gnupg-doc - branch, master, updated. a3200d8cf1cabc9d013068d3cfe210e5eddceef6 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 a3200d8cf1cabc9d013068d3cfe210e5eddceef6 (commit) from a8ace532bdab6870e2b3ca8203e0dbd830ebad6a (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 a3200d8cf1cabc9d013068d3cfe210e5eddceef6 Author: Werner Koch Date: Fri Aug 19 09:07:03 2016 +0200 git.gnupg.org: Cleanup order of gnupg branches on the index page diff --git a/misc/git.gnupg.org/index.html b/misc/git.gnupg.org/index.html index af532e4..831c3d8 100644 --- a/misc/git.gnupg.org/index.html +++ b/misc/git.gnupg.org/index.html @@ -52,7 +52,7 @@ Links

@@ -77,9 +77,9 @@

The GnuPG Repositories

-Use our GIT +Use our GIT Viewer to browse the GIT -repository. Activity reports +repository. Activity reports are also available.

@@ -88,29 +88,29 @@ Here is a list of shortcuts to often used repositories:

----------------------------------------------------------------------- Summary of changes: misc/git.gnupg.org/index.html | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Aug 21 15:59:01 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 21 Aug 2016 15:59:01 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-292-g3e60788 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 3e60788810f93cfcd7f08e5882aff32ed7b6f831 (commit) from 30f156280f18500ee522db58aecd40711c8af685 (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 3e60788810f93cfcd7f08e5882aff32ed7b6f831 Author: Werner Koch Date: Sun Aug 21 15:49:03 2016 +0200 core: New commands --lang and --have-lang for gpgme-config * configure.ac (GPGME_CONFIG_AVAIL_LANG): New ac_subst. * src/gpgme-config.in (avail_lang): Add commands --lang and --have-lang. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 9eb55bb..744b52a 100644 --- a/configure.ac +++ b/configure.ac @@ -717,10 +717,12 @@ AH_BOTTOM([ GPGME_CONFIG_LIBS="-lgpgme" GPGME_CONFIG_CFLAGS="" GPGME_CONFIG_HOST="$host" +GPGME_CONFIG_AVAIL_LANG="$enabled_languages" AC_SUBST(GPGME_CONFIG_API_VERSION) AC_SUBST(GPGME_CONFIG_LIBS) AC_SUBST(GPGME_CONFIG_CFLAGS) AC_SUBST(GPGME_CONFIG_HOST) +AC_SUBST(GPGME_CONFIG_AVAIL_LANG) # Frob'da Variables LTLIBOBJS=`echo "$LIB@&t at OBJS" | diff --git a/doc/gpgme.texi b/doc/gpgme.texi index ac0fffa..e8a735a 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -450,6 +450,19 @@ any other option to select the thread package you want to link with. Supported thread packages are @option{--thread=pth} and @option{--thread=pthread}. +If you need to detect the installed language bindings you can use list +them using: + + at example +gpgme-config --print-lang + at end example + +or test for the availability using + + at example +gpgme-config --have-lang=python && echo 'Bindings for Pythons available' + at end example + @node Largefile Support (LFS) @section Largefile Support (LFS) diff --git a/src/gpgme-config.in b/src/gpgme-config.in index 4be1e08..0d9fda2 100644 --- a/src/gpgme-config.in +++ b/src/gpgme-config.in @@ -36,6 +36,8 @@ thread_modules="" libs_pthread="-lpthread" cflags_pthread="" +avail_lang='c @GPGME_CONFIG_AVAIL_LANG@' + # Configure glib. libs_glib="@GLIB_LIBS@" cflags_glib="@GLIB_CFLAGS@" @@ -48,16 +50,16 @@ usage() cat <&2 fi ;; + --print-lang) + output="$avail_lang" + ;; + --have-lang=*) + for lang in $avail_lang; do + if test x"$lang" = x"$optarg"; then + exit 0 + fi + done + exit 1 + ;; --get-gpg) + # Deprecated output="$output @GPG@" ;; --get-gpgsm) + # Deprecated output="$output @GPGSM@" ;; *) ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 ++ doc/gpgme.texi | 13 +++++++++++++ src/gpgme-config.in | 35 +++++++++++++++++++++++++---------- 3 files changed, 40 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 11:14:00 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 11:14:00 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-2-g62f3e00 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 62f3e0027724b23c0de5be6d1e66cfdeef7e7bc9 (commit) from d4bd9743cfb888ee89d2c42eb681788489f52d47 (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 62f3e0027724b23c0de5be6d1e66cfdeef7e7bc9 Author: Werner Koch Date: Mon Aug 22 11:09:42 2016 +0200 common: Remove unused vars in simple-pwquery. * common/simple-pwquery.c (agent_send_option): Remove unused vars. (simple_query): Ditto. (agent_open): Ditto. Return RC on error. (simple_pwquery): Remove unused vars. Remove shadowing of 'p'. Signed-off-by: Werner Koch diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 240451b..bc555df 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -101,10 +101,7 @@ static int agent_send_option (assuan_context_t ctx, const char *name, const char *value) { int err; - char buf[200]; - int nread; char *line; - int i; line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2); if (!line) @@ -241,12 +238,7 @@ static int agent_open (assuan_context_t *ctx) { int rc; - int fd; - char *infostr, *p; - struct sockaddr_un client_addr; - size_t len; - char line[200]; - int nread; + char *infostr; infostr = default_gpg_agent_info; if ( !infostr || !*infostr ) @@ -285,6 +277,7 @@ agent_open (assuan_context_t *ctx) errout: assuan_release (*ctx); *ctx = NULL; + return rc; } @@ -373,13 +366,14 @@ simple_pwquery (const char *cacheid, int opt_check, int *errorcode) { + int rc; assuan_context_t ctx; membuf_t data; - int nread; char *result = NULL; char *pw = NULL; char *p; - int rc, i; + size_t n; + rc = agent_open (&ctx); if (rc) @@ -437,9 +431,6 @@ simple_pwquery (const char *cacheid, if (rc) { - void *p; - size_t n; - p = get_membuf (&data, &n); if (p) wipememory (p, n); @@ -490,8 +481,6 @@ int simple_query (const char *query) { assuan_context_t ctx; - char response[500]; - int have = 0; int rc; rc = agent_open (&ctx); ----------------------------------------------------------------------- Summary of changes: common/simple-pwquery.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 11:14:30 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 11:14:30 +0200 Subject: [git] KSBA - branch, master, updated. libksba-1.3.4-9-g89d8983 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 "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 89d898346b75337ec2546c672ea720c5c956b53a (commit) from eb7833b8720cd0831c78d42e993ca878cecf27bc (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 89d898346b75337ec2546c672ea720c5c956b53a Author: Werner Koch Date: Mon Aug 22 10:47:59 2016 +0200 Limit allocation in the BER decoder to 16 MiB. * src/ber-decoder.c (MAX_IMAGE_LENGTH): New. (decoder_next): Limit allcoation to MAX_IMAGE_LENGTH. (_ksba_ber_decoder_dump, _ksba_ber_decoder_decode): Ditto. -- We allocate the image used to allocate BER encoded data from the provided length in the object. However, this length may be given arbitrary and we would thus try to allocate huge amounts of memory (and zero them out since commit 2a9fc56) unless the user has set an appropriate ulimit. This is not desirable and thus we better bail out early if a strange (ie. very large object is seen). That whole table driven parser is a mess. Reported-by: Pascal Cuoq Signed-off-by: Werner Koch diff --git a/src/ber-decoder.c b/src/ber-decoder.c index dde73fd..20a91b1 100644 --- a/src/ber-decoder.c +++ b/src/ber-decoder.c @@ -42,6 +42,11 @@ #include "ber-help.h" +/* The maximum length we allow for an image, that is for a BER encoded + * object. */ +#define MAX_IMAGE_LENGTH (16 * 1024 * 1024) + + struct decoder_state_item_s { AsnNode node; int went_up; @@ -867,6 +872,8 @@ decoder_next (BerDecoder d) d->image.length = ti.length + 100; if (d->image.length < ti.length) return gpg_error (GPG_ERR_BAD_BER); + if (d->image.length > MAX_IMAGE_LENGTH) + return gpg_error (GPG_ERR_TOO_LARGE); d->image.buf = xtrycalloc (1, d->image.length); if (!d->image.buf) return gpg_error (GPG_ERR_ENOMEM); @@ -1111,9 +1118,12 @@ _ksba_ber_decoder_dump (BerDecoder d, FILE *fp) if (!buf || buflen < d->val.length) { xfree (buf); + buf = NULL; buflen = d->val.length + 100; if (buflen < d->val.length) err = gpg_error (GPG_ERR_BAD_BER); /* Overflow */ + else if (buflen > MAX_IMAGE_LENGTH) + err = gpg_error (GPG_ERR_TOO_LARGE); else { buf = xtrymalloc (buflen); @@ -1247,9 +1257,12 @@ _ksba_ber_decoder_decode (BerDecoder d, const char *start_name, if (!buf || buflen < d->val.length) { xfree (buf); + buf = NULL; buflen = d->val.length + 100; if (buflen < d->val.length) err = gpg_error (GPG_ERR_BAD_BER); + else if (buflen > MAX_IMAGE_LENGTH) + err = gpg_error (GPG_ERR_TOO_LARGE); else { buf = xtrymalloc (buflen); ----------------------------------------------------------------------- Summary of changes: src/ber-decoder.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 11:50:44 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 11:50:44 +0200 Subject: [git] KSBA - branch, master, updated. libksba-1.3.4-10-g68fba3d 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 "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 68fba3d8d7757b7f7ed75fdebd2b91299943503b (commit) from 89d898346b75337ec2546c672ea720c5c956b53a (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 68fba3d8d7757b7f7ed75fdebd2b91299943503b Author: Werner Koch Date: Mon Aug 22 11:47:28 2016 +0200 Use size_t for the result of fread. * src/reader.c (ksba_reader_read): Make 'n' and size_t. -- GnuPG-bug-id: 2415 Signed-off-by: Werner Koch diff --git a/src/reader.c b/src/reader.c index 0f8bad5..c59978d 100644 --- a/src/reader.c +++ b/src/reader.c @@ -366,7 +366,7 @@ ksba_reader_read (ksba_reader_t r, char *buffer, size_t length, size_t *nread) } else if (r->type == READER_TYPE_FILE) { - int n; + size_t n; if (r->eof) return gpg_error (GPG_ERR_EOF); @@ -378,7 +378,7 @@ ksba_reader_read (ksba_reader_t r, char *buffer, size_t length, size_t *nread) } n = fread (buffer, 1, length, r->u.file); - if (n > 0) + if (n) { r->nread += n; *nread = n; @@ -388,9 +388,9 @@ ksba_reader_read (ksba_reader_t r, char *buffer, size_t length, size_t *nread) if (n < length) { if (ferror(r->u.file)) - r->error = errno; + r->error = errno; r->eof = 1; - if (n <= 0) + if (!n) return gpg_error (GPG_ERR_EOF); } } ----------------------------------------------------------------------- Summary of changes: src/reader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 12:03:02 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 12:03:02 +0200 Subject: [git] KSBA - branch, master, updated. libksba-1.3.4-12-g861cd1e 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 "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 861cd1eb38453a39226c7e206486078e9ac4a12c (commit) via 25cc42cf61a56e01f1bd72883e452f691dda8309 (commit) from 68fba3d8d7757b7f7ed75fdebd2b91299943503b (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 861cd1eb38453a39226c7e206486078e9ac4a12c Author: Werner Koch Date: Mon Aug 22 11:59:47 2016 +0200 Post release updates -- diff --git a/NEWS b/NEWS index 22aeead..24192bc 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.3.6 (unreleased) [C19/A11/R-] +------------------------------------------------ + + Noteworthy changes in version 1.3.5 (2016-08-22) [C19/A11/R6] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index e5e8764..44da1cb 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.14" m4_define([mym4_package],[libksba]) m4_define([mym4_major], [1]) m4_define([mym4_minor], [3]) -m4_define([mym4_micro], [5]) +m4_define([mym4_micro], [6]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a commit 25cc42cf61a56e01f1bd72883e452f691dda8309 Author: Werner Koch Date: Mon Aug 22 11:54:04 2016 +0200 Release 1.3.5 * configure.ac: Set LT version to C19/A/11/R6. diff --git a/NEWS b/NEWS index 9dca760..22aeead 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,18 @@ -Noteworthy changes in version 1.3.5 (unreleased) [C19/A11/R_] +Noteworthy changes in version 1.3.5 (2016-08-22) [C19/A11/R6] ------------------------------------------------ + * Limit the allowed size of complex ASN.1 objects (e.g. certificates) + to 16MiB. -Noteworthy changes in version 1.3.4 (2016-05-03) [C19/A11/R4] + * Avoid read access to unitialized memory. + + * Improve detection of invalid RDNs. + + * Encode the OCSP nonce value as an octet string as described by + RFC-6960. + + +Noteworthy changes in version 1.3.4 (2016-05-03) [C19/A11/R5] ------------------------------------------------ * Fixed two OOB read access bugs which could be used to force a DoS. diff --git a/configure.ac b/configure.ac index d678ce4..e5e8764 100644 --- a/configure.ac +++ b/configure.ac @@ -52,7 +52,7 @@ AC_INIT([mym4_package],[mym4_version], [http://bugs.gnupg.org]) # Please remember to document interface changes in the NEWS file. LIBKSBA_LT_CURRENT=19 LIBKSBA_LT_AGE=11 -LIBKSBA_LT_REVISION=5 +LIBKSBA_LT_REVISION=6 #------------------- # If the API is changed in an incompatible way: increment the next counter. KSBA_CONFIG_API_VERSION=1 ----------------------------------------------------------------------- Summary of changes: NEWS | 18 ++++++++++++++++-- configure.ac | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 15:51:46 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 22 Aug 2016 15:51:46 +0200 Subject: [git] GpgOL - branch, nomapi, updated. gpgol-1.4.0-21-g553db6b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, nomapi has been updated via 553db6ba3cfaca7275669abbc5024037363630be (commit) via 7f9f7bf99de356d794df06852bc12faf9c6e99ba (commit) via 3b27162dcb06c99aa62ab12403312854871e2214 (commit) via 87d57374bbe502b121d68874e9e807e89a20f358 (commit) from c1398da89a56f4c2cad743af8eb687d33e7f3246 (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 553db6ba3cfaca7275669abbc5024037363630be Author: Andre Heinecke Date: Mon Aug 22 15:40:37 2016 +0200 Add GPGME based async decryption * src/Makefile.am (gpgol_SOURCES): Add Mimedataprovider. * src/mail.cpp (Mail::m_moss_position): Store moss pos. (Mail::is_mail_valid): Helper to check for orphaned mail pointer. (Mail::pre_process_message): Store moss position. (get_cipherstream): Use stored moss position. (use_body): Removed. Always use MOSS. (do_parsing): Helper to run in different thread. (Mail::decrypt_verify): Insert placehoder, create parser, start parser thread. (Mail::parsing_done): Helper to insert plaintext in UI Thread. (Mail::revert_all_mails): Fix typo. (Mail::wipe_all_mails): Init err. (Mail::close_inspector): Helper to close current inspector with discard changes. * src/mail.h: Update accordingly. * src/mailparser.cpp (MailParser::MailParser): Use MimeDataProvider. (operation_for_type): Helper to figure out type of work and protocol. (MailParser::parse): Enable a fist version of decrypt. * src/mailparser.h: Update accordingly. * src/main.c (DllMain): Set w32-inst-dir for GpgME. * src/mimedataprovider.cpp: New. Copy stream into GpgME Data. * src/mimedataprovider.h: New. * src/util.h (log_mime_parser): New helper for logging. * src/windowmessages.cpp (gpgol_window_proc): Handle parsing done signal. * src/windowmessages.h (PARSING_DONE): New. * src/attachment.cpp: Implement DataProvider interface. * src/attachment.h: Update accordingly. -- The idea is that DataProvider classes will take and recieve Data from GpgOL, copy it into internal buffers (to avoid working with the OOM from a background thread) and then provide the data as needed to GpgOL. On Read they shall parse the MIME e.g. into a signature part, and on Write they shall deliver useful objects (e.g. attachments) for Outlook to work with. The Close / Wipe changes are a bit unrelated as they were created for experiments to avoid "save your changes" message boxes. diff --git a/src/Makefile.am b/src/Makefile.am index 65e4f7b..fd91691 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,7 +88,8 @@ gpgol_SOURCES = \ gmime-table-private.h \ exechelp.c exechelp.h \ addin-options.cpp addin-options.h \ - mailparser.cpp mailparser.h + mailparser.cpp mailparser.h \ + mimedataprovider.cpp mimedataprovider.h #treeview_SOURCES = treeview.c diff --git a/src/attachment.cpp b/src/attachment.cpp index a9ad736..b052d00 100644 --- a/src/attachment.cpp +++ b/src/attachment.cpp @@ -25,7 +25,9 @@ #include "mapihelp.h" #include "gpgolstr.h" +#include #include +#include Attachment::Attachment() { @@ -42,6 +44,15 @@ Attachment::Attachment() } } +Attachment::Attachment(LPSTREAM stream) +{ + if (stream) + { + stream->AddRef (); + } + m_stream = stream; +} + Attachment::~Attachment() { log_debug ("%s:%s", SRCNAME, __func__); @@ -60,12 +71,6 @@ Attachment::get_display_name() const return m_utf8DisplayName; } -std::string -Attachment::get_tmp_file_name() const -{ - return m_utf8FileName; -} - void Attachment::set_display_name(const char *name) { @@ -78,26 +83,129 @@ Attachment::set_attach_type(attachtype_t type) m_type = type; } -void -Attachment::set_hidden(bool value) +bool +Attachment::isSupported(GpgME::DataProvider::Operation op) const { - m_hidden = value; + return op == GpgME::DataProvider::Read || + op == GpgME::DataProvider::Write || + op == GpgME::DataProvider::Seek || + op == GpgME::DataProvider::Release; +} + +ssize_t +Attachment::read(void *buffer, size_t bufSize) +{ + if (!bufSize) + { + return 0; + } + if (!buffer || bufSize >= ULONG_MAX) + { + log_error ("%s:%s: Read invalid", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EINVAL); + return -1; + } + if (!m_stream) + { + log_error ("%s:%s: Read on null stream.", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EIO); + return -1; + } + + ULONG cb = static_cast (bufSize); + ULONG bRead = 0; + HRESULT hr = m_stream->Read (buffer, cb, &bRead); + if (hr != S_OK && hr != S_FALSE) + { + log_error ("%s:%s: Read failed", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EIO); + return -1; + } + return static_cast(bRead); } -int -Attachment::write(const char *data, size_t size) +ssize_t +Attachment::write(const void *data, size_t size) { - if (!data || !size) + if (!size) { return 0; } - if (!m_stream && m_stream->Write (data, size, NULL) != S_OK) + if (!data || size >= ULONG_MAX) + { + GpgME::Error::setSystemError (GPG_ERR_EINVAL); + return -1; + } + if (!m_stream) { - return 1; + log_error ("%s:%s: Write on NULL stream. ", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EIO); + return -1; + } + ULONG written = 0; + if (m_stream->Write (data, static_cast(size), &written) != S_OK) + { + GpgME::Error::setSystemError (GPG_ERR_EIO); + log_error ("%s:%s: Write failed.", + SRCNAME, __func__); + return -1; } if (m_stream->Commit (0) != S_OK) { - return 1; + log_error ("%s:%s: Commit failed. ", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EIO); + return -1; + } + return static_cast (written); +} + +off_t Attachment::seek(off_t offset, int whence) +{ + DWORD dwOrigin; + switch (whence) + { + case SEEK_SET: + dwOrigin = STREAM_SEEK_SET; + break; + case SEEK_CUR: + dwOrigin = STREAM_SEEK_CUR; + break; + case SEEK_END: + dwOrigin = STREAM_SEEK_END; + break; + default: + GpgME::Error::setSystemError (GPG_ERR_EINVAL); + return (off_t) - 1; + } + if (!m_stream) + { + log_error ("%s:%s: Seek on null stream.", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EIO); + return (off_t) - 1; + } + LARGE_INTEGER move = {0, 0}; + move.QuadPart = offset; + ULARGE_INTEGER result; + HRESULT hr = m_stream->Seek (move, dwOrigin, &result); + + if (hr != S_OK) + { + log_error ("%s:%s: Seek failed. ", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EINVAL); + return (off_t) - 1; } - return 0; + return result.QuadPart; +} + +void Attachment::release() +{ + /* No op. */ + log_debug ("%s:%s", SRCNAME, __func__); } diff --git a/src/attachment.h b/src/attachment.h index 68821ff..ae1fb49 100644 --- a/src/attachment.h +++ b/src/attachment.h @@ -1,6 +1,6 @@ -/* attachment.h - Functions for attachment handling +/* attachment.h - Wrapper class for attachments * Copyright (C) 2005, 2007 g10 Code GmbH - * Copyright (C) 2015 Intevation GmbH + * Copyright (C) 2015, 2016 Intevation GmbH * * This file is part of GpgOL. * @@ -25,40 +25,41 @@ #include "mapihelp.h" #include +#include + /** Helper class for attachment actions. */ -class Attachment +class Attachment : public GpgME::DataProvider { public: /** Creates and opens a new temporary stream. */ Attachment(); + /** Creates the attachment wrapper for an existing stream. */ + Attachment(LPSTREAM stream); + /** Deletes the attachment and the underlying temporary file. */ ~Attachment(); /** Get an assoicated ISteam ptr or NULL. */ LPSTREAM get_stream(); - /** Writes data to the attachment stream. - * Calling this method automatically commits the stream. - * - * Returns 0 on success. */ - int write(const char *data, size_t size); - /** Set the display name */ void set_display_name(const char *name); std::string get_display_name() const; - std::string get_tmp_file_name() const; - void set_attach_type(attachtype_t type); - void set_hidden(bool value); + /* Dataprovider interface */ + bool isSupported(Operation) const; + ssize_t read(void *buffer, size_t bufSize); + ssize_t write(const void *buffer, size_t bufSize); + off_t seek(off_t offset, int whence); + void release(); + private: LPSTREAM m_stream; - std::string m_utf8FileName; std::string m_utf8DisplayName; attachtype_t m_type; - bool m_hidden; }; #endif // ATTACHMENT_H diff --git a/src/mail.cpp b/src/mail.cpp index 4c16852..6043ed1 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -31,6 +31,7 @@ #include "mymapitags.h" #include "mailparser.h" #include "gpgolstr.h" +#include "windowmessages.h" #include #include @@ -87,6 +88,7 @@ Mail::Mail (LPDISPATCH mailitem) : m_crypt_successful(false), m_is_smime(false), m_is_smime_checked(false), + m_moss_position(0), m_sender(NULL), m_type(MSGTYPE_UNKNOWN) { @@ -142,6 +144,19 @@ Mail::get_mail_for_item (LPDISPATCH mailitem) return it->second; } +bool +Mail::is_mail_valid (const Mail *mail) +{ + auto it = g_mail_map.begin(); + while (it != g_mail_map.end()) + { + if (it->second == mail) + return true; + ++it; + } + return false; +} + int Mail::pre_process_message () { @@ -168,7 +183,8 @@ Mail::pre_process_message () /* Create moss attachments here so that they are properly hidden when the item is read into the model. */ - if (mapi_mark_or_create_moss_attach (message, m_type)) + m_moss_position = mapi_mark_or_create_moss_attach (message, m_type); + if (!m_moss_position) { log_error ("%s:%s: Failed to find moss attachment.", SRCNAME, __func__); @@ -181,7 +197,7 @@ Mail::pre_process_message () /** Get the cipherstream of the mailitem. */ static LPSTREAM -get_cipherstream (LPDISPATCH mailitem) +get_cipherstream (LPDISPATCH mailitem, int pos) { LPDISPATCH attachments = get_oom_object (mailitem, "Attachments"); LPDISPATCH attachment = NULL; @@ -203,13 +219,9 @@ get_cipherstream (LPDISPATCH mailitem) gpgol_release (attachments); return NULL; } - if (count > 1) - { - log_debug ("%s:%s: More then one attachment count: %i. Continuing anway.", - SRCNAME, __func__, count); - } /* We assume the crypto attachment is the second item. */ - attachment = get_oom_object (attachments, "Item(2)"); + const auto item_str = std::string("Item(") + std::to_string(pos) + ")"; + attachment = get_oom_object (attachments, item_str.c_str()); gpgol_release (attachments); attachments = NULL; @@ -231,21 +243,6 @@ get_cipherstream (LPDISPATCH mailitem) return stream; } -/** Helper to check if the body should be used for decrypt verify - or if the mime Attachment should be used. */ -static bool -use_body(msgtype_t type) -{ - switch (type) - { - case MSGTYPE_GPGOL_PGP_MESSAGE: - case MSGTYPE_GPGOL_CLEAR_SIGNED: - return true; - default: - return false; - } -} - /** Helper to update the attachments of a mail object in oom. does not modify the underlying mapi structure. */ static bool @@ -270,6 +267,19 @@ add_attachments(LPDISPATCH mail, return false; } +static DWORD WINAPI +do_parsing (LPVOID arg) +{ + log_debug ("%s:%s: starting parsing for: %p", + SRCNAME, __func__, arg); + + Mail *mail = (Mail *)arg; + auto parser = mail->parser(); + parser->parse(); + do_in_ui_thread (PARSING_DONE, arg); + return 0; +} + int Mail::decrypt_verify() { @@ -282,75 +292,75 @@ Mail::decrypt_verify() { log_error ("%s:%s: Decrypt verify called for msg that needs wipe: %p", SRCNAME, __func__, m_mailitem); - return 0; + return 1; } m_processed = true; - /* Do the actual parsing */ - std::unique_ptr parser; - if (!use_body (m_type)) - { - auto cipherstream = get_cipherstream (m_mailitem); - - if (!cipherstream) - { - /* TODO Error message? */ - log_debug ("%s:%s: Failed to get cipherstream.", - SRCNAME, __func__); - return 1; - } - - parser = std::unique_ptr(new MailParser (cipherstream, m_type)); - gpgol_release (cipherstream); - } - else + /* Inser placeholder */ + if (put_oom_string (m_mailitem, "HTMLBody", WAIT_TEMPLATE)) { - parser = std::unique_ptr(); + log_error ("%s:%s: Failed to modify html body of item.", + SRCNAME, __func__); + return 1; } - const std::string err = parser->parse(); - if (!err.empty()) + /* Do the actual parsing */ + auto cipherstream = get_cipherstream (m_mailitem, m_moss_position); + + if (!cipherstream) { - /* TODO Show error message. */ - log_error ("%s:%s: Failed to parse message: %s", - SRCNAME, __func__, err.c_str()); + /* TODO Error message? */ + log_debug ("%s:%s: Failed to get cipherstream.", + SRCNAME, __func__); return 1; } + m_parser = new MailParser (cipherstream, m_type); + gpgol_release (cipherstream); + + CreateThread (NULL, 0, do_parsing, (LPVOID) this, 0, + NULL); + return 0; +} + +void Mail::parsing_done() +{ m_needs_wipe = true; /* Update the body */ - const auto html = parser->get_utf8_html_body(); + const auto html = m_parser->get_utf8_html_body(); if (!html->empty()) { if (put_oom_string (m_mailitem, "HTMLBody", html->c_str())) { log_error ("%s:%s: Failed to modify html body of item.", SRCNAME, __func__); - return 1; + return; } } else { - const auto body = parser->get_utf8_text_body(); + const auto body = m_parser->get_utf8_text_body(); if (put_oom_string (m_mailitem, "Body", body->c_str())) { log_error ("%s:%s: Failed to modify body of item.", SRCNAME, __func__); - return 1; + return; } } /* Update attachments */ - if (add_attachments (m_mailitem, parser->get_attachments())) + if (add_attachments (m_mailitem, m_parser->get_attachments())) { log_error ("%s:%s: Failed to update attachments.", SRCNAME, __func__); - return 1; + return; } /* Invalidate UI to set the correct sig status. */ + delete m_parser; + m_parser = nullptr; gpgoladdin_invalidate_ui (); - return 0; + return; } int @@ -493,7 +503,7 @@ Mail::revert_all_mails () { if (it->second->revert ()) { - log_error ("Failed to wipe mail: %p ", it->first); + log_error ("Failed to revert mail: %p ", it->first); err++; } } @@ -519,14 +529,13 @@ Mail::wipe_all_mails () int Mail::revert () { - int err; + int err = 0; if (!m_processed) { return 0; } err = gpgol_mailitem_revert (m_mailitem); - if (err == -1) { log_error ("%s:%s: Message revert failed falling back to wipe.", @@ -590,3 +599,41 @@ Mail::get_subject() { return std::string(get_oom_string (m_mailitem, "Subject")); } + +int +Mail::close_inspector () +{ + LPDISPATCH inspector = get_oom_object (m_mailitem, "GetInspector"); + HRESULT hr; + DISPID dispid; + if (!inspector) + { + log_debug ("%s:%s: No inspector.", + SRCNAME, __func__); + return -1; + } + + dispid = lookup_oom_dispid (inspector, "Close"); + if (dispid != DISPID_UNKNOWN) + { + VARIANT aVariant[1]; + DISPPARAMS dispparams; + + dispparams.rgvarg = aVariant; + dispparams.rgvarg[0].vt = VT_INT; + dispparams.rgvarg[0].intVal = 1; + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + + hr = inspector->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, + DISPATCH_METHOD, &dispparams, + NULL, NULL, NULL); + if (hr != S_OK) + { + log_debug ("%s:%s: Failed to close inspector: %#lx", + SRCNAME, __func__, hr); + return -1; + } + } + return 0; +} diff --git a/src/mail.h b/src/mail.h index 1bbc789..0dc96d4 100644 --- a/src/mail.h +++ b/src/mail.h @@ -25,6 +25,9 @@ #include "mapihelp.h" #include +#include + +class MailParser; /** @brief Data wrapper around a mailitem. * @@ -57,6 +60,13 @@ public: */ static Mail* get_mail_for_item (LPDISPATCH mailitem); + /** @brief looks for existing Mail objects. + + @returns A reference to an existing mailitem or NULL in case none + could be found. Can be used to check if a mail object was destroyed. + */ + static bool is_mail_valid (const Mail *mail); + /** @brief wipe the plaintext from all known Mail objects. * * This is intended as a "cleanup" call to be done on unload @@ -168,6 +178,22 @@ public: */ bool is_smime (); + /** @brief closes the inspector for this mail + * + * @returns true on success. + */ + int close_inspector (); + + /** @brief get the associated parser. + only valid while the actual parsing happens. */ + MailParser *parser () { return m_parser; } + + /** To be called from outside once the paser was done. + In Qt this would be a slot that is called once it is finished + we hack around that a bit by calling it from our windowmessages + handler. + */ + void parsing_done (); private: LPDISPATCH m_mailitem; LPDISPATCH m_event_sink; @@ -177,7 +203,9 @@ private: m_crypt_successful, /* We successfuly performed crypto on the item. */ m_is_smime, /* This is an smime mail. */ m_is_smime_checked; /* it was checked if this is an smime mail */ + int m_moss_position; /* The number of the original message attachment. */ char *m_sender; msgtype_t m_type; /* Our messagetype as set in mapi */ + MailParser *m_parser; }; #endif // MAIL_H diff --git a/src/mailparser.cpp b/src/mailparser.cpp index 500a383..c73de1f 100644 --- a/src/mailparser.cpp +++ b/src/mailparser.cpp @@ -23,31 +23,104 @@ #include "mailparser.h" #include "attachment.h" +#include "mimedataprovider.h" + +#include +#include + +#include + +using namespace GpgME; MailParser::MailParser(LPSTREAM instream, msgtype_t type): m_body (std::shared_ptr(new std::string())), m_htmlbody (std::shared_ptr(new std::string())), - m_stream (instream), + m_input (Data(new MimeDataProvider(instream))), m_type (type), - m_error (false), - m_in_data (false), - signed_data (nullptr), - sig_data (nullptr) + m_error (false) { - log_debug ("%s:%s: Creating parser for stream: %p", - SRCNAME, __func__, instream); - instream->AddRef(); + log_mime_parser ("%s:%s: Creating parser for stream: %p", + SRCNAME, __func__, instream); } MailParser::~MailParser() { - gpgol_release(m_stream); + log_debug ("%s:%s", SRCNAME, __func__); +} + +static void +operation_for_type(msgtype_t type, bool *decrypt, + bool *verify, Protocol *protocol) +{ + *decrypt = false; + *verify = false; + *protocol = Protocol::UnknownProtocol; + switch (type) + { + case MSGTYPE_GPGOL_MULTIPART_ENCRYPTED: + case MSGTYPE_GPGOL_PGP_MESSAGE: + *decrypt = true; + *protocol = Protocol::OpenPGP; + break; + case MSGTYPE_GPGOL_MULTIPART_SIGNED: + case MSGTYPE_GPGOL_CLEAR_SIGNED: + *verify = true; + *protocol = Protocol::OpenPGP; + break; + case MSGTYPE_GPGOL_OPAQUE_SIGNED: + *protocol = Protocol::CMS; + *verify = true; + break; + case MSGTYPE_GPGOL_OPAQUE_ENCRYPTED: + *protocol = Protocol::CMS; + *decrypt = true; + break; + default: + log_error ("%s:%s: Unknown data type: %i", + SRCNAME, __func__, type); + } } std::string MailParser::parse() { - m_body = std::shared_ptr(new std::string("Hello world")); + // Wrap the input stream in an attachment / GpgME Data + Protocol protocol; + bool decrypt, verify; + operation_for_type (m_type, &decrypt, &verify, &protocol); + auto ctx = Context::createForProtocol (protocol); + ctx->setArmor(true); + + if (decrypt) + { + Data output; + log_debug ("%s:%s: Decrypting with protocol: %s", + SRCNAME, __func__, + protocol == OpenPGP ? "OpenPGP" : + protocol == CMS ? "CMS" : "Unknown"); + auto combined_result = ctx->decryptAndVerify(m_input, output); + m_decrypt_result = combined_result.first; + m_verify_result = combined_result.second; + if (m_decrypt_result.error()) + { + MessageBox (NULL, "Decryption failed.", "Failed", MB_OK); + } + char buf[2048]; + size_t bRead; + output.seek (0, SEEK_SET); + while ((bRead = output.read (buf, 2048)) > 0) + { + (*m_body).append(buf, bRead); + } + log_debug ("Body is: %s", m_body->c_str()); + } + + if (opt.enable_debug) + { + std::stringstream ss; + ss << m_decrypt_result << '\n' << m_verify_result; + log_debug ("Decrypt / Verify result: %s", ss.str().c_str()); + } Attachment *att = new Attachment (); att->write ("Hello attachment", strlen ("Hello attachment")); att->set_display_name ("The Attachment.txt"); @@ -55,17 +128,20 @@ MailParser::parse() return std::string(); } -std::shared_ptr MailParser::get_utf8_html_body() +std::shared_ptr +MailParser::get_utf8_html_body() { return m_htmlbody; } -std::shared_ptr MailParser::get_utf8_text_body() +std::shared_ptr +MailParser::get_utf8_text_body() { return m_body; } -std::vector > MailParser::get_attachments() +std::vector > +MailParser::get_attachments() { return m_attachments; } diff --git a/src/mailparser.h b/src/mailparser.h index 1e03139..f92c313 100644 --- a/src/mailparser.h +++ b/src/mailparser.h @@ -24,12 +24,15 @@ #include "oomhelp.h" #include "mapihelp.h" -#include "gpgme.h" #include #include #include +#include +#include +#include + class Attachment; class MailParser @@ -65,17 +68,11 @@ private: std::shared_ptr m_htmlbody; /* State variables */ - LPSTREAM m_stream; + GpgME::Data m_input; msgtype_t m_type; bool m_error; - bool m_in_data; - gpgme_data_t signed_data;/* NULL or the data object used to collect - the signed data. It would be better to - just hash it but there is no support in - gpgme for this yet. */ - gpgme_data_t sig_data; /* NULL or data object to collect the - signature attachment which should be a - signature then. */ + GpgME::DecryptionResult m_decrypt_result; + GpgME::VerificationResult m_verify_result; }; #endif /* MAILPARSER_H */ diff --git a/src/main.c b/src/main.c index 12321f3..fdff49c 100644 --- a/src/main.c +++ b/src/main.c @@ -162,6 +162,13 @@ DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) gpg_err_init (); + /* Set the installation directory for GpgME so that + it can find tools like gpgme-w32-spawn correctly. */ + char *instdir; + gpgrt_asprintf (&instdir, "%s\\bin", get_gpg4win_dir ()); + gpgme_set_global_flag ("w32-inst-dir", instdir); + xfree (instdir); + /* The next call initializes subsystems of gpgme and should be done as early as possible. The actual return value (the version string) is not used here. It may be called at any diff --git a/src/mimedataprovider.cpp b/src/mimedataprovider.cpp new file mode 100644 index 0000000..d6628f3 --- /dev/null +++ b/src/mimedataprovider.cpp @@ -0,0 +1,213 @@ +/* mimedataprover.cpp - GpgME dataprovider for mime data + * Copyright (C) 2016 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify 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. + * + * GpgOL 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 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, see . + */ +#include "config.h" +#include "common.h" + +#include "mimedataprovider.h" + +/* The maximum length of a line we are able to process. RFC822 allows + only for 1000 bytes; thus 2000 seems to be a reasonable value. */ +#define LINEBUFSIZE 2000 + +/* How much data is read from the underlying stream in a collect + call. */ +#define BUFSIZE 8192 + +#include + +static int +message_cb (void *opaque, rfc822parse_event_t event, + rfc822parse_t msg) +{ + (void) opaque; + (void) event; + (void) msg; + return 0; +} + +MimeDataProvider::MimeDataProvider(LPSTREAM stream): + m_collect(true), + m_parser(rfc822parse_open (message_cb, this)), + m_current_encoding(None) +{ + if (stream) + { + stream->AddRef (); + } + else + { + log_error ("%s:%s called without stream ", SRCNAME, __func__); + return; + } + b64_init (&m_base64_context); + log_mime_parser ("%s:%s Collecting data.", SRCNAME, __func__); + collect_data (stream); + log_mime_parser ("%s:%s Data collected.", SRCNAME, __func__); + gpgol_release (stream); +} + +MimeDataProvider::~MimeDataProvider() +{ + log_debug ("%s:%s", SRCNAME, __func__); +} + +bool +MimeDataProvider::isSupported(GpgME::DataProvider::Operation op) const +{ + return op == GpgME::DataProvider::Read || + op == GpgME::DataProvider::Seek || + op == GpgME::DataProvider::Release; +} + +ssize_t +MimeDataProvider::read(void *buffer, size_t size) +{ + log_mime_parser ("%s:%s: Reading: " SIZE_T_FORMAT "Bytes", + SRCNAME, __func__, size); + ssize_t bRead = m_data.read (buffer, size); + if (opt.enable_debug & DBG_MIME_PARSER) + { + std::string buf ((char *)buffer, bRead); + log_mime_parser ("%s:%s: Data: \"%s\"", + SRCNAME, __func__, buf.c_str()); + } + return bRead; +} + +void +MimeDataProvider::decode_and_collect(char *line, size_t pos) +{ + /* We are inside the data. That should be the actual + ciphertext in the given encoding. Add it to our internal + cache. */ + int slbrk = 0; + size_t len; + + if (m_current_encoding == Quoted) + len = qp_decode (line, pos, &slbrk); + else if (m_current_encoding == Base64) + len = b64_decode (&m_base64_context, line, pos); + else + len = pos; + m_data.write (line, len); + if (m_current_encoding != Encoding::Base64 && !slbrk) + { + m_data.write ("\r\n", 2); + } + return; +} + +/* Split some raw data into lines and handle them accordingly. + returns the amount of bytes not taken from the input buffer. +*/ +size_t +MimeDataProvider::collect_input_lines(const char *input, size_t insize) +{ + char linebuf[LINEBUFSIZE]; + const char *s = input; + size_t pos = 0; + size_t nleft = insize; + size_t not_taken = nleft; + + /* Split the raw data into lines */ + for (; nleft; nleft--, s++) + { + if (pos >= LINEBUFSIZE) + { + log_error ("%s:%s: rfc822 parser failed: line too long\n", + SRCNAME, __func__); + GpgME::Error::setSystemError (GPG_ERR_EIO); + return not_taken; + } + if (*s != '\n') + linebuf[pos++] = *s; + else + { + /* Got a complete line. Remove the last CR. */ + not_taken -= pos + 1; /* Pos starts at 0 so + 1 for it */ + if (pos && linebuf[pos-1] == '\r') + { + pos--; + } + + if (rfc822parse_insert (m_parser, + (unsigned char*) linebuf, + pos)) + { + log_error ("%s:%s: rfc822 parser failed: %s\n", + SRCNAME, __func__, strerror (errno)); + return not_taken; + } + /* If we are currently in a collecting state actually + collect that line */ + if (m_collect) + { + decode_and_collect (linebuf, pos); + } + /* Continue with next line. */ + pos = 0; + } + } + return not_taken; +} + +void +MimeDataProvider::collect_data(LPSTREAM stream) +{ + if (!stream) + { + return; + } + HRESULT hr; + char buf[BUFSIZE]; + ULONG bRead; + while ((hr = stream->Read (buf, BUFSIZE, &bRead)) == S_OK || + hr == S_FALSE) + { + if (!bRead) + { + log_mime_parser ("%s:%s: Input stream at EOF.", + SRCNAME, __func__); + return; + } + log_mime_parser ("%s:%s: Read %lu bytes.", + SRCNAME, __func__, bRead); + + m_rawbuf += std::string (buf, bRead); + size_t not_taken = collect_input_lines (m_rawbuf.c_str(), + m_rawbuf.size()); + + if (not_taken == m_rawbuf.size()) + { + log_error ("%s:%s: Collect failed to consume anything.\n" + "Buffer too small?", + SRCNAME, __func__); + return; + } + log_mime_parser ("%s:%s: Consumed: " SIZE_T_FORMAT " bytes", + SRCNAME, __func__, m_rawbuf.size() - not_taken); + m_rawbuf.erase (0, m_rawbuf.size() - not_taken); + } +} + +off_t +MimeDataProvider::seek(off_t offset, int whence) +{ + return m_data.seek (offset, whence); +} diff --git a/src/mimedataprovider.h b/src/mimedataprovider.h new file mode 100644 index 0000000..8b9d8ee --- /dev/null +++ b/src/mimedataprovider.h @@ -0,0 +1,83 @@ +/* mimedataprover.h - GpgME dataprovider for mime data + * Copyright (C) 2016 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify 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. + * + * GpgOL 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 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, see . + */ +#ifndef MIMEDATAPROVIDER_H +#define MIMEDATAPROVIDER_H + +#include +#include +#include "oomhelp.h" +#include "mapihelp.h" +#include "rfc822parse.h" + +#include + +/** This class does simple one level mime parsing to find crypto + data. + + Use the mimedataprovider on a body or attachment stream. It + will do the conversion from MIME to PGP / CMS data on the fly. + + The raw mime data from the underlying stream is "collected" and + parsed into Crypto data which is then buffered in "databuf". +*/ +class MimeDataProvider : public GpgME::DataProvider +{ +public: + /* Read and parse the stream. Does not hold a reference + to the stream but releases it after read. */ + MimeDataProvider(LPSTREAM stream); + ~MimeDataProvider(); + + /* Dataprovider interface */ + bool isSupported(Operation) const; + + /** Read some data from the stream. This triggers + the conversion code interanally to convert mime + data into PGP/CMS Data that GpgME can work with. */ + ssize_t read(void *buffer, size_t bufSize); + ssize_t write(const void *buffer, size_t bufSize) { + (void)buffer; (void)bufSize; return -1; + } + /* Seek the underlying stream. This discards the internal + buffers as the offset is not mapped. Should not really + be used but can be used to reset the DataProvider. */ + off_t seek(off_t offset, int whence); + /* Noop */ + void release() {} + + /* The the data of the signature part. */ + const GpgME::Data &get_signature_data(); +private: + /* Collect the crypto data from mime. */ + void collect_data(LPSTREAM stream); + /* Collect a single line. */ + size_t collect_input_lines(const char *input, size_t size); + /* Move actual data into the databuffer. */ + void decode_and_collect(char *line, size_t pos); + enum Encoding {None, Base64, Quoted}; + std::string m_sig_data; + GpgME::Data m_data; + GpgME::Data m_signature; + std::string m_rawbuf; + bool m_collect; + rfc822parse_t m_parser; + Encoding m_current_encoding; + b64_state_t m_base64_context; +}; +#endif // MIMEDATAPROVIDER_H diff --git a/src/util.h b/src/util.h index b20f0bc..0b78332 100644 --- a/src/util.h +++ b/src/util.h @@ -96,6 +96,8 @@ void log_window_hierarchy (HWND window, const char *fmt, #define log_oom if (opt.enable_debug & DBG_OOM) log_debug #define log_oom_extra if (opt.enable_debug & DBG_OOM_EXTRA) log_debug +#define log_mime_parser if (opt.enable_debug & DBG_MIME_PARSER) log_debug + #define gpgol_release(X) \ { \ if (X && opt.enable_debug & DBG_OOM_EXTRA) \ diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index e0c95cd..d850a8c 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -1,7 +1,28 @@ +/* @file windowmessages.h + * @brief Helper class to work with the windowmessage handler thread. + * + * Copyright (C) 2015, 2016 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify 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. + * + * GpgOL 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 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, see . + */ #include "windowmessages.h" #include "util.h" #include "oomhelp.h" +#include "mail.h" #include @@ -39,10 +60,21 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ctx->err = request_send_mail ((LPDISPATCH) ctx->data); break; } + case (PARSING_DONE): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_mail_valid (mail)) + { + log_debug ("%s:%s: Parsing done for mail which is gone.", + SRCNAME, __func__); + } + mail->parsing_done(); + } + break; default: log_debug ("Unknown msg"); } - return 0; + return DefWindowProc(hWnd, message, wParam, lParam); } return DefWindowProc(hWnd, message, wParam, lParam); diff --git a/src/windowmessages.h b/src/windowmessages.h index c9355d5..ec66f7b 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -38,8 +38,10 @@ typedef enum _gpgol_wmsg_type { UNKNOWN = 0, - REQUEST_SEND_MAIL = 1 /* Request to send a mail. - Data should be LPMAILITEM */ + REQUEST_SEND_MAIL = 1, /* Request to send a mail. + Data should be LPMAILITEM */ + PARSING_DONE = 2 /* A mail was parsed. Data should be a pointer + to the mail object. */ } gpgol_wmsg_type; typedef struct commit 7f9f7bf99de356d794df06852bc12faf9c6e99ba Author: Andre Heinecke Date: Mon Aug 22 15:38:58 2016 +0200 Return MOSS attachment positon from mapihelp * src/mapihelp.cpp (mapi_mark_or_create_moss_attach): Return MOSS position. * src/mapihelp.h (mapi_mark_or_create_moss_attach): Update doc. -- Returning the attachment position here makes sense as we can then store it in the mail object and won't have search it again later. diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index 76213cb..854e6f4 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -3505,30 +3505,52 @@ mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype) /* First check if we already have one marked. */ mapi_attach_item_t *table = mapi_create_attach_table (message, 0); + int part1 = 0, + part2 = 0; for (i = 0; table && !table[i].end_of_table; i++) { if (table[i].attach_type == ATTACHTYPE_PGPBODY || table[i].attach_type == ATTACHTYPE_MOSS || table[i].attach_type == ATTACHTYPE_MOSSTEMPL) { - /* Found existing moss attachment */ - mapi_release_attach_table (table); - return 0; + if (!part1) + { + part1 = i + 1; + } + else if (!part2) + { + /* If we have two MOSS attachments we use + the second one. */ + part2 = i + 1; + break; + } } } + if (part1 || part2) + { + /* Found existing moss attachment */ + mapi_release_attach_table (table); + return part2; + } if (msgtype == MSGTYPE_GPGOL_CLEAR_SIGNED || msgtype == MSGTYPE_GPGOL_PGP_MESSAGE) { /* Inline message we need to create body attachment so that we are able to restore the content. */ - return mapi_body_to_attachment (message); + if (mapi_body_to_attachment (message)) + { + log_error ("%s:%s: Failed to create body attachment.", + SRCNAME, __func__); + return 0; + } + return 1; } if (!table) { log_debug ("%s:%s: Neither pgp inline nor an attachment table.", SRCNAME, __func__); - return -1; + return 0; } /* MIME Mails check for S/MIME first. */ @@ -3546,7 +3568,7 @@ mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype) { mapi_mark_moss_attach (message, table + i); mapi_release_attach_table (table); - return 0; + return i + 1; } /* PGP/MIME or S/MIME stuff. */ @@ -3579,7 +3601,7 @@ mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype) mapi_mark_moss_attach (message, table+part1_idx); mapi_mark_moss_attach (message, table+part2_idx); mapi_release_attach_table (table); - return 0; + return 2; } } @@ -3593,9 +3615,9 @@ mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype) we have a mean to find it again (see above). */ mapi_mark_moss_attach (message, table + 0); mapi_release_attach_table (table); - return 0; + return 1; } mapi_release_attach_table (table); - return -1; /* No original attachment - this should not happen. */ + return 0; /* No original attachment - this should not happen. */ } diff --git a/src/mapihelp.h b/src/mapihelp.h index 3f22538..da60531 100644 --- a/src/mapihelp.h +++ b/src/mapihelp.h @@ -179,7 +179,8 @@ int get_gpgol_draft_info_flags (LPMESSAGE message); int set_gpgol_draft_info_flags (LPMESSAGE message, int flags); /* Mark crypto attachments as hidden. And mark the moss - attachment for later use. Returns true on error. */ + attachment for later use. Returns the attachments position + (1 is the first attachment) or 0 in case no attachment was found. */ int mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype); /* Copy the MAPI body to a PGPBODY type attachment. */ commit 3b27162dcb06c99aa62ab12403312854871e2214 Author: Andre Heinecke Date: Mon Aug 22 15:33:24 2016 +0200 Check for and depend on GpgMEpp * configure.ac: Check for GpgMEpp. * m4/gpgme.m4 (AM_PATH_GPGMEPP): New. * src/Makefile.am: Link GpgMEpp. (AM_CXXFLAGS): Add GpgMEpp flags. diff --git a/configure.ac b/configure.ac index d6e79d9..340df73 100644 --- a/configure.ac +++ b/configure.ac @@ -166,6 +166,7 @@ AM_CONDITIONAL(BUILD_W64, test "$host" = "x86_64-w64-mingw32") AM_PATH_GPGME("$NEED_GPGME_API:$NEED_GPGME_VERSION", have_gpgme=yes,have_gpgme=no) +AM_PATH_GPGMEPP(have_gpgmepp=yes,have_gpgmepp=no) AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", have_gpg_error=yes,have_gpg_error=no) AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_USER_2, @@ -272,6 +273,14 @@ if test "$have_gpgme" = "no"; then *** (at least version $NEED_GPGME_VERSION is required.) ***]]) fi +if test "$have_gpgmepp" = "no"; then + die=yes + AC_MSG_NOTICE([[ +*** +*** You need the C++ language binding for gpgme to build this program. +** Ensure that GPGME was compiled with --enabled-languages=cpp +***]]) +fi if test "$have_libassuan" = "no"; then die=yes AC_MSG_NOTICE([[ diff --git a/m4/gpgme.m4 b/m4/gpgme.m4 index 44bf43c..4bea719 100644 --- a/m4/gpgme.m4 +++ b/m4/gpgme.m4 @@ -98,6 +98,31 @@ AC_DEFUN([AM_PATH_GPGME], AC_SUBST(GPGME_LIBS) ]) +dnl AM_PATH_GPGMEPP([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgpgme and define GPGME_CFLAGS and GPGME_LIBS. +dnl +AC_DEFUN([AM_PATH_GPGMEPP], +[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl + AC_MSG_CHECKING(for GPGME C++ Bindings) + ok=no + if $GPGME_CONFIG --have-lang=cpp 2>/dev/null ; then + ok=yes + fi + if test $ok = yes; then + GPGMEPP_CXXFLAGS="-I `$GPGME_CONFIG --prefix`/include/gpgme++" + GPGMEPP_CXXFLAGS="${GPGMEPP_CXXFLAGS} -DGPGMEPP_STATIC_DEFINE" + AC_MSG_RESULT(yes) + ifelse([$1], , :, [$1]) + else + GPGMEPP_CFLAGS="" + GPGMEPP_LIBS="" + AC_MSG_RESULT(no) + ifelse([$2], , :, [$2]) + fi + AC_SUBST(GPGMEPP_CXXFLAGS) + AC_SUBST(GPGMEPP_LIBS) +]) + dnl AM_PATH_GPGME_PTH([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libgpgme and define GPGME_PTH_CFLAGS and GPGME_PTH_LIBS. diff --git a/src/Makefile.am b/src/Makefile.am index f9507f4..65e4f7b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,6 +34,7 @@ EXEEXT = .dll AM_CFLAGS = $(GPGME_CFLAGS) $(LIBASSUAN_CFLAGS) -shared AM_CXXFLAGS = $(GPGME_CFLAGS) $(LIBASSUAN_CFLAGS) -shared -std=c++11 +AM_CXXFLAGS += $(GPGMEPP_CXXFLAGS) gpgol_SOURCES = \ main.c gpgol.def \ @@ -98,7 +99,7 @@ gpgol_SOURCES = \ # versions of GPGME and gpg-error, because we want to link to them # statically, and not dynamically (otherwise Outlook would not find # them). -gpgol_DEPENDENCIES = libmapi32.a libgpg-error.a libgpgme.a libassuan.a +gpgol_DEPENDENCIES = libmapi32.a libgpg-error.a libgpgme.a libassuan.a libgpgmepp.a if BUILD_W64 DLLTOOLFLAGS64=--as-flags=--64 -m i386:x86-64 @@ -116,13 +117,16 @@ libgpgme.a: libassuan.a: ln -s $$($(LIBASSUAN_CONFIG) --prefix)/lib/libassuan.a . +libgpgmepp.a: + ln -s $$($(LIBASSUAN_CONFIG) --prefix)/lib/libgpgmepp.a . + clean-local: - rm -f libmapi32.a libgpg-error.a libgpgme.a libassuan.a + rm -f libmapi32.a libgpg-error.a libgpgme.a libassuan.a libgpgmepp.a gpgol_LDFLAGS = -static-libgcc -static-libstdc++ gpgol_LDADD = $(srcdir)/gpgol.def \ - -L . -lgpgme -lassuan -lgpg-error \ + -L . -lgpgmepp -lgpgme -lassuan -lgpg-error \ -lmapi32 -lshell32 -lgdi32 -lcomdlg32 \ -lole32 -loleaut32 -lws2_32 -ladvapi32 \ -luuid -lgdiplus commit 87d57374bbe502b121d68874e9e807e89a20f358 Author: Andre Heinecke Date: Mon Aug 22 15:32:32 2016 +0200 Bump required gpgme version to 1.7.0 * configure.ac (NEED_GPGME_VERSION): 1.7.0 diff --git a/configure.ac b/configure.ac index 709e427..d6e79d9 100644 --- a/configure.ac +++ b/configure.ac @@ -40,7 +40,7 @@ GPGOL_FORMS_REVISION=335 NEED_GPG_ERROR_VERSION=1.9 NEED_GPGME_API=1 -NEED_GPGME_VERSION=1.1.0 +NEED_GPGME_VERSION=1.7.0 NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_VERSION=2.0.0 ----------------------------------------------------------------------- Summary of changes: configure.ac | 11 ++- m4/gpgme.m4 | 25 ++++++ src/Makefile.am | 13 ++- src/attachment.cpp | 140 +++++++++++++++++++++++++++---- src/attachment.h | 29 +++---- src/mail.cpp | 163 +++++++++++++++++++++++------------- src/mail.h | 28 +++++++ src/mailparser.cpp | 102 ++++++++++++++++++++--- src/mailparser.h | 17 ++-- src/main.c | 7 ++ src/mapihelp.cpp | 40 +++++++-- src/mapihelp.h | 3 +- src/mimedataprovider.cpp | 213 +++++++++++++++++++++++++++++++++++++++++++++++ src/mimedataprovider.h | 83 ++++++++++++++++++ src/util.h | 2 + src/windowmessages.cpp | 34 +++++++- src/windowmessages.h | 6 +- 17 files changed, 787 insertions(+), 129 deletions(-) create mode 100644 src/mimedataprovider.cpp create mode 100644 src/mimedataprovider.h hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 17:02:53 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 17:02:53 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-294-g24e6198 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 24e61984c9532924135c57b8ff98489a2d3bd4a3 (commit) via c9e7dcb100d807583d8e312da459561138231376 (commit) from 3e60788810f93cfcd7f08e5882aff32ed7b6f831 (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 24e61984c9532924135c57b8ff98489a2d3bd4a3 Author: Werner Koch Date: Mon Aug 22 16:57:51 2016 +0200 core: Add new items for gpgme_get_dirinfo. * src/dirinfo.c (WANT_SYSCONFDIR, WANT_LIBEXECDIR, WANT_LIBDIR): New. (WANT_DATADIR, WANT_LCOALEDIR, WANT_AGENT_SSH_SOCKET): New (WANT_DIRMNGR_SOCKET): New. (dirinfo): Add fields 'sysconfdir', 'bindir', 'libexecdir', 'libdir', 'datadir', 'localedir', 'agent_ssh_socket', and 'dirmngr_socket'. (parse_output): Set these fields. (get_gpgconf_item): Return them. (gpgme_get_dirinfo): Likewise. Signed-off-by: Werner Koch diff --git a/doc/gpgme.texi b/doc/gpgme.texi index e8a735a..b28c6ca 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -946,9 +946,34 @@ supported values for @var{what} are: @item homedir Return the default home directory. + at item sysconfdir +Return the name of the system configuration directory + + at item bindir +Return the name of the directory with GnuPG program files. + + at item libdir +Return the name of the directory with GnuPG related library files. + + at item libexecdir +Return the name of the directory with GnuPG helper program files. + + at item datadir +Return the name of the directory with GnuPG shared data. + + at item localedir +Return the name of the directory with GnuPG locale data. + @item agent-socket Return the name of the socket to connect to the gpg-agent. + at item agent-ssh-socket +Return the name of the socket to connect to the ssh-agent component of +gpg-agent. + + at item dirmngr-socket +Return the name of the socket to connect to the dirmngr. + @item uiserver-socket Return the name of the socket to connect to the user interface server. diff --git a/src/dirinfo.c b/src/dirinfo.c index 226f93c..ecb1c0c 100644 --- a/src/dirinfo.c +++ b/src/dirinfo.c @@ -37,12 +37,20 @@ DEFINE_STATIC_LOCK (dirinfo_lock); enum { WANT_HOMEDIR, + WANT_SYSCONFDIR, + WANT_BINDIR, + WANT_LIBEXECDIR, + WANT_LIBDIR, + WANT_DATADIR, + WANT_LOCALEDIR, WANT_AGENT_SOCKET, + WANT_AGENT_SSH_SOCKET, + WANT_DIRMNGR_SOCKET, + WANT_UISRV_SOCKET, WANT_GPGCONF_NAME, WANT_GPG_NAME, WANT_GPGSM_NAME, WANT_G13_NAME, - WANT_UISRV_SOCKET, WANT_GPG_ONE_MODE }; @@ -51,12 +59,20 @@ static struct { int valid; /* Cached information is valid. */ int disable_gpgconf; char *homedir; + char *sysconfdir; + char *bindir; + char *libexecdir; + char *libdir; + char *datadir; + char *localedir; char *agent_socket; + char *agent_ssh_socket; + char *dirmngr_socket; + char *uisrv_socket; char *gpgconf_name; char *gpg_name; char *gpgsm_name; char *g13_name; - char *uisrv_socket; int gpg_one_mode; /* System is in gpg1 mode. */ } dirinfo; @@ -121,6 +137,18 @@ parse_output (char *line, int components) { if (!strcmp (line, "homedir") && !dirinfo.homedir) dirinfo.homedir = strdup (value); + else if (!strcmp (line, "sysconfdir") && !dirinfo.sysconfdir) + dirinfo.sysconfdir = strdup (value); + else if (!strcmp (line, "bindir") && !dirinfo.bindir) + dirinfo.bindir = strdup (value); + else if (!strcmp (line, "libexecdir") && !dirinfo.libexecdir) + dirinfo.libexecdir = strdup (value); + else if (!strcmp (line, "libdir") && !dirinfo.libdir) + dirinfo.libdir = strdup (value); + else if (!strcmp (line, "datadir") && !dirinfo.datadir) + dirinfo.datadir = strdup (value); + else if (!strcmp (line, "localedir") && !dirinfo.localedir) + dirinfo.localedir = strdup (value); else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket) { const char name[] = "S.uiserver"; @@ -139,6 +167,10 @@ parse_output (char *line, int components) } } } + else if (!strcmp (line, "dirmngr-socket") && !dirinfo.dirmngr_socket) + dirinfo.dirmngr_socket = strdup (value); + else if (!strcmp (line, "agent-ssh-socket") && !dirinfo.agent_ssh_socket) + dirinfo.agent_ssh_socket = strdup (value); } } @@ -273,14 +305,28 @@ get_gpgconf_item (int what) if (dirinfo.agent_socket) _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: agent='%s'\n", dirinfo.agent_socket); + if (dirinfo.agent_ssh_socket) + _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: ssh='%s'\n", + dirinfo.agent_ssh_socket); + if (dirinfo.dirmngr_socket) + _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: dirmngr='%s'\n", + dirinfo.dirmngr_socket); if (dirinfo.uisrv_socket) _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: uisrv='%s'\n", dirinfo.uisrv_socket); } switch (what) { - case WANT_HOMEDIR: result = dirinfo.homedir; break; + case WANT_HOMEDIR: result = dirinfo.homedir; break; + case WANT_SYSCONFDIR: result = dirinfo.sysconfdir; break; + case WANT_BINDIR: result = dirinfo.bindir; break; + case WANT_LIBEXECDIR: result = dirinfo.libexecdir; break; + case WANT_LIBDIR: result = dirinfo.libdir; break; + case WANT_DATADIR: result = dirinfo.datadir; break; + case WANT_LOCALEDIR: result = dirinfo.localedir; break; case WANT_AGENT_SOCKET: result = dirinfo.agent_socket; break; + case WANT_AGENT_SSH_SOCKET: result = dirinfo.agent_ssh_socket; break; + case WANT_DIRMNGR_SOCKET: result = dirinfo.dirmngr_socket; break; case WANT_GPGCONF_NAME: result = dirinfo.gpgconf_name; break; case WANT_GPG_NAME: result = dirinfo.gpg_name; break; case WANT_GPGSM_NAME: result = dirinfo.gpgsm_name; break; @@ -392,6 +438,22 @@ gpgme_get_dirinfo (const char *what) return get_gpgconf_item (WANT_GPGSM_NAME); else if (!strcmp (what, "g13-name")) return get_gpgconf_item (WANT_G13_NAME); + else if (!strcmp (what, "agent-ssh-socket")) + return get_gpgconf_item (WANT_AGENT_SSH_SOCKET); + else if (!strcmp (what, "dirmngr-socket")) + return get_gpgconf_item (WANT_DIRMNGR_SOCKET); + else if (!strcmp (what, "sysconfdir")) + return get_gpgconf_item (WANT_SYSCONFDIR); + else if (!strcmp (what, "bindir")) + return get_gpgconf_item (WANT_BINDIR); + else if (!strcmp (what, "libexecdir")) + return get_gpgconf_item (WANT_LIBEXECDIR); + else if (!strcmp (what, "libdir")) + return get_gpgconf_item (WANT_LIBDIR); + else if (!strcmp (what, "datadir")) + return get_gpgconf_item (WANT_DATADIR); + else if (!strcmp (what, "localedir")) + return get_gpgconf_item (WANT_LOCALEDIR); else return NULL; } diff --git a/tests/t-engine-info.c b/tests/t-engine-info.c index 53f5b2f..8f617f9 100644 --- a/tests/t-engine-info.c +++ b/tests/t-engine-info.c @@ -111,8 +111,20 @@ main (int argc, char **argv ) gpgme_check_version (NULL); { - const char *keys[] = {"homedir", "agent-socket", "uiserver-socket", - "gpgconf-name", "gpg-name", "gpgsm-name", + const char *keys[] = {"homedir", + "sysconfdir", + "bindir", + "libexecdir", + "libdir", + "datadir", + "localedir", + "agent-socket", + "agent-ssh-socket", + "dirmngr-socket", + "uiserver-socket", + "gpgconf-name", + "gpg-name", + "gpgsm-name", "g13-name", NULL }; const char *s; int i; commit c9e7dcb100d807583d8e312da459561138231376 Author: Werner Koch Date: Mon Aug 22 16:32:14 2016 +0200 core: Base gpgme_get_dirinfo(uiserver-socket) on the socket dir. * src/dirinfo.c (dirname_len): New. (parse_output): Change computation of UISRV_SOCKET. Signed-off-by: Werner Koch diff --git a/src/dirinfo.c b/src/dirinfo.c index 8824c9a..226f93c 100644 --- a/src/dirinfo.c +++ b/src/dirinfo.c @@ -70,6 +70,15 @@ _gpgme_dirinfo_disable_gpgconf (void) } +/* Return the length of the directory part including the trailing + * slash of NAME. */ +static size_t +dirname_len (const char *name) +{ + return _gpgme_get_basename (name) - name; +} + + /* Parse the output of "gpgconf --list-dirs". This function expects that DIRINFO_LOCK is held by the caller. If COMPONENTS is set, the output of --list-components is expected. */ @@ -77,6 +86,7 @@ static void parse_output (char *line, int components) { char *value, *p; + size_t n; value = strchr (line, ':'); if (!value) @@ -110,22 +120,25 @@ parse_output (char *line, int components) else { if (!strcmp (line, "homedir") && !dirinfo.homedir) + dirinfo.homedir = strdup (value); + else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket) { const char name[] = "S.uiserver"; + char *buffer; - dirinfo.homedir = strdup (value); - if (dirinfo.homedir) + dirinfo.agent_socket = strdup (value); + if (dirinfo.agent_socket) { - dirinfo.uisrv_socket = malloc (strlen (dirinfo - .homedir) - + 1 + strlen (name) + 1); - if (dirinfo.uisrv_socket) - strcpy (stpcpy (stpcpy (dirinfo.uisrv_socket, dirinfo.homedir), - DIRSEP_S), name); + n = dirname_len (dirinfo.agent_socket); + buffer = malloc (n + strlen (name) + 1); + if (buffer) + { + strncpy (buffer, dirinfo.agent_socket, n); + strcpy (buffer + n, name); + dirinfo.uisrv_socket = buffer; + } } } - else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket) - dirinfo.agent_socket = strdup (value); } } ----------------------------------------------------------------------- Summary of changes: doc/gpgme.texi | 25 +++++++++++++ src/dirinfo.c | 101 +++++++++++++++++++++++++++++++++++++++++++------- tests/t-engine-info.c | 16 +++++++- 3 files changed, 127 insertions(+), 15 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 22 17:07:42 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 17:07:42 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-3-gc47386a 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 c47386a11a32c5ed3b5a31fad5c3e9a9a020ca7b (commit) from 62f3e0027724b23c0de5be6d1e66cfdeef7e7bc9 (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 c47386a11a32c5ed3b5a31fad5c3e9a9a020ca7b Author: Werner Koch Date: Mon Aug 22 17:05:00 2016 +0200 wks: Install gpg-wks-client under libexec * tools/Makefile.am (bin_PROGRAMS): Move gpg-wks-client to ... (libexec_PROGRAMS): ...here. -- Signed-off-by: Werner Koch diff --git a/tools/Makefile.am b/tools/Makefile.am index 12e5815..6df49f6 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -53,13 +53,16 @@ else gpg_wks_client = endif +libexec_PROGRAMS = + bin_PROGRAMS = gpgconf gpg-connect-agent ${symcryptrun} if !HAVE_W32_SYSTEM -bin_PROGRAMS += watchgnupg gpgparsemail ${gpg_wks_server} ${gpg_wks_client} +bin_PROGRAMS += watchgnupg gpgparsemail ${gpg_wks_server} +libexec_PROGRAMS += ${gpg_wks_client} endif if !DISABLE_REGEX -libexec_PROGRAMS = gpg-check-pattern +libexec_PROGRAMS += gpg-check-pattern endif if !HAVE_W32CE_SYSTEM ----------------------------------------------------------------------- Summary of changes: tools/Makefile.am | 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 Mon Aug 22 20:47:55 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Aug 2016 20:47:55 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-4-g5424597 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 54245979e691129ed9d3a6c642087fb8d3227449 (commit) from c47386a11a32c5ed3b5a31fad5c3e9a9a020ca7b (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 54245979e691129ed9d3a6c642087fb8d3227449 Author: Werner Koch Date: Mon Aug 22 20:44:23 2016 +0200 common: Change license of mbox-util to LGPLv2.1+. -- Noet that the code has entirely been written by me. Signed-off-by: Werner Koch diff --git a/common/mbox-util.c b/common/mbox-util.c index 2029324..c451198 100644 --- a/common/mbox-util.c +++ b/common/mbox-util.c @@ -5,26 +5,16 @@ * This file is part of GnuPG. * * This file 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. + * 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. * * This file 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 + * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . */ diff --git a/common/mbox-util.h b/common/mbox-util.h index 4dd48ec..9c7271f 100644 --- a/common/mbox-util.h +++ b/common/mbox-util.h @@ -4,26 +4,16 @@ * This file is part of GnuPG. * * This file 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. + * 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. * * This file 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 + * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . */ #ifndef GNUPG_COMMON_MBOX_UTIL_H ----------------------------------------------------------------------- Summary of changes: common/mbox-util.c | 18 ++++-------------- common/mbox-util.h | 18 ++++-------------- 2 files changed, 8 insertions(+), 28 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 23 15:26:49 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 23 Aug 2016 15:26:49 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-297-gbe4ff75 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 be4ff75d7d5ac6ed15feb245ef3cec59b4bad561 (commit) via 3955dce06e9d056599e5ec7d40301e66b9305195 (commit) via 26c5ba528ce1411d96655952ec48359105695c0f (commit) from 24e61984c9532924135c57b8ff98489a2d3bd4a3 (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 be4ff75d7d5ac6ed15feb245ef3cec59b4bad561 Author: Werner Koch Date: Tue Aug 23 15:22:28 2016 +0200 core: Change the way TOFU information are represented. * src/gpgme.h.in (struct _gpgme_signature): Remove field 'tofu'. Add field 'key'. (struct _gpgme_key): Add field 'fpr'. (struct _gpgme_user_id): Add field 'tofu'. (struct _gpgme_tofu_info): Remove fields 'address' and 'fpr'. * src/key.c (gpgme_key_unref): Release TOFU and FPR. * src/keylist.c (keylist_colon_handler): Store the fingerprint of the first subkey also in KEY. * src/verify.c (release_tofu_info): Remove. (release_op_data): Release KEY. (parse_tofu_user): Rewrite for new data structure. (parse_tofu_stats): Ditto. (parse_tofu_stats_long): Ditto. * tests/run-verify.c (print_result): Ditto. * tests/run-keylist.c (main): Print more fields. -- TOFU information are now associated with the user ID and not with a separate object. Note that this breaks code relying on the former non-released TOFU feature. The C++ bindings won't work right now. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index ce16687..1294e0b 100644 --- a/NEWS +++ b/NEWS @@ -15,8 +15,10 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] GPGME_PK_EDDSA NEW. gpgme_set_ctx_flag NEW. gpgme_data_set_flag NEW. - gpgme_signature_t EXTENDED: New field tofu. + gpgme_signature_t EXTENDED: New field key. + gpgme_key_t EXTENDED: New field fpr. gpgme_subkey_t EXTENDED: New field keygrip. + gpgme_user_id_t EXTENDED: New field tofu. gpgme_tofu_policy_t NEW. gpgme_tofu_info_t NEW. GPGME_STATUS_KEY_CONSIDERED NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index b28c6ca..02551d9 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3017,6 +3017,10 @@ This is the key ID of the subkey in hexadecimal digits. This is the fingerprint of the subkey in hexadecimal digits, if available. + at item char *keygrip +The keygrip of the subkey in hex digit form or @code{NULL} if not +availabale. + @item long int timestamp This is the creation timestamp of the subkey. This is -1 if the timestamp is invalid, and 0 if it is not available. @@ -3144,6 +3148,16 @@ This is the comment component of @code{uid}, if available. @item char *email This is the email component of @code{uid}, if available. + at item char *address; +The mail address (addr-spec from RFC-5322) of the user ID string. +This is general the same as the @code{email} part of this structure +but might be slightly different. If no mail address is available + at code{NULL} is stored. + + at item gpgme_tofu_info_t tofu +If not @code{NULL} information from the TOFU database pertaining to +this user id. + @item gpgme_key_sig_t signatures This is a linked list with the signatures on this user ID. @end table @@ -3168,8 +3182,8 @@ This is true if the key is disabled. @item unsigned int invalid : 1 This is true if the key is invalid. This might have several reasons, -for a example for the S/MIME backend, it will be set in during key -listsing if the key could not be validated due to a missing +for a example for the S/MIME backend, it will be set during key +listings if the key could not be validated due to missing certificates or unmatched policies. @item unsigned int can_encrypt : 1 @@ -3224,6 +3238,13 @@ in the list is the primary key and usually available. @item gpgme_user_id_t uids This is a linked list with the user IDs of the key. The first user ID in the list is the main (or primary) user ID. + + at item char *fpr +This field gives the fingerprint of the primary key. Note that +this is a copy of the fingerprint of the first subkey. For an +incomplete key (for example from a verification result) a subkey may +be missing but this field may be set nevertheless. + @end table @end deftp @@ -4870,6 +4891,13 @@ The hash algorithm used to create this signature. @item char *pka_address The mailbox from the PKA information or @code{NULL}. + + at item gpgme_key_t key +An object describing the key used to create the signature. This key +object may be incomplete in that it only conveys information +availabale directly with a signature. It may also be @code{NULL} if +such information is not readily available. + @end table @end deftp diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 49cea77..c07cac8 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -624,6 +624,41 @@ struct _gpgme_engine_info typedef struct _gpgme_engine_info *gpgme_engine_info_t; +/* An object with TOFU information. */ +struct _gpgme_tofu_info +{ + struct _gpgme_tofu_info *next; + + /* The TOFU validity: + * 0 := conflict + * 1 := key without history + * 2 := key with too little history + * 3 := key with enough history for basic trust + * 4 := key with a lot of history + */ + unsigned int validity : 3; + + /* The TOFU policy (gpgme_tofu_policy_t). */ + unsigned int policy : 4; + + unsigned int _rfu : 25; + + /* Number of signatures seen for this binding. Capped at USHRT_MAX. */ + unsigned short signcount; + /* Number of encryptions done with this binding. Capped at USHRT_MAX. */ + unsigned short encrcount; + + /* Number of seconds since the first and the most recently seen + * message was verified. */ + unsigned int firstseen; + unsigned int lastseen; + + /* If non-NULL a human readable string summarizing the TOFU data. */ + char *description; +}; +typedef struct _gpgme_tofu_info *gpgme_tofu_info_t; + + /* A subkey from a key. */ struct _gpgme_subkey { @@ -807,6 +842,9 @@ struct _gpgme_user_id * might be slightly different. IF no mail address is available * NULL is stored. */ char *address; + + /* The malloced tofo information or NULL. */ + gpgme_tofu_info_t tofu; }; typedef struct _gpgme_user_id *gpgme_user_id_t; @@ -883,6 +921,11 @@ struct _gpgme_key /* The keylist mode that was active when listing the key. */ gpgme_keylist_mode_t keylist_mode; + + /* This field gives the fingerprint of the primary key. Note that + * this is a copy of the FPR of the first subkey. We need it here + * to allow for an incomplete key object. */ + char *fpr; }; typedef struct _gpgme_key *gpgme_key_t; @@ -1570,50 +1613,6 @@ typedef enum gpgme_sigsum_t; -struct _gpgme_tofu_info -{ - struct _gpgme_tofu_info *next; - - /* The mail address (addr-spec from RFC5322) of the tofu binding. - * - * If no mail address is set for a User ID this is the name used - * for the user ID. Can be ambiguous when the same mail address or - * name is used in multiple user ids. - */ - char *address; - - /* The fingerprint of the primary key. */ - char *fpr; - - /* The TOFU validity: - * 0 := conflict - * 1 := key without history - * 2 := key with too little history - * 3 := key with enough history for basic trust - * 4 := key with a lot of history - */ - unsigned int validity : 3; - - /* The TOFU policy (gpgme_tofu_policy_t). */ - unsigned int policy : 4; - - unsigned int _rfu : 25; - - /* Number of signatures seen for this binding. Capped at USHRT_MAX. */ - unsigned short signcount; - unsigned short reserved; - - /* Number of seconds since the first and the most recently seen - * message was verified. */ - unsigned int firstseen; - unsigned int lastseen; - - /* If non-NULL a human readable string summarizing the TOFU data. */ - char *description; -}; -typedef struct _gpgme_tofu_info *gpgme_tofu_info_t; - - struct _gpgme_signature { struct _gpgme_signature *next; @@ -1621,7 +1620,7 @@ struct _gpgme_signature /* A summary of the signature status. */ gpgme_sigsum_t summary; - /* The fingerprint or key ID of the signature. */ + /* The fingerprint of the signature. This can be a subkey. */ char *fpr; /* The status of the signature. */ @@ -1660,8 +1659,9 @@ struct _gpgme_signature /* The mailbox from the PKA information or NULL. */ char *pka_address; - /* If non-NULL, TOFU info for this signature are available. */ - gpgme_tofu_info_t tofu; + /* If non-NULL, a possible incomplete key object with the data + * available for the signature. */ + gpgme_key_t key; }; typedef struct _gpgme_signature *gpgme_signature_t; diff --git a/src/key.c b/src/key.c index f642501..38acc71 100644 --- a/src/key.c +++ b/src/key.c @@ -356,6 +356,7 @@ gpgme_key_unref (gpgme_key_t key) { gpgme_user_id_t next_uid = uid->next; gpgme_key_sig_t keysig = uid->signatures; + gpgme_tofu_info_t tofu = uid->tofu; while (keysig) { @@ -373,8 +374,21 @@ gpgme_key_unref (gpgme_key_t key) free (keysig); keysig = next_keysig; } + + while (tofu) + { + /* NB: The ->next is currently not used but we are prepared + * for it. */ + gpgme_tofu_info_t tofu_next = tofu->next; + + free (tofu->description); + free (tofu); + tofu = tofu_next; + } + if (uid->address && uid->address != uid->email) free (uid->address); + free (uid); uid = next_uid; } @@ -386,10 +400,13 @@ gpgme_key_unref (gpgme_key_t key) if (key->chain_id) free (key->chain_id); + if (key->fpr) + free (key->fpr); free (key); } + /* Support functions. */ diff --git a/src/keylist.c b/src/keylist.c index 5a346ea..38ddd0c 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -708,6 +708,22 @@ keylist_colon_handler (void *priv, char *line) if (!subkey->fpr) return gpg_error_from_syserror (); } + /* If this is the first subkey, store the fingerprint also + in the KEY object. */ + if (subkey == key->subkeys) + { + if (key->fpr && strcmp (key->fpr, subkey->fpr)) + { + /* FPR already set but mismatch: Should never happen. */ + return trace_gpg_error (GPG_ERR_INTERNAL); + } + if (!key->fpr) + { + key->fpr = strdup (subkey->fpr); + if (!key->fpr) + return gpg_error_from_syserror (); + } + } } /* Field 13 has the gpgsm chain ID (take only the first one). */ diff --git a/src/ops.h b/src/ops.h index 9c27529..97b1019 100644 --- a/src/ops.h +++ b/src/ops.h @@ -138,9 +138,11 @@ gpgme_error_t _gpgme_progress_status_handler (void *priv, gpgme_error_t _gpgme_key_new (gpgme_key_t *r_key); gpgme_error_t _gpgme_key_add_subkey (gpgme_key_t key, gpgme_subkey_t *r_subkey); -gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert); +gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, + const char *src, int convert); gpgme_key_sig_t _gpgme_key_add_sig (gpgme_key_t key, char *src); + /* From keylist.c. */ void _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, diff --git a/src/verify.c b/src/verify.c index 1ec09fe..173d1cb 100644 --- a/src/verify.c +++ b/src/verify.c @@ -50,22 +50,6 @@ typedef struct static void -release_tofu_info (gpgme_tofu_info_t t) -{ - while (t) - { - gpgme_tofu_info_t t2 = t->next; - - free (t->address); - free (t->fpr); - free (t->description); - free (t); - t = t2; - } -} - - -static void release_op_data (void *hook) { op_data_t opd = (op_data_t) hook; @@ -88,7 +72,8 @@ release_op_data (void *hook) free (sig->fpr); if (sig->pka_address) free (sig->pka_address); - release_tofu_info (sig->tofu); + if (sig->key) + gpgme_key_unref (sig->key); free (sig); sig = next; } @@ -690,49 +675,80 @@ parse_tofu_user (gpgme_signature_t sig, char *args) { gpg_error_t err; char *tail; - gpgme_tofu_info_t ti, ti2; + gpgme_user_id_t uid; + gpgme_tofu_info_t ti; + char *fpr = NULL; + char *address = NULL; tail = strchr (args, ' '); if (!tail || tail == args) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No fingerprint. */ + { + err = trace_gpg_error (GPG_ERR_INV_ENGINE); /* No fingerprint. */ + goto leave; + } *tail++ = 0; - ti = calloc (1, sizeof *ti); - if (!ti) - return gpg_error_from_syserror (); - - ti->fpr = strdup (args); - if (!ti->fpr) + fpr = strdup (args); + if (!fpr) { - free (ti); - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; } args = tail; tail = strchr (args, ' '); if (tail == args) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No addr-spec. */ + { + err = trace_gpg_error (GPG_ERR_INV_ENGINE); /* No addr-spec. */ + goto leave; + } if (tail) *tail = 0; - err = _gpgme_decode_percent_string (args, &ti->address, 0, 0); + err = _gpgme_decode_percent_string (args, &address, 0, 0); if (err) + goto leave; + + if (!sig->key) { - free (ti); - return err; + err = _gpgme_key_new (&sig->key); + if (err) + goto leave; + sig->key->fpr = fpr; + fpr = NULL; + } + else if (!sig->key->fpr) + { + err = trace_gpg_error (GPG_ERR_INTERNAL); + goto leave; + } + else if (strcmp (sig->key->fpr, fpr)) + { + /* The engine did not emit NEWSIG before a new key. */ + err = trace_gpg_error (GPG_ERR_INV_ENGINE); + goto leave; } - /* Append to the tofu info list. */ - if (!sig->tofu) - sig->tofu = ti; - else + err = _gpgme_key_append_name (sig->key, address, 0); + if (err) + goto leave; + + uid = sig->key->_last_uid; + assert (uid); + + ti = calloc (1, sizeof *ti); + if (!ti) { - for (ti2 = sig->tofu; ti2->next; ti2 = ti2->next) - ; - ti2->next = ti; + err = gpg_error_from_syserror (); + goto leave; } + uid->tofu = ti; - return 0; + + leave: + free (fpr); + free (address); + return err; } @@ -749,12 +765,10 @@ parse_tofu_stats (gpgme_signature_t sig, char *args) int nfields; unsigned long uval; - if (!sig->tofu) + if (!sig->key || !sig->key->_last_uid || !(ti = sig->key->_last_uid->tofu)) return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No TOFU_USER seen. */ - for (ti = sig->tofu; ti->next; ti = ti->next) - ; if (ti->firstseen || ti->signcount || ti->validity || ti->policy) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already seen. */ + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already set. */ nfields = _gpgme_split_fields (args, field, DIM (field)); if (nfields < 3) @@ -825,12 +839,10 @@ parse_tofu_stats_long (gpgme_signature_t sig, char *args, int raw) gpgme_tofu_info_t ti; char *p; - if (!sig->tofu) + if (!sig->key || !sig->key->_last_uid || !(ti = sig->key->_last_uid->tofu)) return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No TOFU_USER seen. */ - for (ti = sig->tofu; ti->next; ti = ti->next) - ; if (ti->description) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already seen. */ + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already set. */ err = _gpgme_decode_percent_string (args, &ti->description, 0, 0); if (err) diff --git a/tests/run-keylist.c b/tests/run-keylist.c index cc4c354..bae2dbb 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -233,7 +233,14 @@ main (int argc, char **argv) for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++) { printf ("userid %d: %s\n", nuids, nonnull(uid->uid)); - printf ("valid %d: %s\n", nuids, + printf (" mbox %d: %s\n", nuids, nonnull(uid->address)); + if (uid->email && uid->email != uid->address) + printf (" email %d: %s\n", nuids, uid->email); + if (uid->name) + printf (" name %d: %s\n", nuids, uid->name); + if (uid->comment) + printf (" cmmnt %d: %s\n", nuids, uid->comment); + printf (" valid %d: %s\n", nuids, uid->validity == GPGME_VALIDITY_UNKNOWN? "unknown": uid->validity == GPGME_VALIDITY_UNDEFINED? "undefined": uid->validity == GPGME_VALIDITY_NEVER? "never": diff --git a/tests/run-verify.c b/tests/run-verify.c index b174516..ef4dd32 100644 --- a/tests/run-verify.c +++ b/tests/run-verify.c @@ -111,6 +111,7 @@ print_result (gpgme_verify_result_t result) { gpgme_signature_t sig; gpgme_sig_notation_t nt; + gpgme_user_id_t uid; gpgme_tofu_info_t ti; int count = 0; @@ -153,29 +154,34 @@ print_result (gpgme_verify_result_t result) if ((nt->value?strlen (nt->value):0) != nt->value_len) printf (" warning : value larger (%d)\n", nt->value_len); } - for (ti = sig->tofu; ti; ti = ti->next) + if (sig->key) { - printf (" tofu addr .: %s\n", ti->address); - if (!sig->fpr || strcmp (sig->fpr, ti->fpr)) - printf (" WARNING .: fpr mismatch (%s)\n", ti->fpr); - printf (" validity : %u (%s)\n", ti->validity, - ti->validity == 0? "conflict" : - ti->validity == 1? "no history" : - ti->validity == 2? "little history" : - ti->validity == 3? "enough history" : - ti->validity == 4? "lot of history" : "?"); - printf (" policy ..: %u (%s)\n", ti->policy, - ti->policy == GPGME_TOFU_POLICY_NONE? "none" : - ti->policy == GPGME_TOFU_POLICY_AUTO? "auto" : - ti->policy == GPGME_TOFU_POLICY_GOOD? "good" : - ti->policy == GPGME_TOFU_POLICY_UNKNOWN? "unknown" : - ti->policy == GPGME_TOFU_POLICY_BAD? "bad" : - ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?"); - printf (" sigcount : %hu\n", ti->signcount); - printf (" firstseen: %u\n", ti->firstseen); - printf (" lastseen : %u\n", ti->lastseen); - printf (" desc ....: "); - print_description (nonnull (ti->description), 15); + printf (" primary fpr: %s\n", nonnull (sig->key->fpr)); + for (uid = sig->key->uids; uid; uid = uid->next) + { + printf (" tofu addr .: %s\n", nonnull (uid->address)); + ti = uid->tofu; + if (!ti) + continue; + printf (" validity : %u (%s)\n", ti->validity, + ti->validity == 0? "conflict" : + ti->validity == 1? "no history" : + ti->validity == 2? "little history" : + ti->validity == 3? "enough history" : + ti->validity == 4? "lot of history" : "?"); + printf (" policy ..: %u (%s)\n", ti->policy, + ti->policy == GPGME_TOFU_POLICY_NONE? "none" : + ti->policy == GPGME_TOFU_POLICY_AUTO? "auto" : + ti->policy == GPGME_TOFU_POLICY_GOOD? "good" : + ti->policy == GPGME_TOFU_POLICY_UNKNOWN? "unknown" : + ti->policy == GPGME_TOFU_POLICY_BAD? "bad" : + ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?"); + printf (" sigcount : %hu\n", ti->signcount); + printf (" firstseen: %u\n", ti->firstseen); + printf (" lastseen : %u\n", ti->lastseen); + printf (" desc ....: "); + print_description (nonnull (ti->description), 15); + } } } } commit 3955dce06e9d056599e5ec7d40301e66b9305195 Author: Werner Koch Date: Tue Aug 23 06:48:50 2016 +0200 core: Extend gpgme_user_id_t with 'address'. * src/mbox-util.c, src/mbox-util.h: Adjust for use in gpgme. * src/Makefile.am (main_sources): Add mbox-util. * src/key.c (_gpgme_key_append_name): Set 'address' field of uid. (gpgme_key_unref): Free it. Signed-off-by: Werner Koch diff --git a/src/Makefile.am b/src/Makefile.am index 6691540..d541f87 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,6 +76,7 @@ endif main_sources = \ util.h conversion.c b64dec.c get-env.c context.h ops.h \ parsetlv.c parsetlv.h \ + mbox-util.c mbox-util.h \ data.h data.c data-fd.c data-stream.c data-mem.c data-user.c \ data-compat.c data-identify.c \ signers.c sig-notation.c \ diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 40f5442..49cea77 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -801,6 +801,12 @@ struct _gpgme_user_id /* Internal to GPGME, do not use. */ gpgme_key_sig_t _last_keysig; + + /* The mail address (addr-spec from RFC5322) of the UID string. + * This is general the same as the EMAIL part of this struct but + * might be slightly different. IF no mail address is available + * NULL is stored. */ + char *address; }; typedef struct _gpgme_user_id *gpgme_user_id_t; diff --git a/src/key.c b/src/key.c index de97102..f642501 100644 --- a/src/key.c +++ b/src/key.c @@ -31,6 +31,8 @@ #include "ops.h" #include "sema.h" #include "debug.h" +#include "mbox-util.h" + /* Protects all reference counters in keys. All other accesses to a @@ -233,6 +235,14 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert) parse_user_id (uid->uid, &uid->name, &uid->email, &uid->comment, dst); + uid->address = _gpgme_mailbox_from_userid (uid->uid); + if (uid->address && uid->email && !strcmp (uid->address, uid->email)) + { + /* The ADDRESS is the same as EMAIL: Save some space. */ + free (uid->address); + uid->address = uid->email; + } + if (!key->uids) key->uids = uid; if (key->_last_uid) @@ -363,6 +373,8 @@ gpgme_key_unref (gpgme_key_t key) free (keysig); keysig = next_keysig; } + if (uid->address && uid->address != uid->email) + free (uid->address); free (uid); uid = next_uid; } diff --git a/src/mbox-util.c b/src/mbox-util.c index c451198..83c8b5e 100644 --- a/src/mbox-util.c +++ b/src/mbox-util.c @@ -18,16 +18,34 @@ * along with this program; if not, see . */ -#include +/* NB: This code has been taken from GnuPG. Please keep it in sync + * with GnuPG. */ + +#if HAVE_CONFIG_H +# include +#endif + #include #include #include #include #include -#include "util.h" #include "mbox-util.h" +/* Lowercase all ASCII characters in STRING. */ +static char * +ascii_strlwr (char *string) +{ + char *p; + + for (p = string; *p; p++ ) + if (!(*p & ~0x7f) && *p >= 'A' && *p <= 'Z') + *p |= 0x20; + + return string; +} + static int string_count_chr (const char *string, int c) @@ -117,7 +135,7 @@ has_dotdot_after_at (const char *string) 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 +static int has_invalid_email_chars (const void *buffer, size_t length) { const unsigned char *s = buffer; @@ -143,7 +161,7 @@ has_invalid_email_chars (const void *buffer, size_t length) /* Same as is_valid_mailbox (see below) but operates on non-nul terminated buffer. */ -int +static int is_valid_mailbox_mem (const void *name_arg, size_t namelen) { const char *name = name_arg; @@ -162,7 +180,7 @@ is_valid_mailbox_mem (const void *name_arg, size_t namelen) /* Check whether NAME represents a valid mailbox according to RFC822. Returns true if so. */ int -is_valid_mailbox (const char *name) +_gpgme_is_valid_mailbox (const char *name) { return name? is_valid_mailbox_mem (name, strlen (name)) : 0; } @@ -173,7 +191,7 @@ is_valid_mailbox (const char *name) lowercase. Caller must free the result. Returns NULL if no valid mailbox was found (or we are out of memory). */ char * -mailbox_from_userid (const char *userid) +_gpgme_mailbox_from_userid (const char *userid) { const char *s, *s_end; size_t len; @@ -188,7 +206,7 @@ mailbox_from_userid (const char *userid) if (s_end && s_end > s) { len = s_end - s; - result = xtrymalloc (len + 1); + result = malloc (len + 1); if (!result) return NULL; /* Ooops - out of core. */ strncpy (result, s, len); @@ -202,7 +220,7 @@ mailbox_from_userid (const char *userid) || string_has_ctrl_or_space (result) || has_dotdot_after_at (result)) { - xfree (result); + free (result); result = NULL; errno = EINVAL; } @@ -210,14 +228,14 @@ mailbox_from_userid (const char *userid) else errno = EINVAL; } - else if (is_valid_mailbox (userid)) + else if (_gpgme_is_valid_mailbox (userid)) { /* The entire user id is a mailbox. Return that one. Note that this fallback method has some restrictions on the valid syntax of the mailbox. However, those who want weird addresses should know about it and use the regular <...> syntax. */ - result = xtrystrdup (userid); + result = strdup (userid); } else errno = EINVAL; @@ -226,14 +244,14 @@ mailbox_from_userid (const char *userid) } -/* Check whether UID is a valid standard user id of the form - "Heinrich Heine " - and return true if this is the case. */ -int -is_valid_user_id (const char *uid) -{ - if (!uid || !*uid) - return 0; +/* /\* Check whether UID is a valid standard user id of the form */ +/* "Heinrich Heine " */ +/* and return true if this is the case. *\/ */ +/* int */ +/* is_valid_user_id (const char *uid) */ +/* { */ +/* if (!uid || !*uid) */ +/* return 0; */ - return 1; -} +/* return 1; */ +/* } */ diff --git a/src/mbox-util.h b/src/mbox-util.h index 9c7271f..3195a4d 100644 --- a/src/mbox-util.h +++ b/src/mbox-util.h @@ -19,11 +19,11 @@ #ifndef GNUPG_COMMON_MBOX_UTIL_H #define GNUPG_COMMON_MBOX_UTIL_H -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); +/* int has_invalid_email_chars (const void *buffer, size_t length); */ +int _gpgme_is_valid_mailbox (const char *name); +/* int _gpgme_is_valid_mailbox_mem (const void *buffer, size_t length); */ +char *_gpgme_mailbox_from_userid (const char *userid); +/* int is_valid_user_id (const char *uid); */ #endif /*GNUPG_COMMON_MBOX_UTIL_H*/ commit 26c5ba528ce1411d96655952ec48359105695c0f Author: Werner Koch Date: Mon Aug 22 20:50:37 2016 +0200 core: New code for parsing mail addresses. * src/mbox-util.c: New. * src/mbox-util.h: New. -- The files haven been copied verbatim from GnuPG 2.1.15 commit 54245979e691129ed9d3a6c642087fb8d3227449 after the license has been changed in GnuPG. We need this file too match GnuPG's idea of a mail address. Signed-off-by: Werner Koch diff --git a/src/mbox-util.c b/src/mbox-util.c new file mode 100644 index 0000000..c451198 --- /dev/null +++ b/src/mbox-util.c @@ -0,0 +1,239 @@ +/* mbox-util.c - Mail address helper functions + * Copyright (C) 1998-2010 Free Software Foundation, Inc. + * Copyright (C) 1998-2015 Werner Koch + * + * This file is part of GnuPG. + * + * This file is free software; you can redistribute it and/or modify + * 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. + * + * This file 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 Lesser General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "mbox-util.h" + + +static int +string_count_chr (const char *string, int c) +{ + int count; + + for (count=0; *string; string++ ) + if ( *string == c ) + count++; + 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) +{ + for (; *string; string++ ) + if (!(*string & 0x80) && *string <= 0x20) + return 1; + return 0; +} + + +/* Return true if STRING has two consecutive '.' after an '@' + sign. */ +static int +has_dotdot_after_at (const char *string) +{ + string = strchr (string, '@'); + if (!string) + return 0; /* No at-sign. */ + string++; + return !!strstr (string, ".."); +} + + +/* 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 void *buffer, size_t length) +{ + const unsigned char *s = buffer; + int at_seen=0; + const char *valid_chars= + "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + for ( ; length && *s; length--, s++ ) + { + if ((*s & 0x80)) + continue; /* We only care about ASCII. */ + if (*s == '@') + at_seen=1; + else if (!at_seen && !(strchr (valid_chars, *s) + || strchr ("!#$%&'*+/=?^`{|}~", *s))) + return 1; + 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? is_valid_mailbox_mem (name, strlen (name)) : 0; +} + + +/* Return the mailbox (local-part at domain) form a standard user id. + All plain ASCII characters in the result are converted to + lowercase. Caller must free the result. Returns NULL if no valid + mailbox was found (or we are out of memory). */ +char * +mailbox_from_userid (const char *userid) +{ + const char *s, *s_end; + size_t len; + char *result = NULL; + + s = strchr (userid, '<'); + if (s) + { + /* Seems to be a standard user id. */ + s++; + s_end = strchr (s, '>'); + if (s_end && s_end > s) + { + len = s_end - s; + result = xtrymalloc (len + 1); + if (!result) + return NULL; /* Ooops - out of core. */ + strncpy (result, s, len); + result[len] = 0; + /* Apply some basic checks on the address. We do not use + is_valid_mailbox because those checks are too strict. */ + if (string_count_chr (result, '@') != 1 /* Need exactly one '@. */ + || *result == '@' /* local-part missing. */ + || result[len-1] == '@' /* domain missing. */ + || result[len-1] == '.' /* ends with a dot. */ + || string_has_ctrl_or_space (result) + || has_dotdot_after_at (result)) + { + xfree (result); + result = NULL; + errno = EINVAL; + } + } + else + errno = EINVAL; + } + else if (is_valid_mailbox (userid)) + { + /* The entire user id is a mailbox. Return that one. Note that + this fallback method has some restrictions on the valid + syntax of the mailbox. However, those who want weird + addresses should know about it and use the regular <...> + syntax. */ + result = xtrystrdup (userid); + } + else + errno = EINVAL; + + return result? ascii_strlwr (result): NULL; +} + + +/* Check whether UID is a valid standard user id of the form + "Heinrich Heine " + and return true if this is the case. */ +int +is_valid_user_id (const char *uid) +{ + if (!uid || !*uid) + return 0; + + return 1; +} diff --git a/src/mbox-util.h b/src/mbox-util.h new file mode 100644 index 0000000..9c7271f --- /dev/null +++ b/src/mbox-util.h @@ -0,0 +1,29 @@ +/* mbox-util.h - Defs for mail address helper functions + * Copyright (C) 2015 Werner Koch + * + * This file is part of GnuPG. + * + * This file is free software; you can redistribute it and/or modify + * 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. + * + * This file 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 Lesser General Public License + * along with this program; if not, see . + */ +#ifndef GNUPG_COMMON_MBOX_UTIL_H +#define GNUPG_COMMON_MBOX_UTIL_H + +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); + + +#endif /*GNUPG_COMMON_MBOX_UTIL_H*/ ----------------------------------------------------------------------- Summary of changes: NEWS | 4 +- doc/gpgme.texi | 32 ++++++- src/Makefile.am | 1 + src/gpgme.h.in | 100 ++++++++++---------- src/key.c | 29 ++++++ src/keylist.c | 16 ++++ src/mbox-util.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mbox-util.h | 29 ++++++ src/ops.h | 4 +- src/verify.c | 106 ++++++++++++---------- tests/run-keylist.c | 9 +- tests/run-verify.c | 50 +++++----- 12 files changed, 516 insertions(+), 121 deletions(-) create mode 100644 src/mbox-util.c create mode 100644 src/mbox-util.h hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 23 15:58:30 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 23 Aug 2016 15:58:30 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-298-g2972c44 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 2972c44bd7e97b2169dea9c4a49d9754afdae3f0 (commit) from be4ff75d7d5ac6ed15feb245ef3cec59b4bad561 (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 2972c44bd7e97b2169dea9c4a49d9754afdae3f0 Author: Werner Koch Date: Tue Aug 23 15:55:55 2016 +0200 core: Put the protocol into a TOFU created key object. * src/verify.c (parse_tofu_user): Add arg 'protocol' and store it in the KEY. (_gpgme_verify_status_handler): Pass protocol. Signed-off-by: Werner Koch diff --git a/src/verify.c b/src/verify.c index 173d1cb..075f1d6 100644 --- a/src/verify.c +++ b/src/verify.c @@ -671,7 +671,7 @@ parse_trust (gpgme_signature_t sig, gpgme_status_code_t code, char *args) /* Parse a TOFU_USER line and put the info into SIG. */ static gpgme_error_t -parse_tofu_user (gpgme_signature_t sig, char *args) +parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol) { gpg_error_t err; char *tail; @@ -715,6 +715,7 @@ parse_tofu_user (gpgme_signature_t sig, char *args) if (err) goto leave; sig->key->fpr = fpr; + sig->key->protocol = protocol; fpr = NULL; } else if (!sig->key->fpr) @@ -993,7 +994,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) case GPGME_STATUS_TOFU_USER: opd->only_newsig_seen = 0; - return sig ? parse_tofu_user (sig, args) + return sig ? parse_tofu_user (sig, args, ctx->protocol) /* */ : trace_gpg_error (GPG_ERR_INV_ENGINE); case GPGME_STATUS_TOFU_STATS: ----------------------------------------------------------------------- Summary of changes: src/verify.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 23 16:44:54 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 23 Aug 2016 16:44:54 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-299-g799b168 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 799b168243e6499ac01bf59e0656547f353a2589 (commit) from 2972c44bd7e97b2169dea9c4a49d9754afdae3f0 (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 799b168243e6499ac01bf59e0656547f353a2589 Author: Andre Heinecke Date: Tue Aug 23 16:40:21 2016 +0200 Cpp: Move tofuinfo from signature to userid * lang/cpp/src/key.cpp (UserID::tofuInfo): New. * lang/cpp/src/key.h: Update accordingly. * lang/cpp/src/tofuinfo.cpp: Remove dropped fields. * lang/cpp/src/tofuinfo.h: Update accordingly. * lang/cpp/src/verificationresult.cpp, lang/cpp/src/verificationresult.h: Remove tofu info. * lang/qt/tests/t-tofuinfo.cpp: Disable for now. -- With be4ff75d7 Tofu info now lives with a UserID Object. While this breaks API it was not yet released. diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index d99c5ec..68d7685 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -23,6 +23,7 @@ #include #include "util.h" +#include "tofuinfo.h" #include @@ -625,6 +626,14 @@ bool UserID::isInvalid() const return uid && uid->invalid; } +TofuInfo UserID::tofuInfo() const +{ + if (!uid) { + return TofuInfo(); + } + return TofuInfo(uid->tofu); +} + // // // class Signature diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h index bb0487b..e8d7ee2 100644 --- a/lang/cpp/src/key.h +++ b/lang/cpp/src/key.h @@ -43,6 +43,7 @@ class Context; class Subkey; class UserID; +class TofuInfo; typedef std::shared_ptr< std::remove_pointer::type > shared_gpgme_key_t; @@ -309,6 +310,10 @@ public: bool isRevoked() const; bool isInvalid() const; + /** TOFU info for this userid. + * @returns The TOFU stats or a null TofuInfo. + */ + GpgME::TofuInfo tofuInfo() const; private: shared_gpgme_key_t key; gpgme_user_id_t uid; diff --git a/lang/cpp/src/tofuinfo.cpp b/lang/cpp/src/tofuinfo.cpp index c27a59e..fe8f051 100644 --- a/lang/cpp/src/tofuinfo.cpp +++ b/lang/cpp/src/tofuinfo.cpp @@ -31,12 +31,6 @@ public: Private(gpgme_tofu_info_t info) : mInfo(info ? new _gpgme_tofu_info(*info) : nullptr) { - if (mInfo && mInfo->fpr) { - mInfo->fpr = strdup(mInfo->fpr); - } - if (mInfo && mInfo->address) { - mInfo->address = strdup(mInfo->address); - } if (mInfo && mInfo->description) { mInfo->description = strdup(mInfo->description); } @@ -45,12 +39,6 @@ public: Private(const Private &other) : mInfo(other.mInfo) { - if (mInfo && mInfo->fpr) { - mInfo->fpr = strdup(mInfo->fpr); - } - if (mInfo && mInfo->address) { - mInfo->address = strdup(mInfo->address); - } if (mInfo && mInfo->description) { mInfo->description = strdup(mInfo->description); } @@ -59,10 +47,6 @@ public: ~Private() { if (mInfo) { - std::free(mInfo->fpr); - mInfo->fpr = nullptr; - std::free(mInfo->address); - mInfo->address = nullptr; std::free(mInfo->description); mInfo->description = nullptr; @@ -129,16 +113,6 @@ GpgME::TofuInfo::Policy GpgME::TofuInfo::policy() const } } -const char *GpgME::TofuInfo::fingerprint() const -{ - return isNull() ? nullptr : d->mInfo->fpr; -} - -const char *GpgME::TofuInfo::address() const -{ - return isNull() ? nullptr : d->mInfo->address; -} - const char *GpgME::TofuInfo::description() const { return isNull() ? nullptr : d->mInfo->description; @@ -163,9 +137,7 @@ std::ostream &GpgME::operator<<(std::ostream &os, const GpgME::TofuInfo &info) { os << "GpgME::Signature::TofuInfo("; if (!info.isNull()) { - os << "\n address: " << protect(info.address()) - << "\n fpr: " << protect(info.fingerprint()) - << "\n desc: " << protect(info.description()) + os << "\n desc: " << protect(info.description()) << "\n validity: " << info.validity() << "\n policy: " << info.policy() << "\n signcount: "<< info.signCount() diff --git a/lang/cpp/src/tofuinfo.h b/lang/cpp/src/tofuinfo.h index c698360..4835120 100644 --- a/lang/cpp/src/tofuinfo.h +++ b/lang/cpp/src/tofuinfo.h @@ -99,20 +99,9 @@ public: /* Number of seconds since the last message was verified. */ unsigned int lastSeen() const; - /* Finterprint of the key for this entry. */ - const char *fingerprint() const; - /* If non-NULL a human readable string summarizing the TOFU data. */ const char *description() const; - /* The address of the tofu binding. - * - * If no mail address is set for a User ID this is the name used - * for the user ID. Can be ambiguous when the same mail address or - * name is used in multiple user ids. - */ - const char *address() const; - private: class Private; std::shared_ptr d; diff --git a/lang/cpp/src/verificationresult.cpp b/lang/cpp/src/verificationresult.cpp index 3eb8a85..c32c896 100644 --- a/lang/cpp/src/verificationresult.cpp +++ b/lang/cpp/src/verificationresult.cpp @@ -24,7 +24,6 @@ #include #include "result_p.h" #include "util.h" -#include "tofuinfo.h" #include @@ -82,11 +81,6 @@ public: } nota.back().push_back(n); } - // copy tofu info: - tinfos.push_back(std::vector()); - for (gpgme_tofu_info_t in = is->tofu; in ; in = in->next) { - tinfos.back().push_back(TofuInfo(in)); - } } } ~Private() @@ -113,7 +107,6 @@ public: std::vector sigs; std::vector< std::vector > nota; - std::vector< std::vector > tinfos; std::vector purls; std::string file_name; }; @@ -373,15 +366,6 @@ std::vector GpgME::Signature::notations() const return result; } -std::vector GpgME::Signature::tofuInfo() const -{ - if (isNull()) { - return std::vector(); - } - - return d->tinfos[idx]; -} - class GpgME::Notation::Private { public: @@ -550,9 +534,6 @@ std::ostream &GpgME::operator<<(std::ostream &os, const Signature &sig) const std::vector nota = sig.notations(); std::copy(nota.begin(), nota.end(), std::ostream_iterator(os, "\n")); - const std::vector tinfos = sig.tofuInfo(); - std::copy(tinfos.begin(), tinfos.end(), - std::ostream_iterator(os, "\n")); } return os << ')'; } diff --git a/lang/cpp/src/verificationresult.h b/lang/cpp/src/verificationresult.h index f5fbc2e..3394a47 100644 --- a/lang/cpp/src/verificationresult.h +++ b/lang/cpp/src/verificationresult.h @@ -40,7 +40,6 @@ namespace GpgME class Error; class Signature; class Notation; -class TofuInfo; class GPGMEPP_EXPORT VerificationResult : public Result { @@ -158,18 +157,6 @@ public: GpgME::Notation notation(unsigned int index) const; std::vector notations() const; - /** List of TOFU stats for this signature. - * - * For each UserID of the key used to create this - * signature a tofu entry is returned. - * - * Warning: Addresses can be ambigous if there are multiple UserID's - * with the same mailbox in a key. - * - * @returns The list of TOFU stats. - */ - std::vector tofuInfo() const; - private: std::shared_ptr d; unsigned int idx; diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index 3072f0f..2f2ed43 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -57,6 +57,7 @@ static const char testMsg1[] = class TofuInfoTest: public QGpgMETest { +#if 0 Q_OBJECT void testTofuCopy(TofuInfo other, const TofuInfo &orig) @@ -235,6 +236,7 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: mDir.path() + QStringLiteral("/secring.gpg"))); } +#endif }; QTEST_MAIN(TofuInfoTest) ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/key.cpp | 9 +++++++++ lang/cpp/src/key.h | 5 +++++ lang/cpp/src/tofuinfo.cpp | 30 +----------------------------- lang/cpp/src/tofuinfo.h | 11 ----------- lang/cpp/src/verificationresult.cpp | 19 ------------------- lang/cpp/src/verificationresult.h | 13 ------------- lang/qt/tests/t-tofuinfo.cpp | 2 ++ 7 files changed, 17 insertions(+), 72 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 24 14:01:56 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 24 Aug 2016 14:01:56 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-302-gd2e40fb 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 d2e40fb7adf667f3e2d2457ee4c646ea4d4d88b3 (commit) via 7c5a4974b71c30e824cbfcb3a0a70064e5ed5adb (commit) via 40ea1c85773cbe324557c34b3a4282f609fcdaf6 (commit) from 799b168243e6499ac01bf59e0656547f353a2589 (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 d2e40fb7adf667f3e2d2457ee4c646ea4d4d88b3 Author: Andre Heinecke Date: Wed Aug 24 14:00:41 2016 +0200 Qt: Adapt (disabled) tofuinfo test to new API * lang/qt/tests/t-tofuinfo.cpp: Switch to UID based API. -- Test is still disabled as GnuPG still returns unexpected results. diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index 2f2ed43..ab466ee 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -41,6 +41,7 @@ #include "qgpgmesignjob.h" #include "key.h" #include "t-support.h" +#include "engineinfo.h" #include using namespace QGpgME; @@ -57,14 +58,20 @@ static const char testMsg1[] = class TofuInfoTest: public QGpgMETest { -#if 0 Q_OBJECT + bool testSupported() + { + /* GnuPG currently returns different values for different uid's + * on the first verify. This breaks this test. so its disabled + * for now. See GnuPG-Bug 2405 */ + return !(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "3.0.0"); + } + void testTofuCopy(TofuInfo other, const TofuInfo &orig) { Q_ASSERT(!orig.isNull()); Q_ASSERT(!other.isNull()); - Q_ASSERT(!strcmp(orig.fingerprint(), other.fingerprint())); Q_ASSERT(orig.lastSeen() == other.lastSeen()); Q_ASSERT(orig.signCount() == other.signCount()); Q_ASSERT(orig.validity() == other.validity()); @@ -84,6 +91,9 @@ class TofuInfoTest: public QGpgMETest QByteArray signedData; auto sigResult = job->exec(keys, what.toUtf8(), NormalSignatureMode, signedData); + auto info = keys[0].userID(0).tofuInfo(); + Q_ASSERT(info.signCount() == expected - 1); + Q_ASSERT(!sigResult.error()); auto verifyJob = openpgp()->verifyOpaqueJob(); @@ -97,23 +107,23 @@ class TofuInfoTest: public QGpgMETest Q_ASSERT(result.numSignatures() == 1); auto sig = result.signatures()[0]; - Q_FOREACH(const TofuInfo stats, sig.tofuInfo()) { - Q_ASSERT(!stats.isNull()); - Q_ASSERT(!strcmp(stats.fingerprint(), sig.fingerprint())); - Q_ASSERT(stats.signCount() == expected); - } + auto key2 = sig.key(); + Q_ASSERT(!key.isNull()); + Q_ASSERT(!strcmp (key2.primaryFingerprint(), key.primaryFingerprint())); + Q_ASSERT(!strcmp (key.primaryFingerprint(), sig.fingerprint())); + auto stats = key2.userID(0).tofuInfo(); + Q_ASSERT(!stats.isNull()); + Q_ASSERT(stats.signCount() == expected); } -private: - QTemporaryDir mDir; - -private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: +private Q_SLOTS: void testTofuNull() { + if (!testSupported()) { + return; + } TofuInfo tofu; Q_ASSERT(tofu.isNull()); - Q_ASSERT(!tofu.fingerprint()); - Q_ASSERT(!tofu.address()); Q_ASSERT(!tofu.description()); Q_ASSERT(!tofu.signCount()); Q_ASSERT(!tofu.lastSeen()); @@ -124,6 +134,9 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: void testTofuInfo() { + if (!testSupported()) { + return; + } auto *job = openpgp()->verifyOpaqueJob(true); const QByteArray data1(testMsg1); QByteArray plaintext; @@ -139,20 +152,17 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: /* TOFU is always marginal */ Q_ASSERT(sig.validity() == Signature::Marginal); - Q_ASSERT(!sig.tofuInfo().empty()); - Q_FOREACH(const TofuInfo stats, sig.tofuInfo()) { - Q_ASSERT(!stats.isNull()); - Q_ASSERT(!strcmp(stats.fingerprint(), sig.fingerprint())); - Q_ASSERT(stats.firstSeen() == stats.lastSeen()); - Q_ASSERT(!stats.signCount()); - Q_ASSERT(stats.address()); - /* See issue2405 Comment back in when resolved - Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); */ - Q_ASSERT(stats.validity() == TofuInfo::NoHistory); - } + auto stats = sig.key().userID(0).tofuInfo(); + Q_ASSERT(!stats.isNull()); + Q_ASSERT(sig.key().primaryFingerprint()); + Q_ASSERT(sig.fingerprint()); + Q_ASSERT(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint())); + Q_ASSERT(stats.firstSeen() == stats.lastSeen()); + Q_ASSERT(stats.signCount() == 1); + Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); + Q_ASSERT(stats.validity() == TofuInfo::LittleHistory); - const TofuInfo first = sig.tofuInfo()[0]; - testTofuCopy(first, first); + testTofuCopy(stats, stats); /* Another verify */ @@ -167,15 +177,13 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: /* TOFU is always marginal */ Q_ASSERT(sig.validity() == Signature::Marginal); - Q_ASSERT(!sig.tofuInfo().empty()); - Q_FOREACH(const TofuInfo stats, sig.tofuInfo()) { - Q_ASSERT(!stats.isNull()); - Q_ASSERT(!strcmp(stats.fingerprint(), sig.fingerprint())); - Q_ASSERT(stats.signCount() == 1); - Q_ASSERT(stats.address()); - Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); - Q_ASSERT(stats.validity() == TofuInfo::LittleHistory); - } + stats = sig.key().userID(0).tofuInfo(); + Q_ASSERT(!stats.isNull()); + Q_ASSERT(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint())); + Q_ASSERT(stats.firstSeen() == stats.lastSeen()); + Q_ASSERT(stats.signCount() == 1); + Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); + Q_ASSERT(stats.validity() == TofuInfo::LittleHistory); /* Verify that another call yields the same result */ job = openpgp()->verifyOpaqueJob(true); @@ -189,19 +197,20 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: /* TOFU is always marginal */ Q_ASSERT(sig.validity() == Signature::Marginal); - Q_ASSERT(!sig.tofuInfo().empty()); - Q_FOREACH(const TofuInfo stats, sig.tofuInfo()) { - Q_ASSERT(!stats.isNull()); - Q_ASSERT(!strcmp(stats.fingerprint(), sig.fingerprint())); - Q_ASSERT(stats.signCount() == 1); - Q_ASSERT(stats.address()); - Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); - Q_ASSERT(stats.validity() == TofuInfo::LittleHistory); - } + stats = sig.key().userID(0).tofuInfo(); + Q_ASSERT(!stats.isNull()); + Q_ASSERT(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint())); + Q_ASSERT(stats.firstSeen() == stats.lastSeen()); + Q_ASSERT(stats.signCount() == 1); + Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); + Q_ASSERT(stats.validity() == TofuInfo::LittleHistory); } void testTofuSignCount() { + if (!testSupported()) { + return; + } auto *job = openpgp()->keyListJob(false, false, false); std::vector keys; GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("zulu at example.net"), @@ -210,10 +219,10 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: Key key = keys[0]; Q_ASSERT(!key.isNull()); - signAndVerify(QStringLiteral("Hello"), key, 0); - signAndVerify(QStringLiteral("Hello2"), key, 1); - signAndVerify(QStringLiteral("Hello3"), key, 2); - signAndVerify(QStringLiteral("Hello4"), key, 3); + signAndVerify(QStringLiteral("Hello"), key, 1); + signAndVerify(QStringLiteral("Hello2"), key, 2); + signAndVerify(QStringLiteral("Hello3"), key, 3); + signAndVerify(QStringLiteral("Hello4"), key, 4); } void initTestCase() @@ -236,7 +245,9 @@ private /* FIXME Disabled until GnuPG-Bug-Id 2405 is fixed Q_SLOTS */: mDir.path() + QStringLiteral("/secring.gpg"))); } -#endif +private: + QTemporaryDir mDir; + }; QTEST_MAIN(TofuInfoTest) commit 7c5a4974b71c30e824cbfcb3a0a70064e5ed5adb Author: Andre Heinecke Date: Wed Aug 24 13:59:37 2016 +0200 Cpp: Add Key to signature * lang/cpp/src/verificationresult.cpp, lang/cpp/src/verificationresult.h (Signature::key): New. diff --git a/lang/cpp/src/verificationresult.cpp b/lang/cpp/src/verificationresult.cpp index c32c896..c62625d 100644 --- a/lang/cpp/src/verificationresult.cpp +++ b/lang/cpp/src/verificationresult.cpp @@ -24,6 +24,7 @@ #include #include "result_p.h" #include "util.h" +#include "key.h" #include @@ -64,6 +65,10 @@ public: # endif scopy->next = 0; sigs.push_back(scopy); + // copy keys + if (scopy->key) { + keys.push_back(Key(scopy->key, true)); + } // copy notations: nota.push_back(std::vector()); purls.push_back(0); @@ -107,6 +112,7 @@ public: std::vector sigs; std::vector< std::vector > nota; + std::vector keys; std::vector purls; std::string file_name; }; @@ -366,6 +372,14 @@ std::vector GpgME::Signature::notations() const return result; } +GpgME::Key GpgME::Signature::key() const +{ + if (isNull()) { + return Key(); + } + return d->keys[idx]; +} + class GpgME::Notation::Private { public: diff --git a/lang/cpp/src/verificationresult.h b/lang/cpp/src/verificationresult.h index 3394a47..93288af 100644 --- a/lang/cpp/src/verificationresult.h +++ b/lang/cpp/src/verificationresult.h @@ -40,6 +40,7 @@ namespace GpgME class Error; class Signature; class Notation; +class Key; class GPGMEPP_EXPORT VerificationResult : public Result { @@ -157,6 +158,11 @@ public: GpgME::Notation notation(unsigned int index) const; std::vector notations() const; + /** Returns the key object associated with this signature. + * May be incomplete but will have at least the fingerprint + * set or the associated TOFU Information if applicable. */ + GpgME::Key key() const; + private: std::shared_ptr d; unsigned int idx; commit 40ea1c85773cbe324557c34b3a4282f609fcdaf6 Author: Andre Heinecke Date: Wed Aug 24 13:57:49 2016 +0200 Cpp: Use fpr field for primaryFingerprint * lang/cpp/src/key.cpp (Key::primaryFingerprint): Return fpr value if available. -- Should not be necessary but we might have an incomplete key without subkeys but the fingerprint already set in gpgme's data type. diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index 68d7685..6f40f66 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -259,11 +259,16 @@ const char *Key::shortKeyID() const const char *Key::primaryFingerprint() const { - const char *fpr = key && key->subkeys ? key->subkeys->fpr : 0 ; - if (fpr) { - return fpr; - } else { - return keyID(); + if (!key) { + return nullptr; + } + if (key->fpr) { + /* Return what gpgme thinks is the primary fingerprint */ + return key->fpr; + } + if (key->subkeys) { + /* Return the first subkeys fingerprint */ + return key->subkeys->fpr; } } ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/key.cpp | 15 +++-- lang/cpp/src/verificationresult.cpp | 14 +++++ lang/cpp/src/verificationresult.h | 6 ++ lang/qt/tests/t-tofuinfo.cpp | 109 ++++++++++++++++++++---------------- 4 files changed, 90 insertions(+), 54 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 24 14:17:35 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Aug 2016 14:17:35 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-303-ge20b0f0 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 e20b0f0201543834f15c5d50cd3b2ece69a35d70 (commit) from d2e40fb7adf667f3e2d2457ee4c646ea4d4d88b3 (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 e20b0f0201543834f15c5d50cd3b2ece69a35d70 Author: Werner Koch Date: Tue Aug 23 19:50:01 2016 +0200 cpp: Get rid of AssuanResult due to its deprecation. * lang/cpp/src/assuanresult.cpp: Remove. * lang/cpp/src/assuanresult.h: Remove. * lang/cpp/src/Makefile.am: Remove these files. * lang/cpp/src/context.cpp: Remove header assuanresult.h (assuanTransact): Change return type to Error. Use gpgme_op_assuan_transact_ext. (startAssuanTransaction): Change return type to Error. (assuanResult): Remove * lang/cpp/src/context.h (assuanResult): Adjust for changes. Signed-off-by: Werner Koch diff --git a/lang/cpp/src/Makefile.am b/lang/cpp/src/Makefile.am index 188585a..e65a875 100644 --- a/lang/cpp/src/Makefile.am +++ b/lang/cpp/src/Makefile.am @@ -25,7 +25,7 @@ lib_LTLIBRARIES = libgpgmepp.la main_sources = \ exception.cpp context.cpp key.cpp trustitem.cpp data.cpp callbacks.cpp \ - eventloopinteractor.cpp editinteractor.cpp assuanresult.cpp \ + eventloopinteractor.cpp editinteractor.cpp \ keylistresult.cpp keygenerationresult.cpp importresult.cpp \ decryptionresult.cpp verificationresult.cpp \ signingresult.cpp encryptionresult.cpp \ @@ -36,7 +36,7 @@ main_sources = \ vfsmountresult.cpp configuration.cpp tofuinfo.cpp gpgmepp_headers = \ - assuanresult.h configuration.h context.h data.h decryptionresult.h \ + configuration.h context.h data.h decryptionresult.h \ defaultassuantransaction.h editinteractor.h encryptionresult.h \ engineinfo.h error.h eventloopinteractor.h exception.h global.h \ gpgadduserideditinteractor.h gpgagentgetinfoassuantransaction.h \ diff --git a/lang/cpp/src/assuanresult.cpp b/lang/cpp/src/assuanresult.cpp deleted file mode 100644 index 3d6d0a3..0000000 --- a/lang/cpp/src/assuanresult.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - assuanresult.cpp - wraps a gpgme assuan result - Copyright (C) 2009 Klar?lvdalens Datakonsult AB - - This file is part of GPGME++. - - GPGME++ is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - GPGME++ 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 Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with GPGME++; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include -#include "result_p.h" - -#include - -#include - -using namespace GpgME; - -class AssuanResult::Private -{ -public: - explicit Private(const gpgme_assuan_result_t r) - { - if (!r) { - return; - } - error = r->err; - } - - gpgme_error_t error; -}; - -AssuanResult::AssuanResult(gpgme_ctx_t ctx, int error) - : Result(error), d() -{ - init(ctx); -} - -AssuanResult::AssuanResult(gpgme_ctx_t ctx, const Error &error) - : Result(error), d() -{ - init(ctx); -} - -void AssuanResult::init(gpgme_ctx_t ctx) -{ - (void)ctx; - if (!ctx) { - return; - } - gpgme_assuan_result_t res = gpgme_op_assuan_result(ctx); - if (!res) { - return; - } - d.reset(new Private(res)); -} - -make_standard_stuff(AssuanResult) - -Error AssuanResult::assuanError() const -{ - if (d) { - return Error(d->error); - } - return Error(); -} - -std::ostream &GpgME::operator<<(std::ostream &os, const AssuanResult &result) -{ - os << "GpgME::AssuanResult("; - if (!result.isNull()) { - os << "\n error: " << result.error() - << "\n assuanError: " << result.assuanError() - << "\n"; - } - return os << ')'; -} diff --git a/lang/cpp/src/assuanresult.h b/lang/cpp/src/assuanresult.h deleted file mode 100644 index e59b5ac..0000000 --- a/lang/cpp/src/assuanresult.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - assuanresult.h - wraps a gpgme assuan result - Copyright (C) 2009 Klar?lvdalens Datakonsult AB - Author: Marc Mutz - - This file is part of GPGME++. - - GPGME++ is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - GPGME++ 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 Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with GPGME++; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __GPGMEPP_ASSUANRESULT_H__ -#define __GPGMEPP_ASSUANRESULT_H__ - -#include "gpgmefw.h" -#include "result.h" -#include "gpgmepp_export.h" - -#include - -#include -#include -#include - -namespace GpgME -{ - -class Error; - -class GPGMEPP_EXPORT AssuanResult : public Result -{ -public: - AssuanResult(); - AssuanResult(gpgme_ctx_t ctx, int error); - AssuanResult(gpgme_ctx_t ctx, const Error &error); - explicit AssuanResult(const Error &err); - - const AssuanResult &operator=(AssuanResult other) - { - swap(other); - return *this; - } - - void swap(AssuanResult &other) - { - Result::swap(other); - using std::swap; - swap(this->d, other.d); - } - - bool isNull() const; - - Error assuanError() const; - - class Private; -private: - void init(gpgme_ctx_t ctx); - std::shared_ptr d; -}; - -GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const AssuanResult &result); - -} - -GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(AssuanResult) - -#endif // __GPGMEPP_ASSUANRESULT_H__ diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 11080cf..4e66d3b 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -801,26 +800,36 @@ static gpgme_error_t assuan_transaction_status_callback(void *opaque, const char return t->status(status, a.c_str()).encodedError(); } -AssuanResult Context::assuanTransact(const char *command) +Error Context::assuanTransact(const char *command) { return assuanTransact(command, std::unique_ptr(new DefaultAssuanTransaction)); } -AssuanResult Context::assuanTransact(const char *command, std::unique_ptr transaction) +Error Context::assuanTransact(const char *command, std::unique_ptr transaction) { + gpgme_error_t err, operr; + d->lastop = Private::AssuanTransact; d->lastAssuanTransaction = std::move(transaction); if (!d->lastAssuanTransaction.get()) { - return AssuanResult(Error(d->lasterr = make_error(GPG_ERR_INV_ARG))); + return Error(d->lasterr = make_error(GPG_ERR_INV_ARG)); } - d->lasterr = gpgme_op_assuan_transact(d->ctx, command, - assuan_transaction_data_callback, - d->lastAssuanTransaction.get(), - assuan_transaction_inquire_callback, - d, // sic! - assuan_transaction_status_callback, - d->lastAssuanTransaction.get()); - return AssuanResult(d->ctx, d->lasterr); + err = gpgme_op_assuan_transact_ext + (d->ctx, + command, + assuan_transaction_data_callback, + d->lastAssuanTransaction.get(), + assuan_transaction_inquire_callback, + d, + assuan_transaction_status_callback, + d->lastAssuanTransaction.get(), + &operr); + + if (!err) + err = operr; + d->lasterr = err; + + return Error(d->lasterr); } Error Context::startAssuanTransaction(const char *command) @@ -830,27 +839,26 @@ Error Context::startAssuanTransaction(const char *command) Error Context::startAssuanTransaction(const char *command, std::unique_ptr transaction) { + gpgme_error_t err; + d->lastop = Private::AssuanTransact; d->lastAssuanTransaction = std::move(transaction); if (!d->lastAssuanTransaction.get()) { return Error(d->lasterr = make_error(GPG_ERR_INV_ARG)); } - return Error(d->lasterr = gpgme_op_assuan_transact_start(d->ctx, command, - assuan_transaction_data_callback, - d->lastAssuanTransaction.get(), - assuan_transaction_inquire_callback, - d, // sic! - assuan_transaction_status_callback, - d->lastAssuanTransaction.get())); -} + err = gpgme_op_assuan_transact_start + (d->ctx, + command, + assuan_transaction_data_callback, + d->lastAssuanTransaction.get(), + assuan_transaction_inquire_callback, + d, + assuan_transaction_status_callback, + d->lastAssuanTransaction.get()); -AssuanResult Context::assuanResult() const -{ - if (d->lastop & Private::AssuanTransact) { - return AssuanResult(d->ctx, d->lasterr); - } else { - return AssuanResult(); - } + d->lasterr = err; + + return Error(d->lasterr); } AssuanTransaction *Context::lastAssuanTransaction() const diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 29eba91..6518d4c 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -46,7 +46,6 @@ class EventLoopInteractor; class EditInteractor; class AssuanTransaction; -class AssuanResult; class KeyListResult; class KeyGenerationResult; class ImportResult; @@ -240,11 +239,10 @@ public: // Assuan Transactions // - AssuanResult assuanTransact(const char *command, std::unique_ptr transaction); - AssuanResult assuanTransact(const char *command); + GpgME::Error assuanTransact(const char *command, std::unique_ptr transaction); + GpgME::Error assuanTransact(const char *command); GpgME::Error startAssuanTransaction(const char *command, std::unique_ptr transaction); GpgME::Error startAssuanTransaction(const char *command); - AssuanResult assuanResult() const; AssuanTransaction *lastAssuanTransaction() const; std::unique_ptr takeLastAssuanTransaction(); diff --git a/lang/cpp/src/vfsmountresult.h b/lang/cpp/src/vfsmountresult.h index abdd655..b46eeb1 100644 --- a/lang/cpp/src/vfsmountresult.h +++ b/lang/cpp/src/vfsmountresult.h @@ -73,4 +73,4 @@ GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const VfsMountResult & GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(VfsMountResult) -#endif // __GPGMEPP_ASSUANRESULT_H__ +#endif // __GPGMEPP_VFSMOUNTRESULT_H__ ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/Makefile.am | 4 +- lang/cpp/src/assuanresult.cpp | 90 ------------------------------------------- lang/cpp/src/assuanresult.h | 79 ------------------------------------- lang/cpp/src/context.cpp | 62 ++++++++++++++++------------- lang/cpp/src/context.h | 6 +-- lang/cpp/src/vfsmountresult.h | 2 +- 6 files changed, 40 insertions(+), 203 deletions(-) delete mode 100644 lang/cpp/src/assuanresult.cpp delete mode 100644 lang/cpp/src/assuanresult.h hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 24 15:51:32 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Aug 2016 15:51:32 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-6-g460568d 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 460568d341851ac79dd100e00e4eafcac1318148 (commit) via 95e9a97b32623eeab03cb8e86a00f810c18bcd5f (commit) from 54245979e691129ed9d3a6c642087fb8d3227449 (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 460568d341851ac79dd100e00e4eafcac1318148 Author: Werner Koch Date: Wed Aug 24 15:48:21 2016 +0200 wks: Add command --supported to gpg-wks-client. * tools/gpg-wks-client.c (aSupported): New. (opts): Add --supported. (parse_arguments): Ditto. (main): Call command_supported. (command_supported): New. Signed-off-by: Werner Koch diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 2c9cc4f..34b26ea 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -49,6 +49,7 @@ enum cmd_and_opt_values oDebug = 500, + aSupported, aCreate, aReceive, aRead, @@ -64,6 +65,8 @@ enum cmd_and_opt_values static ARGPARSE_OPTS opts[] = { ARGPARSE_group (300, ("@Commands:\n ")), + ARGPARSE_c (aSupported, "supported", + ("check whether provider supports WKS")), ARGPARSE_c (aCreate, "create", ("create a publication request")), ARGPARSE_c (aReceive, "receive", @@ -98,6 +101,7 @@ static struct debug_flags_s debug_flags [] = static void wrong_args (const char *text) GPGRT_ATTR_NORETURN; +static gpg_error_t command_supported (char *userid); static gpg_error_t command_send (const char *fingerprint, char *userid); static gpg_error_t process_confirmation_request (estream_t msg); static gpg_error_t command_receive_cb (void *opaque, @@ -174,6 +178,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts) opt.output = pargs->r.ret_str; break; + case aSupported: case aCreate: case aReceive: case aRead: @@ -237,6 +242,14 @@ main (int argc, char **argv) /* Run the selected command. */ switch (cmd) { + case aSupported: + if (argc != 1) + wrong_args ("--supported USER-ID"); + err = command_supported (argv[0]); + if (err && gpg_err_code (err) != GPG_ERR_FALSE) + log_error ("checking support failed: %s\n", gpg_strerror (err)); + break; + case aCreate: if (argc != 2) wrong_args ("--create FINGERPRINT USER-ID"); @@ -381,6 +394,48 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec) +/* Check whether the provider supports the WKS protocol. */ +static gpg_error_t +command_supported (char *userid) +{ + gpg_error_t err; + char *addrspec = NULL; + char *submission_to = NULL; + + addrspec = mailbox_from_userid (userid); + if (!addrspec) + { + log_error (_("\"%s\" is not a proper mail address\n"), userid); + err = gpg_error (GPG_ERR_INV_USER_ID); + goto leave; + } + + /* Get the submission address. */ + err = wkd_get_submission_address (addrspec, &submission_to); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_NO_DATA + || gpg_err_code (err) == GPG_ERR_UNKNOWN_HOST) + { + if (opt.verbose) + log_info ("provider for '%s' does NOT support WKS (%s)\n", + addrspec, gpg_strerror (err)); + err = gpg_error (GPG_ERR_FALSE); + log_inc_errorcount (); + } + goto leave; + } + if (opt.verbose) + log_info ("provider for '%s' supports WKS\n", addrspec); + + leave: + xfree (submission_to); + xfree (addrspec); + return err; +} + + + /* Locate the key by fingerprint and userid and send a publication * request. */ static gpg_error_t commit 95e9a97b32623eeab03cb8e86a00f810c18bcd5f Author: Werner Koch Date: Wed Aug 24 15:31:44 2016 +0200 doc: Some additional source comments -- diff --git a/common/mbox-util.c b/common/mbox-util.c index c451198..9072275 100644 --- a/common/mbox-util.c +++ b/common/mbox-util.c @@ -18,6 +18,10 @@ * along with this program; if not, see . */ +/* NB: GPGME uses the same code to reflect our idea on how to extract + * a mail address from a user id. + */ + #include #include #include diff --git a/doc/DETAILS b/doc/DETAILS index dc8ba1f..332e686 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -701,7 +701,8 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: This status identifies the key and the userid for all following Tofu information. The fingerprint is the fingerprint of the primary key and the mbox is in general the addr-spec part of the - userid encoded in UTF-8 and percent escaped. + userid encoded in UTF-8 and percent escaped. The fingerprint is + indentical for all TOFU_USER lines up to a NEWSIG line. *** TOFU_STATS 0 [ [ ]] ----------------------------------------------------------------------- Summary of changes: common/mbox-util.c | 4 ++++ doc/DETAILS | 3 ++- tools/gpg-wks-client.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 24 16:07:57 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Aug 2016 16:07:57 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-304-g1eefc2d 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 1eefc2d43c0adb2ce516f8e3509ace2fb562e401 (commit) from e20b0f0201543834f15c5d50cd3b2ece69a35d70 (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 1eefc2d43c0adb2ce516f8e3509ace2fb562e401 Author: Werner Koch Date: Wed Aug 24 16:04:54 2016 +0200 core: Set the 'encrcount' field in gpgme_tofu_info_t. * src/verify.c (parse_tofu_stats): Set ENCRCOUNT field. Signed-off-by: Werner Koch diff --git a/src/verify.c b/src/verify.c index 075f1d6..e573b01 100644 --- a/src/verify.c +++ b/src/verify.c @@ -755,7 +755,7 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol) /* Parse a TOFU_STATS line and store it in the last tofu info of SIG. * - * TOFU_STATS 0 [ [ ]] + * TOFU_STATS [ [ ]] */ static gpgme_error_t parse_tofu_stats (gpgme_signature_t sig, char *args) @@ -790,7 +790,13 @@ parse_tofu_stats (gpgme_signature_t sig, char *args) uval = USHRT_MAX; ti->signcount = uval; - /* We skip the 0, which is RFU. */ + /* Parse the encr-count. */ + err = _gpgme_strtoul_field (field[2], &uval); + if (err) + return trace_gpg_error (GPG_ERR_INV_ENGINE); + if (uval > USHRT_MAX) + uval = USHRT_MAX; + ti->encrcount = uval; if (nfields == 3) return 0; /* All mandatory fields parsed. */ ----------------------------------------------------------------------- Summary of changes: src/verify.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 24 19:59:21 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Aug 2016 19:59:21 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-8-g0f1f02a 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 0f1f02acc1cdcc2cf74a97b05507bb1f062f8af2 (commit) via 5eb2682686b32bd82096924eeabd0c5bd347adfd (commit) from 460568d341851ac79dd100e00e4eafcac1318148 (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 0f1f02acc1cdcc2cf74a97b05507bb1f062f8af2 Author: Werner Koch Date: Wed Aug 24 19:56:14 2016 +0200 gpg: Change TOFU_STATS to return timestamps. * g10/tofu.c (write_stats_status): Add arg FP to print a colon formated line. Adjust for changed TOFU_STATS interface. (show_statistics): Let the query return timestamps and use gnupg_get-time to compute the "time ago" values. Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 332e686..454f2e3 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -60,6 +60,7 @@ described here. - pkd :: Public key data [*] - grp :: Keygrip - rvk :: Revocation key + - tfs :: TOFU statistics [*] - tru :: Trust database information [*] - spk :: Signature subpacket [*] - cfg :: Configuration data [*] @@ -230,6 +231,20 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: !--------- index (eg. DSA goes from 0 to 3: p,q,g,y) #+end_example +*** TFS - TOFU statistics + + This field may follows a UID record to convey information about + the TOFU database. The information is similar to a TOFU_STATS + status line. + + - Field 2 :: tfs record version (must be 1) + - Field 3 :: validity - A number with validity code. + - Field 4 :: signcount - The number of signatures seen. + - Field 5 :: encrcount - The number of encryptions done. + - Field 6 :: policy - A string with the policy + - Field 7 :: first-seen - a timestamp or 0 if not known. + - Field 8 :: most-recent-seen - a timestamp or 0 if not known. + *** TRU - Trust database information Example for a "tru" trust base record: #+begin_example @@ -723,9 +738,9 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: - ask :: Policy is "ask" - unknown :: Policy is not known. - TM1 gives the number of seconds since the the first messages was - verified. TM2 gives the number of seconds since the most recent - message was verified. + TM1 ist the time the first messages was verified. TM2 is the time + the most recent message was verified. Both may either be seconds + since Epoch or an ISO time string (yyyymmddThhmmss). *** TOFU_STATS_SHORT diff --git a/g10/tofu.c b/g10/tofu.c index ef14e85..29318c7 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1872,14 +1872,13 @@ time_ago_str (long long int t) } -/* Write TOFU_STATS status line. */ +/* If FP is NULL, write TOFU_STATS status line. If FP is not NULL + * write a "tfs" record to that stream. */ static void -write_stats_status (long messages, enum tofu_policy policy, - long first_seen_ago, long most_recent_seen_ago) +write_stats_status (estream_t fp, long messages, enum tofu_policy policy, + unsigned long first_seen, + unsigned long most_recent_seen) { - char numbuf1[35]; - char numbuf2[35]; - char numbuf3[35]; const char *validity; if (messages < 1) @@ -1891,19 +1890,33 @@ write_stats_status (long messages, enum tofu_policy policy, else validity = "4"; /* Key with a lot of history. */ - snprintf (numbuf1, sizeof numbuf1, " %ld", messages); - *numbuf2 = *numbuf3 = 0; - if (first_seen_ago >= 0 && most_recent_seen_ago >= 0) + if (fp) { - snprintf (numbuf2, sizeof numbuf2, " %ld", first_seen_ago); - snprintf (numbuf3, sizeof numbuf3, " %ld", most_recent_seen_ago); + es_fprintf (fp, "tfs:1:%s:%ld:0:%s:%lu:%lu:\n", + validity, messages, + tofu_policy_str (policy), + first_seen, most_recent_seen); } + else + { + char numbuf1[35]; + char numbuf2[35]; + char numbuf3[35]; + + snprintf (numbuf1, sizeof numbuf1, " %ld", messages); + *numbuf2 = *numbuf3 = 0; + if (first_seen && most_recent_seen) + { + snprintf (numbuf2, sizeof numbuf2, " %lu", first_seen); + snprintf (numbuf3, sizeof numbuf3, " %lu", most_recent_seen); + } - write_status_strings (STATUS_TOFU_STATS, - validity, numbuf1, " 0", - " ", tofu_policy_str (policy), - numbuf2, numbuf3, - NULL); + write_status_strings (STATUS_TOFU_STATS, + validity, numbuf1, " 0", + " ", tofu_policy_str (policy), + numbuf2, numbuf3, + NULL); + } } static void @@ -1920,8 +1933,7 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, rc = gpgsql_exec_printf (dbs->db, strings_collect_cb, &strlist, &err, - "select count (*), strftime('%%s','now') - min (signatures.time),\n" - " strftime('%%s','now') - max (signatures.time)\n" + "select count (*), min (signatures.time), max (signatures.time)\n" " from signatures\n" " left join bindings on signatures.binding = bindings.oid\n" " where fingerprint = %Q and email = %Q and sig_digest %s%s%s;", @@ -1939,6 +1951,7 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, goto out; } + write_status_text_and_buffer (STATUS_TOFU_USER, fingerprint, email, strlen (email), 0); @@ -1946,13 +1959,14 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, { log_info (_("Have never verified a message signed by key %s!\n"), fingerprint_pp); - write_stats_status (0, TOFU_POLICY_NONE, -1, -1); + write_stats_status (NULL, 0, TOFU_POLICY_NONE, 0, 0); } else { + unsigned long now = gnupg_get_time (); signed long messages; - signed long first_seen_ago; - signed long most_recent_seen_ago; + unsigned long first_seen; + unsigned long most_recent_seen; log_assert (strlist_length (strlist) == 3); @@ -1960,19 +1974,32 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, if (messages == 0 && *strlist->next->d == '\0') { /* min(NULL) => NULL => "". */ - first_seen_ago = -1; - most_recent_seen_ago = -1; + first_seen = 0; + most_recent_seen = 0; } else { - string_to_long (&first_seen_ago, strlist->next->d, -1, __LINE__); - string_to_long (&most_recent_seen_ago, strlist->next->next->d, -1, - __LINE__); + string_to_ulong (&first_seen, strlist->next->d, -1, __LINE__); + if (first_seen > now) + { + log_debug ("time-warp - tofu DB has a future value (%lu, %lu)\n", + first_seen, now); + first_seen = now; + } + string_to_ulong (&most_recent_seen, strlist->next->next->d, -1, + __LINE__); + if (most_recent_seen > now) + { + log_debug ("time-warp - tofu DB has a future value (%lu, %lu)\n", + most_recent_seen, now); + most_recent_seen = now; + } + } - if (messages == -1 || first_seen_ago == -1) + if (messages == -1 || !first_seen) { - write_stats_status (0, TOFU_POLICY_NONE, -1, -1); + write_stats_status (NULL, 0, TOFU_POLICY_NONE, 0, 0); log_info (_("Failed to collect signature statistics for \"%s\"\n" "(key %s)\n"), user_id, fingerprint_pp); @@ -1983,8 +2010,8 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, estream_t fp; char *msg; - write_stats_status (messages, policy, - first_seen_ago, most_recent_seen_ago); + write_stats_status (NULL, messages, policy, + first_seen, most_recent_seen); fp = es_fopenmem (0, "rw,samethread"); if (! fp) @@ -1999,7 +2026,7 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, } else { - char *first_seen_ago_str = time_ago_str (first_seen_ago); + char *first_seen_ago_str = time_ago_str (now - first_seen); /* TRANSLATORS: The final %s is replaced by a string like "7 months, 1 day, 5 minutes, 0 seconds". */ @@ -2013,7 +2040,7 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, if (messages > 1) { - char *tmpstr = time_ago_str (most_recent_seen_ago); + char *tmpstr = time_ago_str (now - most_recent_seen); es_fputs (" ", fp); es_fprintf (fp, _("The most recent message was" " verified %s ago."), tmpstr); commit 5eb2682686b32bd82096924eeabd0c5bd347adfd Author: Werner Koch Date: Wed Aug 24 18:37:55 2016 +0200 common: Guarantee that gnupg_get_time does not return an error. * common/gettime.c (gnupg_get_time): Abor if time() failed. (gnupg_get_isotime): Remove now useless check. (make_timestamp): Remove check becuase we already checked this modulo the faked time thing. -- In reality a call foo = time (NULL) can never fail because the only defined error is EFAULT, but we don't provide a buffer. Signed-off-by: Werner Koch diff --git a/common/gettime.c b/common/gettime.c index dd9c196..9702bbc 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -60,6 +60,9 @@ time_t gnupg_get_time () { time_t current = time (NULL); + if (current == (time_t)(-1)) + log_fatal ("time() failed\n"); + if (timemode == NORMAL) return current; else if (timemode == FROZEN) @@ -99,22 +102,16 @@ void gnupg_get_isotime (gnupg_isotime_t timebuf) { time_t atime = gnupg_get_time (); + struct tm *tp; + struct tm tmbuf; - if (atime == (time_t)(-1)) + tp = gnupg_gmtime (&atime, &tmbuf); + if (!tp) *timebuf = 0; else - { - struct tm *tp; - struct tm tmbuf; - - tp = gnupg_gmtime (&atime, &tmbuf); - if (!tp) - *timebuf = 0; - else - snprintf (timebuf, 16, "%04d%02d%02dT%02d%02d%02d", - 1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - } + snprintf (timebuf, 16, "%04d%02d%02dT%02d%02d%02d", + 1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); } @@ -164,9 +161,6 @@ u32 make_timestamp (void) { time_t t = gnupg_get_time (); - - if (t == (time_t)-1) - log_fatal ("gnupg_get_time() failed\n"); return (u32)t; } ----------------------------------------------------------------------- Summary of changes: common/gettime.c | 26 +++++++--------- doc/DETAILS | 21 +++++++++++-- g10/tofu.c | 91 ++++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 87 insertions(+), 51 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 24 20:13:38 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Aug 2016 20:13:38 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-305-g38798fe 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 38798fee5b539d6153a8a7856152959412ee59b5 (commit) from 1eefc2d43c0adb2ce516f8e3509ace2fb562e401 (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 38798fee5b539d6153a8a7856152959412ee59b5 Author: Werner Koch Date: Wed Aug 24 20:10:36 2016 +0200 core: Adjust for TOFU_STATS change in gnupg 2.1.16. * src/gpgme.h.in (_gpgme_tofu_info): Change 'firstseen' and 'lastseen' to a timestamp value. * src/verify.c (parse_tofu_stats): Do not cap these values at UINT_MAX. -- Using an unsigned long here is okay: We will never get an error and even on machines where unsigned long is 32 bit (e.g. Windows64) this allows us to operate until 2106. By then Windows will be a footnote in history or Windows128 has changed that type to something larger than 32 bit ;-) Signed-off-by: Werner Koch diff --git a/src/gpgme.h.in b/src/gpgme.h.in index c07cac8..79a7b9f 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -648,10 +648,10 @@ struct _gpgme_tofu_info /* Number of encryptions done with this binding. Capped at USHRT_MAX. */ unsigned short encrcount; - /* Number of seconds since the first and the most recently seen - * message was verified. */ - unsigned int firstseen; - unsigned int lastseen; + /* Number of seconds since Epoch when the first and the most + * recently seen message were verified. 0 means unknown. */ + unsigned long firstseen; + unsigned long lastseen; /* If non-NULL a human readable string summarizing the TOFU data. */ char *description; diff --git a/src/verify.c b/src/verify.c index e573b01..92eb333 100644 --- a/src/verify.c +++ b/src/verify.c @@ -818,20 +818,16 @@ parse_tofu_stats (gpgme_signature_t sig, char *args) if (nfields == 4) return 0; /* No more optional fields. */ - /* Parse first and last seen (none or both are required). */ + /* Parse first and last seen timestamps (none or both are required). */ if (nfields < 6) return trace_gpg_error (GPG_ERR_INV_ENGINE); /* "tm2" missing. */ err = _gpgme_strtoul_field (field[4], &uval); if (err) return trace_gpg_error (GPG_ERR_INV_ENGINE); - if (uval > UINT_MAX) - uval = UINT_MAX; ti->firstseen = uval; err = _gpgme_strtoul_field (field[5], &uval); if (err) return trace_gpg_error (GPG_ERR_INV_ENGINE); - if (uval > UINT_MAX) - uval = UINT_MAX; ti->lastseen = uval; return 0; ----------------------------------------------------------------------- Summary of changes: src/gpgme.h.in | 8 ++++---- src/verify.c | 6 +----- 2 files changed, 5 insertions(+), 9 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 09:40:50 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 25 Aug 2016 09:40:50 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-9-g19d12be 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 19d12be3cea5b4ee8153287a2f2442913a5e07a1 (commit) from 0f1f02acc1cdcc2cf74a97b05507bb1f062f8af2 (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 19d12be3cea5b4ee8153287a2f2442913a5e07a1 Author: Werner Koch Date: Thu Aug 25 09:26:36 2016 +0200 gpg: New option --with-tofu-info. * g10/gpg.c (oWithTofuInfo): New. (opts): Add --with-tofu-info. (main): Set opt.with_tofu_info. * g10/options.h (struct opt): Add field WITH_TOFU_INFO. * g10/tofu.c (show_statistics): Add optional arg OUTFP and enter special mode if not NULL. Change all callers. (tofu_write_tfs_record): New. * g10/keylist.c (list_keyblock_colon): Do not print the tofu policy as part of the "uid" record. Print a new "tfs" record if the new option is set. * tests/openpgp/tofu.scm (getpolicy): Change from UID to TFS record. -- A separate option is required to avoid slowing down key listings. Foer example the current code takes for a keylisting in tofu+pgp mode 17 seconds while it takes more than 5 minutes if the option is used. Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 454f2e3..cf779d2 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -52,7 +52,7 @@ described here. - sub :: Subkey (secondary key) - sec :: Secret key - ssb :: Secret subkey (secondary key) - - uid :: User id (only field 10 is used). + - uid :: User id - uat :: User attribute (same as user id except for field 10). - sig :: Signature - rev :: Revocation signature @@ -214,10 +214,6 @@ described here. For pub, sub, sec, and ssb records this field is used for the ECC curve name. -*** Field 18 - TOFU Policy - - This is the TOFU policy. It is either good, bad, unknown, ask or - auto. This is only shows for uid records. ** Special fields diff --git a/g10/gpg.c b/g10/gpg.c index e02efe4..3193e74 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -193,6 +193,11 @@ enum cmd_and_opt_values oWithKeygrip, oWithSecret, oWithWKDHash, + oWithColons, + oWithKeyData, + oWithTofuInfo, + oWithSigList, + oWithSigCheck, oAnswerYes, oAnswerNo, oKeyring, @@ -259,10 +264,6 @@ enum cmd_and_opt_values oNoOptions, oNoBatch, oHomedir, - oWithColons, - oWithKeyData, - oWithSigList, - oWithSigCheck, oSkipVerify, oSkipHiddenRecipients, oNoSkipHiddenRecipients, @@ -699,6 +700,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_n (oNoBatch, "no-batch", "@"), ARGPARSE_s_n (oWithColons, "with-colons", "@"), + ARGPARSE_s_n (oWithTofuInfo,"with-tofu-info", "@"), ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"), ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"), ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"), @@ -2650,6 +2652,8 @@ main (int argc, char **argv) case oHomedir: break; case oNoBatch: opt.batch = 0; break; + case oWithTofuInfo: opt.with_tofu_info = 1; break; + case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/ case oWithColons: opt.with_colons=':'; break; diff --git a/g10/gpgv.c b/g10/gpgv.c index 4ef3e8b..1f2cecb 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -661,6 +661,17 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, } gpg_error_t +tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, + PKT_public_key *pk, const char *user_id) +{ + (void)ctrl; + (void)fp; + (void)pk; + (void)user_id; + return gpg_error (GPG_ERR_GENERAL); +} + +gpg_error_t tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id, enum tofu_policy *policy) { diff --git a/g10/keylist.c b/g10/keylist.c index 59344b2..a34ef64 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1289,8 +1289,8 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, char *str; PKT_user_id *uid = node->pkt->pkt.user_id; - if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL) - dump_attribs (node->pkt->pkt.user_id, pk); + if (attrib_fp && uid->attrib_data != NULL) + dump_attribs (uid, pk); /* * Fixme: We need a valid flag here too */ @@ -1326,18 +1326,16 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len); else es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL); - es_fprintf (es_stdout, "::::::::"); - if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP) - { -#ifdef USE_TOFU - enum tofu_policy policy; - if (! tofu_get_policy (ctrl, pk, uid, &policy) - && policy != TOFU_POLICY_NONE) - es_fprintf (es_stdout, "%s", tofu_policy_str (policy)); -#endif /*USE_TOFU*/ - } es_putc (':', es_stdout); es_putc ('\n', es_stdout); +#ifdef USE_TOFU + if (!uid->attrib_data && opt.with_tofu_info + && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)) + { + /* Print a "tfs" record. */ + tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name); + } +#endif /*USE_TOFU*/ } else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) { diff --git a/g10/options.h b/g10/options.h index 6b8f649..544be60 100644 --- a/g10/options.h +++ b/g10/options.h @@ -81,6 +81,7 @@ struct int with_fingerprint; /* Option --with-fingerprint active. */ int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */ int with_keygrip; /* Option --with-keygrip active. */ + int with_tofu_info; /* Option --with-tofu_info active. */ int with_secret; /* Option --with-secret active. */ int with_wkd_hash; /* Option --with-wkd-hash. */ int fingerprint; /* list fingerprints */ diff --git a/g10/test-stubs.c b/g10/test-stubs.c index c5f2f79..55351b8 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -474,6 +474,17 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, } gpg_error_t +tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, + PKT_public_key *pk, const char *user_id) +{ + (void)ctrl; + (void)fp; + (void)pk; + (void)user_id; + return gpg_error (GPG_ERR_GENERAL); +} + +gpg_error_t tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id, enum tofu_policy *policy) { diff --git a/g10/tofu.c b/g10/tofu.c index 29318c7..9d562c2 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1919,10 +1919,13 @@ write_stats_status (estream_t fp, long messages, enum tofu_policy policy, } } + +/* Note: If OUTFP is not NULL, this function merely prints a "tfs" record + * to OUTFP. In this case USER_ID is not required. */ static void show_statistics (tofu_dbs_t dbs, const char *fingerprint, const char *email, const char *user_id, - const char *sig_exclude) + const char *sig_exclude, estream_t outfp) { char *fingerprint_pp; int rc; @@ -1951,15 +1954,16 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, goto out; } - - write_status_text_and_buffer (STATUS_TOFU_USER, fingerprint, - email, strlen (email), 0); + if (!outfp) + write_status_text_and_buffer (STATUS_TOFU_USER, fingerprint, + email, strlen (email), 0); if (! strlist) { - log_info (_("Have never verified a message signed by key %s!\n"), - fingerprint_pp); - write_stats_status (NULL, 0, TOFU_POLICY_NONE, 0, 0); + if (!outfp) + log_info (_("Have never verified a message signed by key %s!\n"), + fingerprint_pp); + write_stats_status (outfp, 0, TOFU_POLICY_NONE, 0, 0); } else { @@ -1999,10 +2003,17 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, if (messages == -1 || !first_seen) { - write_stats_status (NULL, 0, TOFU_POLICY_NONE, 0, 0); - log_info (_("Failed to collect signature statistics for \"%s\"\n" - "(key %s)\n"), - user_id, fingerprint_pp); + write_stats_status (outfp, 0, TOFU_POLICY_NONE, 0, 0); + if (!outfp) + log_info (_("Failed to collect signature statistics for \"%s\"\n" + "(key %s)\n"), + user_id, fingerprint_pp); + } + else if (outfp) + { + write_stats_status (outfp, messages, + get_policy (dbs, fingerprint, email, NULL), + first_seen, most_recent_seen); } else { @@ -2010,7 +2021,8 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, estream_t fp; char *msg; - write_stats_status (NULL, messages, policy, + write_stats_status (NULL, messages, + policy, first_seen, most_recent_seen); fp = es_fopenmem (0, "rw,samethread"); @@ -2313,7 +2325,7 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, /* It's only appropriate to show the statistics in an interactive context. */ show_statistics (dbs, fingerprint, email, user_id, - already_verified ? NULL : sig_digest); + already_verified ? NULL : sig_digest, NULL); xfree (email); xfree (fingerprint); @@ -2385,6 +2397,38 @@ tofu_wot_trust_combine (int tofu_base, int wot_base) } +/* Write a "tfs" record for a --with-colons listing. */ +gpg_error_t +tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, + PKT_public_key *pk, const char *user_id) +{ + gpg_error_t err; + tofu_dbs_t dbs; + char *fingerprint; + char *email; + + if (!*user_id) + return 0; /* No TOFU stats possible for an empty ID. */ + + dbs = opendbs (ctrl); + if (!dbs) + { + err = gpg_error (GPG_ERR_GENERAL); + log_error (_("error opening TOFU database: %s\n"), gpg_strerror (err)); + return err; + } + + fingerprint = hexfingerprint (pk, NULL, 0); + email = email_from_user_id (user_id); + + show_statistics (dbs, fingerprint, email, user_id, NULL, fp); + + xfree (email); + xfree (fingerprint); + return 0; +} + + /* Return the validity (TRUST_NEVER, etc.) of the binding . @@ -2429,7 +2473,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, trust_level = TRUST_UNDEFINED; if (may_ask && trust_level != TRUST_ULTIMATE) - show_statistics (dbs, fingerprint, email, user_id, NULL); + show_statistics (dbs, fingerprint, email, user_id, NULL, NULL); die: xfree (email); diff --git a/g10/tofu.h b/g10/tofu.h index e3ec819..d6854e9 100644 --- a/g10/tofu.h +++ b/g10/tofu.h @@ -88,6 +88,10 @@ int tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, interest when the trust model is tofu+pgp (TM_TOFU_PGP). */ int tofu_wot_trust_combine (int tofu, int wot); +/* Write a "tfs" record for a --with-colons listing. */ +gpg_error_t tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, + PKT_public_key *pk, const char *user_id); + /* Determine the validity (TRUST_NEVER, etc.) of the binding . If MAY_ASK is 1, then this function may interact with the user. If not, TRUST_UNKNOWN is returned. If an diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm index 2b302ba..448c253 100755 --- a/tests/openpgp/tofu.scm +++ b/tests/openpgp/tofu.scm @@ -46,11 +46,11 @@ ;; This function only supports keys with a single user id. (define (getpolicy keyid format . args) (let ((policy - (list-ref (assoc "uid" (gpg-with-colons + (list-ref (assoc "tfs" (gpg-with-colons `(--tofu-db-format ,format - --trust-model=tofu + --trust-model=tofu --with-tofu-info , at args - --list-keys ,keyid))) 17))) + --list-keys ,keyid))) 5))) (unless (member policy '("auto" "good" "unknown" "bad" "ask")) (error "Bad policy:" policy)) policy)) ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 6 +---- g10/gpg.c | 12 ++++++--- g10/gpgv.c | 11 ++++++++ g10/keylist.c | 22 +++++++-------- g10/options.h | 1 + g10/test-stubs.c | 11 ++++++++ g10/tofu.c | 72 ++++++++++++++++++++++++++++++++++++++++---------- g10/tofu.h | 4 +++ tests/openpgp/tofu.scm | 6 ++--- 9 files changed, 107 insertions(+), 38 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 11:41:33 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 25 Aug 2016 11:41:33 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-306-g9ee1039 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 9ee103957e4136337b92d238283f8ef30fd4a7c5 (commit) from 38798fee5b539d6153a8a7856152959412ee59b5 (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 9ee103957e4136337b92d238283f8ef30fd4a7c5 Author: Werner Koch Date: Thu Aug 25 11:38:03 2016 +0200 core: Add GPGME_KEYLIST_MODE_WITH_TOFU. * src/gpgme.h.in (GPGME_KEYLIST_MODE_WITH_TOFU): New. * src/engine-gpg.c (gpg_keylist_build_options): Use that. * src/keylist.c: Include limits.h. (parse_tfs_record): New. (keylist_colon_handler): Support TFS record. * tests/run-keylist.c: Include time.h. (isotimestr): New. (main): Add option --tofu. Print TOFU info. * tests/run-verify.c: Include time.h. (isotimestr): New. (print_result): Use isotimestr for TOFU dates. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 1294e0b..da331b4 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_] GPGME_STATUS_TOFU_STATS NEW. GPGME_STATUS_TOFU_STATS_LONG NEW. GPGME_STATUS_NOTATION_FLAGS NEW. + GPGME_KEYLIST_MODE_WITH_TOFU NEW. GPGME_DATA_TYPE_PGP_ENCRYPTED NEW. GPGME_DATA_TYPE_PGP_SIGNATURE NEW. GPGME_DATA_ENCODING_MIME NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 02551d9..dfc9548 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -2683,6 +2683,11 @@ signature notations on key signatures should be included in the listed keys. This only works if @code{GPGME_KEYLIST_MODE_SIGS} is also enabled. + at item GPGME_KEYLIST_MODE_WITH_TOFU +The @code{GPGME_KEYLIST_MODE_WITH_TOFU} symbol specifies that +information pertaining to the TOFU trust model should be included in +the listed keys. + @item GPGME_KEYLIST_MODE_WITH_SECRET The @code{GPGME_KEYLIST_MODE_WITH_SECRET} returns information about the presence of a corresponding secret key in a public key listing. A diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 3edac6c..7036ee0 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2338,8 +2338,13 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only, err = add_arg (gpg, "--with-fingerprint"); } + if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU) + && have_gpg_version (gpg, "2.1.16")) + err = add_arg (gpg, "--with-tofu-info"); + if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET)) err = add_arg (gpg, "--with-secret"); + if (!err && (mode & GPGME_KEYLIST_MODE_SIGS) && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS)) @@ -2348,6 +2353,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only, if (!err) err = add_arg (gpg, "show-sig-subpackets=\"20,26\""); } + if (!err) { if ( (mode & GPGME_KEYLIST_MODE_EXTERN) ) @@ -2379,6 +2385,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only, ? "--check-sigs" : "--list-keys")); } } + if (!err) err = add_arg (gpg, "--"); diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 79a7b9f..57f3446 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -411,6 +411,7 @@ gpgme_protocol_t; #define GPGME_KEYLIST_MODE_SIGS 4 #define GPGME_KEYLIST_MODE_SIG_NOTATIONS 8 #define GPGME_KEYLIST_MODE_WITH_SECRET 16 +#define GPGME_KEYLIST_MODE_WITH_TOFU 32 #define GPGME_KEYLIST_MODE_EPHEMERAL 128 #define GPGME_KEYLIST_MODE_VALIDATE 256 @@ -843,7 +844,7 @@ struct _gpgme_user_id * NULL is stored. */ char *address; - /* The malloced tofo information or NULL. */ + /* The malloced TOFU information or NULL. */ gpgme_tofu_info_t tofu; }; typedef struct _gpgme_user_id *gpgme_user_id_t; diff --git a/src/keylist.c b/src/keylist.c index 38ddd0c..9f1e68d 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -33,6 +33,7 @@ #include #include #include +#include /* Suppress warning for accessing deprecated member "class". */ #define _GPGME_IN_GPGME @@ -403,6 +404,84 @@ parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field) } +/* Parse a tfs record. */ +static gpg_error_t +parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield) +{ + gpg_error_t err; + gpgme_tofu_info_t ti; + unsigned long uval; + + /* We add only the first TOFU record in case future versions emit + * several. */ + if (uid->tofu) + return 0; + + /* Check that we have enough fields and that the version is supported. */ + if (nfield < 8 || atoi(field[1]) != 1) + return trace_gpg_error (GPG_ERR_INV_ENGINE); + + ti = calloc (1, sizeof *ti); + if (!ti) + return gpg_error_from_syserror (); + + /* Note that we allow a value of up to 7 which is what we can store + * in the ti->validity. */ + err = _gpgme_strtoul_field (field[2], &uval); + if (err || uval > 7) + goto inv_engine; + ti->validity = uval; + + /* Parse the sign-count. */ + err = _gpgme_strtoul_field (field[3], &uval); + if (err) + goto inv_engine; + if (uval > USHRT_MAX) + uval = USHRT_MAX; + ti->signcount = uval; + + /* Parse the encr-count. */ + err = _gpgme_strtoul_field (field[4], &uval); + if (err) + goto inv_engine; + if (uval > USHRT_MAX) + uval = USHRT_MAX; + ti->encrcount = uval; + + /* Parse the policy. */ + if (!strcmp (field[5], "none")) + ti->policy = GPGME_TOFU_POLICY_NONE; + else if (!strcmp (field[5], "auto")) + ti->policy = GPGME_TOFU_POLICY_AUTO; + else if (!strcmp (field[5], "good")) + ti->policy = GPGME_TOFU_POLICY_GOOD; + else if (!strcmp (field[5], "bad")) + ti->policy = GPGME_TOFU_POLICY_BAD; + else if (!strcmp (field[5], "ask")) + ti->policy = GPGME_TOFU_POLICY_ASK; + else /* "unknown" and invalid policy strings. */ + ti->policy = GPGME_TOFU_POLICY_UNKNOWN; + + /* Parse first and last seen timestamps. */ + err = _gpgme_strtoul_field (field[6], &uval); + if (err) + goto inv_engine; + ti->firstseen = uval; + err = _gpgme_strtoul_field (field[7], &uval); + if (err) + goto inv_engine; + ti->lastseen = uval; + + /* Ready. */ + uid->tofu = ti; + return 0; + + inv_engine: + free (ti); + return trace_gpg_error (GPG_ERR_INV_ENGINE); +} + + /* We have read an entire key into tmp_key and should now finish it. It is assumed that this releases tmp_key. */ static void @@ -426,7 +505,7 @@ keylist_colon_handler (void *priv, char *line) gpgme_ctx_t ctx = (gpgme_ctx_t) priv; enum { - RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_GRP, + RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP, RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK } rectype = RT_NONE; @@ -483,6 +562,8 @@ keylist_colon_handler (void *priv, char *line) rectype = RT_GRP; else if (!strcmp (field[0], "uid") && key) rectype = RT_UID; + else if (!strcmp (field[0], "tfs") && key) + rectype = RT_TFS; else if (!strcmp (field[0], "sub") && key) rectype = RT_SUB; else if (!strcmp (field[0], "ssb") && key) @@ -492,10 +573,10 @@ keylist_colon_handler (void *priv, char *line) else rectype = RT_NONE; - /* Only look at signatures immediately following a user ID. For - this, clear the user ID pointer when encountering anything but a - signature. */ - if (rectype != RT_SIG && rectype != RT_REV) + /* Only look at signature and trust info records immediately + following a user ID. For this, clear the user ID pointer when + encountering anything but a signature or trust record. */ + if (rectype != RT_SIG && rectype != RT_REV && rectype != RT_TFS) opd->tmp_uid = NULL; /* Only look at subpackets immediately following a signature. For @@ -695,6 +776,15 @@ keylist_colon_handler (void *priv, char *line) } break; + case RT_TFS: + if (opd->tmp_uid) + { + err = parse_tfs_record (opd->tmp_uid, field, fields); + if (err) + return err; + } + break; + case RT_FPR: /* Field 10 has the fingerprint (take only the first one). */ if (fields >= 10 && field[9] && *field[9]) diff --git a/tests/run-keylist.c b/tests/run-keylist.c index bae2dbb..00f874d 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -49,6 +50,7 @@ show_usage (int ex) " --local use GPGME_KEYLIST_MODE_LOCAL\n" " --extern use GPGME_KEYLIST_MODE_EXTERN\n" " --sigs use GPGME_KEYLIST_MODE_SIGS\n" + " --tofu use GPGME_KEYLIST_MODE_TOFU\n" " --sig-notations use GPGME_KEYLIST_MODE_SIG_NOTATIONS\n" " --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n" " --validate use GPGME_KEYLIST_MODE_VALIDATE\n" @@ -60,6 +62,26 @@ show_usage (int ex) } +static const char * +isotimestr (unsigned long value) +{ + time_t t; + static char buffer[25+5]; + struct tm *tp; + + if (!value) + return "none"; + t = value; + + tp = gmtime (&t); + snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d", + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + return buffer; +} + + + int main (int argc, char **argv) { @@ -120,6 +142,11 @@ main (int argc, char **argv) mode |= GPGME_KEYLIST_MODE_EXTERN; argc--; argv++; } + else if (!strcmp (*argv, "--tofu")) + { + mode |= GPGME_KEYLIST_MODE_WITH_TOFU; + argc--; argv++; + } else if (!strcmp (*argv, "--sigs")) { mode |= GPGME_KEYLIST_MODE_SIGS; @@ -181,6 +208,7 @@ main (int argc, char **argv) while (!(err = gpgme_op_keylist_next (ctx, &key))) { gpgme_user_id_t uid; + gpgme_tofu_info_t ti; int nuids; int nsub; @@ -233,24 +261,42 @@ main (int argc, char **argv) for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++) { printf ("userid %d: %s\n", nuids, nonnull(uid->uid)); - printf (" mbox %d: %s\n", nuids, nonnull(uid->address)); + printf (" mbox: %s\n", nonnull(uid->address)); if (uid->email && uid->email != uid->address) - printf (" email %d: %s\n", nuids, uid->email); + printf (" email: %s\n", uid->email); if (uid->name) - printf (" name %d: %s\n", nuids, uid->name); + printf (" name: %s\n", uid->name); if (uid->comment) - printf (" cmmnt %d: %s\n", nuids, uid->comment); - printf (" valid %d: %s\n", nuids, + printf (" cmmnt: %s\n", uid->comment); + printf (" valid: %s\n", uid->validity == GPGME_VALIDITY_UNKNOWN? "unknown": uid->validity == GPGME_VALIDITY_UNDEFINED? "undefined": uid->validity == GPGME_VALIDITY_NEVER? "never": uid->validity == GPGME_VALIDITY_MARGINAL? "marginal": uid->validity == GPGME_VALIDITY_FULL? "full": uid->validity == GPGME_VALIDITY_ULTIMATE? "ultimate": "[?]"); + if ((ti = uid->tofu)) + { + printf (" tofu: %u (%s)\n", ti->validity, + ti->validity == 0? "conflict" : + ti->validity == 1? "no history" : + ti->validity == 2? "little history" : + ti->validity == 3? "enough history" : + ti->validity == 4? "lot of history" : "?"); + printf (" policy: %u (%s)\n", ti->policy, + ti->policy == GPGME_TOFU_POLICY_NONE? "none" : + ti->policy == GPGME_TOFU_POLICY_AUTO? "auto" : + ti->policy == GPGME_TOFU_POLICY_GOOD? "good" : + ti->policy == GPGME_TOFU_POLICY_UNKNOWN? "unknown" : + ti->policy == GPGME_TOFU_POLICY_BAD? "bad" : + ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?"); + printf (" nsigs: %hu\n", ti->signcount); + printf (" nencr: %hu\n", ti->encrcount); + printf (" first: %s\n", isotimestr (ti->firstseen)); + printf (" last: %s\n", isotimestr (ti->lastseen)); + } } - - putchar ('\n'); if (import) diff --git a/tests/run-verify.c b/tests/run-verify.c index ef4dd32..3c18d3b 100644 --- a/tests/run-verify.c +++ b/tests/run-verify.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -36,6 +37,26 @@ static int verbose; + +static const char * +isotimestr (unsigned long value) +{ + time_t t; + static char buffer[25+5]; + struct tm *tp; + + if (!value) + return "none"; + t = value; + + tp = gmtime (&t); + snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d", + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + return buffer; +} + + static gpg_error_t status_cb (void *opaque, const char *keyword, const char *value) { @@ -177,8 +198,8 @@ print_result (gpgme_verify_result_t result) ti->policy == GPGME_TOFU_POLICY_BAD? "bad" : ti->policy == GPGME_TOFU_POLICY_ASK? "ask" : "?"); printf (" sigcount : %hu\n", ti->signcount); - printf (" firstseen: %u\n", ti->firstseen); - printf (" lastseen : %u\n", ti->lastseen); + printf (" firstseen: %s\n", isotimestr (ti->firstseen)); + printf (" lastseen : %s\n", isotimestr (ti->lastseen)); printf (" desc ....: "); print_description (nonnull (ti->description), 15); } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/gpgme.texi | 5 +++ src/engine-gpg.c | 7 ++++ src/gpgme.h.in | 3 +- src/keylist.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++--- tests/run-keylist.c | 60 +++++++++++++++++++++++++++---- tests/run-verify.c | 25 +++++++++++-- 7 files changed, 186 insertions(+), 15 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 11:42:06 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 25 Aug 2016 11:42:06 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-309-gde7b67f 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 de7b67f9b2e6bd43a036fa0bcc6a8ca4f5b10986 (commit) via abcd9a283ee8f81870622c8e1dbdc7aad38c0358 (commit) via ece8b02a839d6fc566fea7b6e59fabff164f6cf5 (commit) from 9ee103957e4136337b92d238283f8ef30fd4a7c5 (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 de7b67f9b2e6bd43a036fa0bcc6a8ca4f5b10986 Author: Andre Heinecke Date: Thu Aug 25 10:46:17 2016 +0200 Cpp: Change firstSeen / lastSeen return values * lang/cpp/src/tofuinfo.cpp, lang/cpp/src/tofuinfo.h (TofuInfo::firstSeen, TofuInfo::lastSeen): Change return values to unsigned long and update doc. diff --git a/lang/cpp/src/tofuinfo.cpp b/lang/cpp/src/tofuinfo.cpp index fe8f051..ade262b 100644 --- a/lang/cpp/src/tofuinfo.cpp +++ b/lang/cpp/src/tofuinfo.cpp @@ -123,12 +123,12 @@ unsigned short GpgME::TofuInfo::signCount() const return isNull() ? 0 : d->mInfo->signcount; } -unsigned int GpgME::TofuInfo::firstSeen() const +unsigned long GpgME::TofuInfo::firstSeen() const { return isNull() ? 0 : d->mInfo->firstseen; } -unsigned int GpgME::TofuInfo::lastSeen() const +unsigned long GpgME::TofuInfo::lastSeen() const { return isNull() ? 0 : d->mInfo->lastseen; } diff --git a/lang/cpp/src/tofuinfo.h b/lang/cpp/src/tofuinfo.h index 4835120..eb5dbcc 100644 --- a/lang/cpp/src/tofuinfo.h +++ b/lang/cpp/src/tofuinfo.h @@ -93,11 +93,11 @@ public: /* Number of signatures seen for this binding. Capped at USHRT_MAX. */ unsigned short signCount() const; - /* Number of seconds since the first message was verified. */ - unsigned int firstSeen() const; + /** Number of seconds since epoch when the first message was verified */ + unsigned long firstSeen() const; - /* Number of seconds since the last message was verified. */ - unsigned int lastSeen() const; + /** Number of seconds since epoch when the last message was verified */ + unsigned long lastSeen() const; /* If non-NULL a human readable string summarizing the TOFU data. */ const char *description() const; commit abcd9a283ee8f81870622c8e1dbdc7aad38c0358 Author: Andre Heinecke Date: Thu Aug 25 10:45:24 2016 +0200 Cpp: Add wrapper for gpgme_get_dirinfo * lang/cpp/src/context.cpp (dirInfo): New. * lang/cpp/src/global.h (dirInfo): New. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 2619084..62cad20 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1489,6 +1489,11 @@ GpgME::EngineInfo GpgME::engineInfo(GpgME::Protocol proto) return EngineInfo(); } +const char *GpgME::dirInfo(const char *what) +{ + return gpgme_get_dirinfo(what); +} + GpgME::Error GpgME::checkEngine(GpgME::Protocol proto) { const gpgme_protocol_t p = proto == CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ; diff --git a/lang/cpp/src/global.h b/lang/cpp/src/global.h index fc01d1e..3f12323 100644 --- a/lang/cpp/src/global.h +++ b/lang/cpp/src/global.h @@ -81,6 +81,15 @@ typedef void (*IOCallback)(void *data, int fd); GPGMEPP_EXPORT EngineInfo engineInfo(Protocol proto); GPGMEPP_EXPORT EngineInfo engineInfo(Engine engine); +/** Wrapper around gpgme_get_dirinfo. What can be: +homedir, sysconfdir, bindir, libexecdir, libdir, +datadir, localedir, agent-socket, agent-ssh-socket, +dirmngr-socket, uiserver-socket, gpgconf-name, gpg-name, +gpgsm-name, g13-name + +This may be extended in the future. +*/ +GPGMEPP_EXPORT const char *dirInfo(const char *what); GPGMEPP_EXPORT Error checkEngine(Protocol proto); GPGMEPP_EXPORT Error checkEngine(Engine engine); commit ece8b02a839d6fc566fea7b6e59fabff164f6cf5 Author: Andre Heinecke Date: Thu Aug 25 10:42:49 2016 +0200 Cpp: Add support for spawn engine * lang/cpp/src/context.cpp (Context::spawn, Context::spawnAsync): New. * lang/cpp/src/context.h: Add prototypes. (SpawnFlags): New. * lang/cpp/src/global.h (SpawnEngine): Added. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 4e66d3b..2619084 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -252,6 +252,15 @@ std::unique_ptr Context::createForEngine(Engine eng, Error *error) return std::unique_ptr(); } break; + case SpawnEngine: + if (const gpgme_error_t err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_SPAWN)) { + gpgme_release(ctx); + if (error) { + *error = Error(err); + } + return std::unique_ptr(); + } + break; default: if (error) { *error = Error::fromCode(GPG_ERR_INV_ARG); @@ -1311,6 +1320,29 @@ Error Context::setPinentryMode(PinentryMode which) return Error(d->lasterr = gpgme_set_pinentry_mode(d->ctx, mode)); } +// Engine Spawn stuff +Error Context::spawn(const char *file, const char *argv[], + Data &input, Data &output, Data &err, + SpawnFlags flags) +{ + return Error(d->lasterr = gpgme_op_spawn (d->ctx, file, argv, + input.impl() ? input.impl()->data : nullptr, + output.impl() ? output.impl()->data : nullptr, + err.impl() ? err.impl()->data : nullptr, + static_cast(flags))); +} + +Error Context::spawnAsync(const char *file, const char *argv[], + Data &input, Data &output, Data &err, + SpawnFlags flags) +{ + return Error(d->lasterr = gpgme_op_spawn_start (d->ctx, file, argv, + input.impl() ? input.impl()->data : nullptr, + output.impl() ? output.impl()->data : nullptr, + err.impl() ? err.impl()->data : nullptr, + static_cast(flags))); +} + std::ostream &operator<<(std::ostream &os, Protocol proto) { os << "GpgME::Protocol("; @@ -1345,6 +1377,9 @@ std::ostream &operator<<(std::ostream &os, Engine eng) case AssuanEngine: os << "AssuanEngine"; break; + case SpawnEngine: + os << "SpawnEngine"; + break; default: case UnknownEngine: os << "UnknownEngine"; @@ -1474,6 +1509,8 @@ static gpgme_protocol_t engine2protocol(const GpgME::Engine engine) return GPGME_PROTOCOL_ASSUAN; case GpgME::G13Engine: return GPGME_PROTOCOL_G13; + case GpgME::SpawnEngine: + return GPGME_PROTOCOL_SPAWN; case GpgME::UnknownEngine: ; } diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 6518d4c..f5e2b95 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -346,6 +346,34 @@ public: GpgME::Error createVFS(const char *containerFile, const std::vector &recipients); VfsMountResult mountVFS(const char *containerFile, const char *mountDir); + // Spawn Engine + enum SpawnFlags { + SpawnNone = 0, + SpawnDetached = 1, + SpawnAllowSetFg = 2 + }; + /** Spwan the process \a file with arguments \a argv. + * + * If a data parameter is null the /dev/null will be + * used. (Or other platform stuff). + * + * @param file The executable to start. + * @param argv list of arguments file should be argv[0]. + * @param input The data to be sent through stdin. + * @param output The data to be recieve the stdout. + * @param err The data to recieve stderr. + * @param flags Additional flags. + * + * @returns An error or empty error. + */ + GpgME::Error spawn(const char *file, const char *argv[], + Data &input, Data &output, Data &err, + SpawnFlags flags); + /** Async variant of spawn. Immediately returns after starting the + * process. */ + GpgME::Error spawnAsync(const char *file, const char *argv[], + Data &input, Data &output, + Data &err, SpawnFlags flags); // // // Run Control diff --git a/lang/cpp/src/global.h b/lang/cpp/src/global.h index 508e1d7..fc01d1e 100644 --- a/lang/cpp/src/global.h +++ b/lang/cpp/src/global.h @@ -53,7 +53,7 @@ GPGMEPP_EXPORT Error initializeLibrary(int); enum Protocol { OpenPGP, CMS, UnknownProtocol }; -enum Engine { GpgEngine, GpgSMEngine, GpgConfEngine, UnknownEngine, AssuanEngine, G13Engine }; +enum Engine { GpgEngine, GpgSMEngine, GpgConfEngine, UnknownEngine, AssuanEngine, G13Engine, SpawnEngine }; enum KeyListMode { Local = 0x1, ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/context.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ lang/cpp/src/context.h | 28 ++++++++++++++++++++++++++++ lang/cpp/src/global.h | 11 ++++++++++- lang/cpp/src/tofuinfo.cpp | 4 ++-- lang/cpp/src/tofuinfo.h | 8 ++++---- 5 files changed, 86 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 14:40:35 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 25 Aug 2016 14:40:35 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-311-gdf04b23 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 df04b232b8897f030534f8c3fbc87064edf8ae7d (commit) via 94420b05775122b25885c66ac67f77c59d01644d (commit) from de7b67f9b2e6bd43a036fa0bcc6a8ca4f5b10986 (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 df04b232b8897f030534f8c3fbc87064edf8ae7d Author: Andre Heinecke Date: Thu Aug 25 14:35:09 2016 +0200 qt: Add test for wkspublishjob * lang/qt/tests/t-wkspublish.cpp: New. * lang/qt/tests/Makefile.am: Update accordingly. -- Most tests are disabled by default as tey require an online connection. Define DO_ONLINE_TESTS to enable the tests. diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 85f6fa6..90f2978 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -25,10 +25,10 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) EXTRA_DIST = initial.test TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo \ - t-encrypt + t-encrypt t-wkspublish moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ - t-encrypt.moc t-support.hmoc + t-encrypt.moc t-support.hmoc t-wkspublish.moc AM_LDFLAGS = -no-install @@ -55,6 +55,7 @@ t_keylocate_SOURCES = t-keylocate.cpp $(support_src) t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src) t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src) t_encrypt_SOURCES = t-encrypt.cpp $(support_src) +t_wkspublish_SOURCES = t-wkspublish.cpp $(support_src) run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp nodist_t_keylist_SOURCES = $(moc_files) @@ -62,7 +63,7 @@ nodist_t_keylist_SOURCES = $(moc_files) BUILT_SOURCES = $(moc_files) noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ - run-keyformailboxjob + run-keyformailboxjob t-wkspublish CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \ diff --git a/lang/qt/tests/t-wkspublish.cpp b/lang/qt/tests/t-wkspublish.cpp new file mode 100644 index 0000000..7039f3c --- /dev/null +++ b/lang/qt/tests/t-wkspublish.cpp @@ -0,0 +1,280 @@ +/* t-wkspublish.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ +#include +#include +#include +#include +#include "wkspublishjob.h" +#include "keygenerationjob.h" +#include "keygenerationresult.h" +#include "importjob.h" +#include "importresult.h" +#include "protocol.h" +#include "engineinfo.h" +#include "context.h" + +#include "t-support.h" + +using namespace QGpgME; +using namespace GpgME; + +//#define DO_ONLINE_TESTS + +#define TEST_ADDRESS "testuser2 at test.gnupg.org" + +static const char *testSecKey = +"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +"\n" +"lHgEV77hVhMJKyQDAwIIAQEHAgMEN3qKqBr9EecnfUnpw8RS8DHAjJqhwm2HAoEE\n" +"3yfQQ9w8uB/bKm5dqW4HML3JWRH8YoJaKSVrJY2D1FZUY+vHlgABAKDwEAB0HND8\n" +"5kbxiJmqKIuuNqCJ2jHgs9G0xk4GdKvZEdq0JlRlc3QgVXNlciAyIDx0ZXN0dXNl\n" +"cjJAdGVzdC5nbnVwZy5vcmc+iHkEExMIACEFAle+4VYCGwMFCwkIBwIGFQgJCgsC\n" +"BBYCAwECHgECF4AACgkQRVRoUEJO+6zgFQD7BF3pnS3w3A7J9y+Y3kyGfmscXFWJ\n" +"Kme1PAsAlVSm1y4A+weReMvWFYHJH257v94yhStmV8egGoybsNDttNAW53cbnHwE\n" +"V77hVhIJKyQDAwIIAQEHAgMEX+6cF0HEn4g3ztFvwHyr7uwXMVYUGL3lE3mjhnV3\n" +"SbY6Dmy3OeFVnEVkawHqSv+HobpQTeEqNoQHAoIiXFCRlgMBCAcAAP9FykiyDspm\n" +"T33XWRPD+LAOmaIU7CIhfv9+lVkeExlU1w+qiGEEGBMIAAkFAle+4VYCGwwACgkQ\n" +"RVRoUEJO+6xjhgD/ZJ/MwYZJPk/xPYhTP8+wF+tErVNA8w3pP9D69dgUPdcA/izZ\n" +"Pji6YetVhgsyaHc4PrKynsk5G6nM3KkAOehUQsX8\n" +"=S/Wa\n" +"-----END PGP PRIVATE KEY BLOCK-----\n"; + +static const char *testResponse = +"From key-submission at test.gnupg.org Thu Aug 25 12:15:54 2016\n" +"Return-Path: \n" +"From: key-submission at test.gnupg.org\n" +"To: testuser2 at test.gnupg.org\n" +"Subject: Confirm your key publication\n" +"X-Wks-Loop: webkey.g10code.com\n" +"MIME-Version: 1.0\n" +"Content-Type: multipart/encrypted; protocol=\"application/pgp-encrypted\";\n" +" boundary=\"=-=01-wbu5fr9nu6fix5tcojjo=-=\"\n" +"Date: Thu, 25 Aug 2016 12:15:54 +0000\n" +"Message-Id: \n" +"Sender: \n" +"X-Kolab-Scheduling-Message: FALSE\n" +"\n" +" \n" +"\n" +"--=-=01-wbu5fr9nu6fix5tcojjo=-=\n" +"Content-Type: application/pgp-encrypted\n" +"\n" +"Version: 1\n" +"\n" +"--=-=01-wbu5fr9nu6fix5tcojjo=-=\n" +"Content-Type: application/octet-stream\n" +"\n" +"-----BEGIN PGP MESSAGE-----\n" +"Version: GnuPG v2\n" +"\n" +"hH4D8pSp7hUsFUASAgMEg0w39E6d0TkFYxLbT6n3YcoKTT+Ur/c7Sn1ECyL7Rnuk\n" +"cmPO0adt3JxueK7Oz5COlk32SECFODdF3cQuDhkGxzC6Sfc4SfisdILmNhaT/MeW\n" +"8a+yE4skSK70absif4kw5XkvxXNxHeIHfAteP50jPJLSwEsBTEceb9cRMoP7s8w0\n" +"lYyi+RWQ7UKlKKywtcRCL4ow2H7spjx+a+3FzNOAoy7K0/thhLVRk8z+iuPi0/4n\n" +"Z2Ql60USLLUlfV2ZIpXdCd+5GjTJsnGhDos1pas5TZcOOAxO12Cg5TcqHISOaqa8\n" +"6BqxcKCU3NypIynOKHj375KArSs0WsEH8HWHyBBHB+NYtNpnTAuHNKxM+JtNxf+U\n" +"NfD2zptS6kyiHLw+4zjL5pEV7RHS2PBwWBDS6vhnyybNwckleya96U04iYiGRYGE\n" +"lUUR6Fl8H6x04dItFH1/jJA6Ppcu4FoYou04HADWCqJXPTgztjiW1/9QoCeXl5lm\n" +"CcOCcuw7lXp+qTejuns=\n" +"=SsWX\n" +"-----END PGP MESSAGE-----\n" +"\n" +"--=-=01-wbu5fr9nu6fix5tcojjo=-=--\n"; + + +class WKSPublishTest : public QGpgMETest +{ + Q_OBJECT + +Q_SIGNALS: + void asyncDone(); + +private Q_SLOTS: + void testUnsupported() + { + // First check if it is supported + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(err); + Q_EMIT asyncDone(); + }); + job->startCheck ("testuser1 at localhost"); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } +#ifdef DO_ONLINE_TESTS +private Q_SLOTS: +#else +private: +#endif + void testWSKPublishSupport() + { + // First check if it is supported + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + std::cout << err; + Q_ASSERT(err); + } else { + Q_ASSERT(!err); + } + Q_EMIT asyncDone(); + }); + job->startCheck ("testuser1 at test.gnupg.org"); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } + + void testWKSPublishErrors() { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + /* Not supported */ + return; + } + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(err); + Q_EMIT asyncDone(); + }); + job->startCreate("AB874F24E98EBB8487EE7B170F8E3D97FE7011B7", + QStringLiteral("Foo at bar.baz")); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } + + void testWKSPublishCreate() { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + /* Not supported */ + return; + } + auto ctx = Context::createForProtocol(OpenPGP); + /* First generate a test key */ + const QString args = QStringLiteral("\n" + "%no-protection\n" + "%transient-key\n" + "key-type: ECDSA\n" + "key-curve: brainpoolP256r1\n" + "key-usage: sign\n" + "subkey-type: ECDH\n" + "subkey-curve: brainpoolP256r1\n" + "subkey-usage: encrypt\n" + "name-email: %1\n" + "name-real: Test User\n" + "").arg(TEST_ADDRESS); + + auto keygenjob = openpgp()->keyGenerationJob(); + QByteArray fpr; + connect(keygenjob, &KeyGenerationJob::result, this, + [this, &fpr](KeyGenerationResult result, QByteArray pubkeyData, QString, Error) + { + Q_ASSERT(!result.error()); + fpr = QByteArray(result.fingerprint()); + Q_ASSERT(!fpr.isEmpty()); + Q_EMIT asyncDone(); + }); + keygenjob->start(args); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + + /* Then try to create a request. */ + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(!err); + Q_EMIT asyncDone(); + const QString outstr = QString(out); + Q_ASSERT(outstr.contains( + QStringLiteral("-----BEGIN PGP PUBLIC KEY BLOCK-----"))); + Q_ASSERT(outstr.contains( + QStringLiteral("Content-Type: application/pgp-keys"))); + Q_ASSERT(outstr.contains( + QStringLiteral("From: " TEST_ADDRESS))); + }); + job->startCreate(fpr.constData(), QLatin1String(TEST_ADDRESS)); + Q_ASSERT(spy.wait()); + } + + void testWKSPublishRecieve() { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + /* Not supported */ + return; + } + auto importjob = openpgp()->importJob(); + connect(importjob, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + Q_ASSERT(!result.error()); + Q_ASSERT(!result.imports().empty()); + Q_ASSERT(result.numSecretKeysImported()); + Q_EMIT asyncDone(); + }); + importjob->start(QByteArray(testSecKey)); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + + /* Get a response. */ + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(!err); + Q_EMIT asyncDone(); + const QString outstr = QString(out); + Q_ASSERT(outstr.contains( + QStringLiteral("-----BEGIN PGP MESSAGE-----"))); + Q_ASSERT(outstr.contains( + QStringLiteral("Content-Type: multipart/encrypted;"))); + Q_ASSERT(outstr.contains( + QStringLiteral("From: " TEST_ADDRESS))); + }); + job->startRecieve(QByteArray(testResponse)); + Q_ASSERT(spy.wait()); + } + + void initTestCase() + { + QGpgMETest::initTestCase(); + const QString gpgHome = qgetenv("GNUPGHOME"); + qputenv("GNUPGHOME", mDir.path().toUtf8()); + Q_ASSERT(mDir.isValid()); + QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf")); + Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); + agentConf.write("allow-loopback-pinentry"); + agentConf.close(); + } +private: + QTemporaryDir mDir; +}; + +QTEST_MAIN(WKSPublishTest) + +#include "t-wkspublish.moc" commit 94420b05775122b25885c66ac67f77c59d01644d Author: Andre Heinecke Date: Thu Aug 25 14:29:41 2016 +0200 qt: Add WKSPublishJob * lang/qt/src/Makefile.am: Add new files. * lang/qt/src/job.cpp: Include moc / subclass stub. * lang/qt/src/protocol.h: Add virtual for new job. * lang/qt/src/protocol_p.h: Add job. * lang/qt/src/wkspublishjob.h: Interface for WKSPublishJob. * lang/qt/src/qgpgmewkspublishjob.cpp, lang/qt/src/qgpgmewkspublishjob.h: New. -- The Job was originally intended to be used with a SpawnEngine Context but QProcess was a better fit for the job. Usage is similar to the client tool. check, create, recieve. diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 840557e..8f6d773 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -34,7 +34,7 @@ qgpgme_sources = \ qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \ qgpgmeverifyopaquejob.cpp threadedjobmixin.cpp \ qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp \ - defaultkeygenerationjob.cpp + defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp # If you add one here make sure that you also add one in camelcase qgpgme_headers= \ @@ -68,7 +68,8 @@ qgpgme_headers= \ keylistjob.h \ listallkeysjob.h \ verifydetachedjob.h \ - defaultkeygenerationjob.h + defaultkeygenerationjob.h \ + wkspublishjob.h camelcase_headers= \ AddUserIDJob \ @@ -100,7 +101,8 @@ camelcase_headers= \ ListAllKeysJob \ VerifyDetachedJob \ KeyForMailboxJob \ - DefaultKeyGenerationJob + DefaultKeyGenerationJob \ + WKSPublishJob private_qgpgme_headers = \ qgpgme_export.h \ @@ -130,6 +132,7 @@ private_qgpgme_headers = \ qgpgmeverifydetachedjob.h \ qgpgmeverifyopaquejob.h \ qgpgmekeyformailboxjob.h \ + qgpgmewkspublishjob.h \ specialjob.h \ threadedjobmixin.h @@ -175,6 +178,7 @@ qgpgme_moc_sources = \ qgpgmesignkeyjob.moc \ qgpgmeverifydetachedjob.moc \ qgpgmeverifyopaquejob.moc \ + qgpgmewkspublishjob.moc \ refreshkeysjob.moc \ signencryptjob.moc \ signjob.moc \ @@ -183,6 +187,7 @@ qgpgme_moc_sources = \ verifydetachedjob.moc \ verifyopaquejob.moc \ keyformailboxjob.moc \ + wkspublishjob.moc \ qgpgmekeyformailboxjob.moc \ defaultkeygenerationjob.moc diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp index 8e50647..6b355a0 100644 --- a/lang/qt/src/job.cpp +++ b/lang/qt/src/job.cpp @@ -56,6 +56,7 @@ #include "adduseridjob.h" #include "specialjob.h" #include "keyformailboxjob.h" +#include "wkspublishjob.h" #include #include @@ -122,6 +123,7 @@ make_job_subclass(RefreshKeysJob) make_job_subclass(AddUserIDJob) make_job_subclass(SpecialJob) make_job_subclass(KeyForMailboxJob) +make_job_subclass(WKSPublishJob) #undef make_job_subclass @@ -151,3 +153,4 @@ make_job_subclass(KeyForMailboxJob) #include "adduseridjob.moc" #include "specialjob.moc" #include "keyformailboxjob.moc" +#include "wkspublishjob.moc" diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index 23b9d93..b2dee1d 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -63,6 +63,7 @@ class ChangePasswdJob; class AddUserIDJob; class SpecialJob; class KeyForMailboxJob; +class WKSPublishJob; /** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors. * @@ -148,6 +149,9 @@ public: virtual KeyListJob *locateKeysJob() const = 0; /** Find the best key to use for a mailbox. */ virtual KeyForMailboxJob *keyForMailboxJob() const = 0; + + /** A Job for interacting with gnupg's wks tools. */ + virtual WKSPublishJob *wksPublishJob() const = 0; }; /** Obtain a reference to the OpenPGP Protocol. diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index afb4f9c..2ce4182 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -57,6 +57,7 @@ #include "qgpgmechangepasswdjob.h" #include "qgpgmeadduseridjob.h" #include "qgpgmekeyformailboxjob.h" +#include "qgpgmewkspublishjob.h" namespace { @@ -387,6 +388,18 @@ public: } return new QGpgME::QGpgMEKeyForMailboxJob(context); } + + QGpgME::WKSPublishJob *wksPublishJob() const Q_DECL_OVERRIDE + { + if (mProtocol != GpgME::OpenPGP) { + return Q_NULLPTR; + } + auto context = GpgME::Context::createForEngine(GpgME::SpawnEngine); + if (!context) { + return Q_NULLPTR; + } + return new QGpgME::QGpgMEWKSPublishJob(context.release()); + } }; } diff --git a/lang/qt/src/qgpgmewkspublishjob.cpp b/lang/qt/src/qgpgmewkspublishjob.cpp new file mode 100644 index 0000000..8f97cb5 --- /dev/null +++ b/lang/qt/src/qgpgmewkspublishjob.cpp @@ -0,0 +1,189 @@ +/* wkspublishjob.cpp + + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "qgpgmewkspublishjob.h" + +#include "context.h" +#include "key.h" +#include "util.h" + +#include +#include +#include + +/* Timeout for the WKS Processes will be 5 Minutes as + * they can involve pinentry questions. */ +#define TIMEOUT_VALUE (5*60*1000) + +using namespace QGpgME; +using namespace GpgME; + +QGpgMEWKSPublishJob::QGpgMEWKSPublishJob(Context *context) + : mixin_type(context) +{ + lateInitialization(); +} + +QGpgMEWKSPublishJob::~QGpgMEWKSPublishJob() {} + +static QString getWKSClient() +{ + auto libexecdir = QString::fromLocal8Bit(dirInfo("libexecdir")); + if (libexecdir.isEmpty()) { + return QString(); + } + + const QFileInfo fi(QDir(libexecdir).absoluteFilePath(QStringLiteral("gpg-wks-client"))); + if (fi.exists() && fi.isExecutable()) { + return fi.absoluteFilePath(); + } + return QString(); +} + +static QGpgMEWKSPublishJob::result_type check_worker(const QString &mail) +{ + if (mail.isEmpty()) { + return std::make_tuple (Error(make_error(GPG_ERR_INV_ARG)), + QByteArray(), QByteArray(), QString(), Error()); + } + + const auto wksPath = getWKSClient(); + if (wksPath.isEmpty()) { + return std::make_tuple (Error(make_error(GPG_ERR_NOT_SUPPORTED)), + QByteArray(), QByteArray(), QString(), Error()); + } + + /* QProcess instead of engine_spawn because engine_spawn does not communicate + * the return value of the process and we are in qt anyway. */ + QProcess proc; + proc.setProgram(wksPath); + proc.setArguments(QStringList() << QStringLiteral("--supported") << mail); + proc.start(); + if (!proc.waitForStarted()) { + return std::make_tuple (Error(make_error(GPG_ERR_NOT_SUPPORTED)), + QByteArray(), QByteArray(), QString(), Error()); + } + if (!proc.waitForFinished(TIMEOUT_VALUE)) { + return std::make_tuple (Error(make_error(GPG_ERR_TIMEOUT)), + QByteArray(), QByteArray(), QString(), Error()); + } + if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) { + return std::make_tuple (Error(), QByteArray(), QByteArray(), QString(), Error()); + } + return std::make_tuple (Error(make_error(GPG_ERR_NOT_ENABLED)), + QByteArray(), QByteArray(), QString(), Error()); +} + +static QGpgMEWKSPublishJob::result_type create_worker(const char *fpr, const QString &mail) +{ + if (mail.isEmpty() || !fpr) { + return std::make_tuple (Error(make_error(GPG_ERR_INV_ARG)), + QByteArray(), QByteArray(), QString(), Error()); + } + + const auto wksPath = getWKSClient(); + if (wksPath.isEmpty()) { + return std::make_tuple (Error(make_error(GPG_ERR_NOT_SUPPORTED)), + QByteArray(), QByteArray(), QString(), Error()); + } + + QProcess proc; + proc.setProgram(wksPath); + proc.setArguments(QStringList() << QStringLiteral("--create") + << QLatin1String(fpr) + << mail); + proc.start(); + if (!proc.waitForStarted()) { + return std::make_tuple (Error(make_error(GPG_ERR_NOT_SUPPORTED)), + QByteArray(), QByteArray(), QString(), Error()); + } + + if (!proc.waitForFinished(TIMEOUT_VALUE)) { + return std::make_tuple (Error(make_error(GPG_ERR_TIMEOUT)), + QByteArray(), QByteArray(), QString(), Error()); + } + if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) { + return std::make_tuple (Error(), proc.readAllStandardOutput(), + proc.readAllStandardError(), QString(), Error()); + } + return std::make_tuple (Error(make_error(GPG_ERR_GENERAL)), + proc.readAllStandardOutput(), proc.readAllStandardError(), QString(), Error()); +} + +static QGpgMEWKSPublishJob::result_type recieve_worker(const QByteArray &response) +{ + if (response.isEmpty()) { + return std::make_tuple (Error(make_error(GPG_ERR_INV_ARG)), + QByteArray(), QByteArray(), QString(), Error()); + } + + const auto wksPath = getWKSClient(); + if (wksPath.isEmpty()) { + return std::make_tuple (Error(make_error(GPG_ERR_NOT_SUPPORTED)), + QByteArray(), QByteArray(), QString(), Error()); + } + + QProcess proc; + proc.setProgram(wksPath); + proc.setArguments(QStringList() << QStringLiteral("--receive")); + proc.start(); + if (!proc.waitForStarted()) { + return std::make_tuple (Error(make_error(GPG_ERR_NOT_SUPPORTED)), + QByteArray(), QByteArray(), QString(), Error()); + } + proc.write(response); + proc.closeWriteChannel(); + if (!proc.waitForFinished(TIMEOUT_VALUE)) { + return std::make_tuple (Error(make_error(GPG_ERR_TIMEOUT)), + QByteArray(), QByteArray(), QString(), Error()); + } + if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) { + return std::make_tuple (Error(), proc.readAllStandardOutput(), + proc.readAllStandardError(), QString(), Error()); + } + return std::make_tuple (Error(make_error(GPG_ERR_GENERAL)), + proc.readAllStandardOutput(), proc.readAllStandardError(), QString(), Error()); +} + +void QGpgMEWKSPublishJob::startCheck(const QString &mailbox) +{ + run(std::bind(&check_worker, mailbox)); +} + +void QGpgMEWKSPublishJob::startCreate(const char *fpr, const QString &mailbox) { + run(std::bind(&create_worker, fpr, mailbox)); +} + +void QGpgMEWKSPublishJob::startRecieve(const QByteArray &response) +{ + run(std::bind(&recieve_worker, response)); +} + +#include "qgpgmewkspublishjob.moc" diff --git a/lang/qt/src/qgpgmewkspublishjob.h b/lang/qt/src/qgpgmewkspublishjob.h new file mode 100644 index 0000000..1a31149 --- /dev/null +++ b/lang/qt/src/qgpgmewkspublishjob.h @@ -0,0 +1,70 @@ +/* qgpgmewkspublishjob.h + + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ +#ifndef QGPGME_QGPGMEWKSPUBLISHJOB_H +#define QGPGME_QGPGMEWKSPUBLISHJOB_H + +#include "wkspublishjob.h" + +#include "threadedjobmixin.h" +namespace GpgME +{ + class Key; +} // namespace GpgME + +namespace QGpgME { + +/** + * Handles Web Key Service Publishing. Needs WKS tools installed and + * server support. + */ +class QGpgMEWKSPublishJob +#ifdef Q_MOC_RUN + : public WKSPublishJob +#else + : public _detail::ThreadedJobMixin > +#endif +{ + Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: + void slotFinished(); +#endif +public: + explicit QGpgMEWKSPublishJob(GpgME::Context *context); + ~QGpgMEWKSPublishJob(); + + void startCheck(const QString &mailbox) Q_DECL_OVERRIDE; + void startCreate(const char *fpr, const QString &mailbox) Q_DECL_OVERRIDE; + void startRecieve(const QByteArray &response) Q_DECL_OVERRIDE; +}; + +} + +#endif diff --git a/lang/qt/src/wkspublishjob.h b/lang/qt/src/wkspublishjob.h new file mode 100644 index 0000000..782112f --- /dev/null +++ b/lang/qt/src/wkspublishjob.h @@ -0,0 +1,101 @@ +/* wkspublishjob.h + + Copyright (c) 2016 Intevation GmbH + + QGpgME 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. + + QGpgME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ +#ifndef QGPGME_WKSPUBLISHJOB_H +#define QGPGME_WKSPUBLISHJOB_H + +#include "job.h" + +#include "qgpgme_export.h" + +namespace GpgME +{ + class Key; +} // namespace GpgME + +namespace QGpgME { + +/** + * Handles Web Key Service Publishing. Needs WKS tools installed and + * server support. + * + * Remember that after a result is emited the job is auto deleted + * so you can only use it for a single action. + */ +class QGPGME_EXPORT WKSPublishJob: public Job +{ + Q_OBJECT +protected: + explicit WKSPublishJob(QObject *parent); +public: + ~WKSPublishJob(); + + + /** Start a check if WKS Publishing is supported. As this involves + * an HTTP Query it might take a while. Returns GPG_ERR_NOT_SUPPORED + * result if GnuPG is too old or the required tools are not installed. + * + * The error GPG_ERR_NOT_ENABLED indicates that wks-tools failed to + * detect a working wks service for this. + * + * @param the mailbox to check for. + **/ + virtual void startCheck(const QString &mailbox) = 0; + + /** Create a publish request. + * The returned Data from the result will contain + * the full Mail as returned by gpg-wks-client --create + * + * @param fpr the fingerprint of the key to create the request for. + * @param mailbox A simple mail address without a Name. + */ + virtual void startCreate(const char *fpr, const QString &mailbox) = 0; + + /** Handle a submisson response. The returned Data will contain + * the full Mail as returned by gpg-wks-client --create + * + * @param response The response of the server. + **/ + virtual void startRecieve(const QByteArray &response) = 0; + +Q_SIGNALS: + /* Result of the operation returned Data and returned Error are + * the results from gpg-wks-client's stdout or stderr respectively. + * + * As usual auditLogAsHtml and auditLogError can be ignored. + **/ + void result(const GpgME::Error &error, const QByteArray &returnedData, + const QByteArray &returnedError, + const QString &auditLogAsHtml = QString(), + const GpgME::Error &auditLogError = GpgME::Error()); +}; + +} + +#endif ----------------------------------------------------------------------- Summary of changes: lang/qt/src/Makefile.am | 11 +- lang/qt/src/job.cpp | 3 + lang/qt/src/protocol.h | 4 + lang/qt/src/protocol_p.h | 13 + lang/qt/src/qgpgmewkspublishjob.cpp | 189 ++++++++++++++ .../{qgpgmedeletejob.h => qgpgmewkspublishjob.h} | 47 ++-- lang/qt/src/wkspublishjob.h | 101 ++++++++ lang/qt/tests/Makefile.am | 7 +- lang/qt/tests/t-wkspublish.cpp | 280 +++++++++++++++++++++ 9 files changed, 625 insertions(+), 30 deletions(-) create mode 100644 lang/qt/src/qgpgmewkspublishjob.cpp copy lang/qt/src/{qgpgmedeletejob.h => qgpgmewkspublishjob.h} (60%) create mode 100644 lang/qt/src/wkspublishjob.h create mode 100644 lang/qt/tests/t-wkspublish.cpp hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 15:22:25 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 25 Aug 2016 15:22:25 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-313-g053e6e0 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 053e6e0a7b8ea38ad9d4160c84814867bbb9fcf6 (commit) via f08904b810d77d87c66d9c7875c4e7f2bde5dd92 (commit) from df04b232b8897f030534f8c3fbc87064edf8ae7d (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 053e6e0a7b8ea38ad9d4160c84814867bbb9fcf6 Author: Andre Heinecke Date: Thu Aug 25 15:20:02 2016 +0200 qt: Fix tofuinfo test when gpg is gpg2 * lang/qt/tests/t-support.cpp (QGpgMETest::copyKeyrings): New helper. * lang/qt/tests/t-support.h: Declare. * lang/qt/tests/t-encrypt.cpp: use it * lang/qt/tests/t-tofuinbo.cpp: ditto. -- New helper takes care of copying the correct files for either keybox or keyring. diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp index 708c205..44cea96 100644 --- a/lang/qt/tests/t-encrypt.cpp +++ b/lang/qt/tests/t-encrypt.cpp @@ -242,11 +242,7 @@ public Q_SLOT: Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); agentConf.write("allow-loopback-pinentry"); agentConf.close(); - Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/pubring.gpg"), - mDir.path() + QStringLiteral("/pubring.gpg"))); - Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/secring.gpg"), - mDir.path() + QStringLiteral("/secring.gpg"))); - + copyKeyrings(gpgHome, mDir.path()); } private: diff --git a/lang/qt/tests/t-support.cpp b/lang/qt/tests/t-support.cpp index ffb0f9e..73e8d5c 100644 --- a/lang/qt/tests/t-support.cpp +++ b/lang/qt/tests/t-support.cpp @@ -45,6 +45,31 @@ void QGpgMETest::cleanupTestCase() killAgent(); } +bool QGpgMETest::copyKeyrings(const QString &src, const QString &dest) +{ + bool is21dir = QFileInfo(src + QDir::separator() + QStringLiteral("pubring.kbx")).exists(); + const QString name = is21dir ? QStringLiteral("pubring.kbx") : + QStringLiteral("pubring.gpg"); + if (!QFile::copy(src + name, dest + QDir::separator() + name)) { + return false; + } + if (!is21dir) { + return (QFile::copy(src + QDir::separator() + QStringLiteral("secring.gpg"), + dest + QDir::separator() + QStringLiteral("secring.gpg"))); + } + QDir dir (src + QDir::separator() + QStringLiteral("private-keys-v1.d")); + QDir target(dest); + if (!target.mkdir("private-keys-v1.d")) { + return false; + } + foreach (QString f, dir.entryList(QDir::Files)) { + if (!QFile::copy(src + QDir::separator() + f, dest + QDir::separator() + f)) { + return false; + } + } + return true; +} + void killAgent(const QString& dir) { QProcess proc; @@ -59,4 +84,5 @@ void killAgent(const QString& dir) proc.waitForFinished(); } + #include "t-support.hmoc" diff --git a/lang/qt/tests/t-support.h b/lang/qt/tests/t-support.h index cf0cb26..74163b1 100644 --- a/lang/qt/tests/t-support.h +++ b/lang/qt/tests/t-support.h @@ -55,6 +55,8 @@ void killAgent(const QString &dir = qgetenv("GNUPGHOME")); class QGpgMETest : public QObject { Q_OBJECT +protected: + bool copyKeyrings(const QString &from, const QString& to); public Q_SLOTS: void initTestCase(); diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index ab466ee..7eea1ea 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -239,11 +239,7 @@ private Q_SLOTS: Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); agentConf.write("allow-loopback-pinentry"); agentConf.close(); - Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/pubring.gpg"), - mDir.path() + QStringLiteral("/pubring.gpg"))); - Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/secring.gpg"), - mDir.path() + QStringLiteral("/secring.gpg"))); - + copyKeyrings(gpgHome, mDir.path()); } private: QTemporaryDir mDir; commit f08904b810d77d87c66d9c7875c4e7f2bde5dd92 Author: Andre Heinecke Date: Thu Aug 25 15:00:46 2016 +0200 qt: Remove unused variable in test * t-wkspublish.cpp (testWKSPublishCreate): Remove context. diff --git a/lang/qt/tests/t-wkspublish.cpp b/lang/qt/tests/t-wkspublish.cpp index 7039f3c..17d3447 100644 --- a/lang/qt/tests/t-wkspublish.cpp +++ b/lang/qt/tests/t-wkspublish.cpp @@ -39,7 +39,6 @@ #include "importresult.h" #include "protocol.h" #include "engineinfo.h" -#include "context.h" #include "t-support.h" @@ -177,7 +176,6 @@ private: /* Not supported */ return; } - auto ctx = Context::createForProtocol(OpenPGP); /* First generate a test key */ const QString args = QStringLiteral("\n" "%no-protection\n" ----------------------------------------------------------------------- Summary of changes: lang/qt/tests/t-encrypt.cpp | 6 +----- lang/qt/tests/t-support.cpp | 26 ++++++++++++++++++++++++++ lang/qt/tests/t-support.h | 2 ++ lang/qt/tests/t-tofuinfo.cpp | 6 +----- lang/qt/tests/t-wkspublish.cpp | 2 -- 5 files changed, 30 insertions(+), 12 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 16:21:30 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 25 Aug 2016 16:21:30 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-11-g0a5a854 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 0a5a854510fda6e6990938a3fca424df868fe676 (commit) via 74a082bc10960b2d65d4d1e31152f988a40a2225 (commit) from 19d12be3cea5b4ee8153287a2f2442913a5e07a1 (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 0a5a854510fda6e6990938a3fca424df868fe676 Author: Werner Koch Date: Thu Aug 25 15:18:51 2016 +0200 gpg: Fix false negatives in Ed25519 signature verification. * g10/pkglue.c (pk_verify): Fix Ed25519 signatrue values. * tests/openpgp/verify.scm (msg_ed25519_rshort): New (msg_ed25519_sshort): New. ("Checking that a valid Ed25519 signature is verified as such"): New. -- About one out of 256 signature won't verify due to stripped zero bytes. See the source comment for details. Reported-by: Andre Heinecke Signed-off-by: Werner Koch diff --git a/g10/pkglue.c b/g10/pkglue.c index 7de2fa7..50de347 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -58,6 +58,7 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, { gcry_sexp_t s_sig, s_hash, s_pkey; int rc; + unsigned int neededfixedlen = 0; /* Make a sexp from pkey. */ if (pkalgo == PUBKEY_ALGO_DSA) @@ -103,6 +104,9 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, curve, pkey[1]); xfree (curve); } + + if (openpgp_oid_is_ed25519 (pkey[0])) + neededfixedlen = 256 / 8; } else return GPG_ERR_PUBKEY_ALGO; @@ -144,11 +148,59 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, } else if (pkalgo == PUBKEY_ALGO_EDDSA) { - if (!data[0] || !data[1]) + gcry_mpi_t r = data[0]; + gcry_mpi_t s = data[1]; + size_t rlen, slen, n; /* (bytes) */ + char buf[64]; + + log_assert (neededfixedlen <= sizeof buf); + + if (!r || !s) + rc = gpg_error (GPG_ERR_BAD_MPI); + else if ((rlen = (gcry_mpi_get_nbits (r)+7)/8) > neededfixedlen || !rlen) + rc = gpg_error (GPG_ERR_BAD_MPI); + else if ((slen = (gcry_mpi_get_nbits (s)+7)/8) > neededfixedlen || !slen) rc = gpg_error (GPG_ERR_BAD_MPI); else - rc = gcry_sexp_build (&s_sig, NULL, - "(sig-val(eddsa(r%M)(s%M)))", data[0], data[1]); + { + /* We need to fixup the length in case of leading zeroes. + * OpenPGP does not allow leading zeroes and the parser for + * the signature packet has no information on the use curve, + * thus we need to do it here. We won't do it for opaque + * MPIs under the assumption that they are known to be fine; + * we won't see them here anyway but the check is anyway + * required. Fixme: A nifty feature for gcry_sexp_build + * would be a format to left pad the value (e.g. "%*M"). */ + rc = 0; + + if (rlen < neededfixedlen + && !gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE) + && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, r))) + { + log_assert (n < neededfixedlen); + memmove (buf + (neededfixedlen - n), buf, n); + memset (buf, 0, neededfixedlen - n); + r = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8); + } + if (slen < neededfixedlen + && !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE) + && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, s))) + { + log_assert (n < neededfixedlen); + memmove (buf + (neededfixedlen - n), buf, n); + memset (buf, 0, neededfixedlen - n); + s = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8); + } + + if (!rc) + rc = gcry_sexp_build (&s_sig, NULL, + "(sig-val(eddsa(r%M)(s%M)))", r, s); + + if (r != data[0]) + gcry_mpi_release (r); + if (s != data[1]) + gcry_mpi_release (s); + } } else if (pkalgo == PUBKEY_ALGO_ELGAMAL || pkalgo == PUBKEY_ALGO_ELGAMAL_E) { diff --git a/tests/openpgp/verify.scm b/tests/openpgp/verify.scm index de03db5..2f03027 100755 --- a/tests/openpgp/verify.scm +++ b/tests/openpgp/verify.scm @@ -236,6 +236,67 @@ FWIAQUplk7JWbyRKAJ92ZJyJpWfzb0yc1s7MY65r2qEHrg== ;; Two clear text signatures in a row (define msg_clsclss_asc_multiple (string-append msg_cls_asc msg_clss_asc)) + +;; An Ed25519 cleartext message with an R parameter of only 247 bits +;; so that the code to re-insert the stripped zero byte kicks in. The +;; S parameter has 253 bits but that does not strip a full byte. +(define msg_ed25519_rshort " +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Dear Emily: + I'm still confused as to what groups articles should be posted +to. How about an example? + -- Still Confused + +Dear Still: + Ok. Let's say you want to report that Gretzky has been traded from +the Oilers to the Kings. Now right away you might think rec.sport.hockey +would be enough. WRONG. Many more people might be interested. This is a +big trade! Since it's a NEWS article, it belongs in the news.* hierarchy +as well. If you are a news admin, or there is one on your machine, try +news.admin. If not, use news.misc. + The Oilers are probably interested in geology, so try sci.physics. +He is a big star, so post to sci.astro, and sci.space because they are also +interested in stars. Next, his name is Polish sounding. So post to +soc.culture.polish. But that group doesn't exist, so cross-post to +news.groups suggesting it should be created. With this many groups of +interest, your article will be quite bizarre, so post to talk.bizarre as +well. (And post to comp.std.mumps, since they hardly get any articles +there, and a \"comp\" group will propagate your article further.) + You may also find it is more fun to post the article once in each +group. If you list all the newsgroups in the same article, some newsreaders +will only show the the article to the reader once! Don't tolerate this. + -- Emily Postnews Answers Your Questions on Netiquette +-----BEGIN PGP SIGNATURE----- + +iJEEARYIADoWIQSyHeq0+HX7PaQvHR0TlWNoKgINCgUCV772DhwccGF0cmljZS5s +dW11bWJhQGV4YW1wbGUubmV0AAoJEBOVY2gqAg0KMAIA90EtUwAja0iJGpO91wyz +GLh9pS5v495V0r94yU6uUyUA/RT/StyPWe1wbnEZuacZnLbUV6Yy/aTXCVAlxf0r +TusO +=vQ3f +-----END PGP SIGNATURE----- +") + +;; An Ed25519 cleartext message with an S parameter of only 248 bits +;; so that the code to re-insert the stripped zero byte kicks in. +(define msg_ed25519_sshort " +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +All articles that coruscate with resplendence are not truly auriferous. +-----BEGIN PGP SIGNATURE----- + +iJEEARYIADoWIQSyHeq0+HX7PaQvHR0TlWNoKgINCgUCV771QhwccGF0cmljZS5s +dW11bWJhQGV4YW1wbGUubmV0AAoJEBOVY2gqAg0KHVEBAI66OPDYXKWO3r6SaFT+ +uxmh8x4ZerW41vMA9gkJ4AEKAPjoe/Z7fDqo1lCptIFutFAGbfNxcm/53prfx2fT +GisM +=L7sk +-----END PGP SIGNATURE----- +") + + + ;; Fixme: We need more tests with manipulated cleartext signatures. ;; @@ -272,3 +333,15 @@ FWIAQUplk7JWbyRKAJ92ZJyJpWfzb0yc1s7MY65r2qEHrg== (pipe:spawn `(, at GPG --verify))) (error "verification succeded but should not"))) '(bad_ls_asc bad_fols_asc bad_olsf_asc bad_ools_asc)) + + +;;; Need to import the ed25519 sample key used for +;;; the next two tests. +(call-check `(, at GPG --quiet --yes --import ,(in-srcdir key-file2))) +(for-each-p + "Checking that a valid Ed25519 signature is verified as such" + (lambda (armored-file) + (pipe:do + (pipe:echo (eval armored-file (current-environment))) + (pipe:spawn `(, at GPG --verify)))) + '(msg_ed25519_rshort msg_ed25519_sshort)) commit 74a082bc10960b2d65d4d1e31152f988a40a2225 Author: Werner Koch Date: Thu Aug 25 15:16:32 2016 +0200 common: Rename an odd named function. * common/openpgp-oid.c (oid_crv25519): Rename to oid_cv25519. (openpgp_oid_is_crv25519): Rename to openpgp_oid_is_cv25519. Change callers. -- We use "cv25519" everywhere else and thus the test function should not have a surprising name. Signed-off-by: Werner Koch diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 7c93547..af3cbbe 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -68,7 +68,7 @@ static const char oid_ed25519[] = { 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 }; /* The OID for Curve25519 in OpenPGP format. */ -static const char oid_crv25519[] = +static const char oid_cv25519[] = { 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 }; @@ -298,7 +298,7 @@ openpgp_oid_is_ed25519 (gcry_mpi_t a) int -openpgp_oid_is_crv25519 (gcry_mpi_t a) +openpgp_oid_is_cv25519 (gcry_mpi_t a) { const unsigned char *buf; unsigned int nbits; @@ -309,8 +309,8 @@ openpgp_oid_is_crv25519 (gcry_mpi_t a) buf = gcry_mpi_get_opaque (a, &nbits); n = (nbits+7)/8; - return (n == DIM (oid_crv25519) - && !memcmp (buf, oid_crv25519, DIM (oid_crv25519))); + return (n == DIM (oid_cv25519) + && !memcmp (buf, oid_cv25519, DIM (oid_cv25519))); } diff --git a/common/util.h b/common/util.h index 1c3cce9..f293234 100644 --- a/common/util.h +++ b/common/util.h @@ -206,7 +206,7 @@ size_t percent_unescape_inplace (char *string, int nulrepl); gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi); char *openpgp_oid_to_str (gcry_mpi_t a); int openpgp_oid_is_ed25519 (gcry_mpi_t a); -int openpgp_oid_is_crv25519 (gcry_mpi_t a); +int openpgp_oid_is_cv25519 (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, int canon); const char *openpgp_enum_curves (int *idxp); diff --git a/g10/keyid.c b/g10/keyid.c index 84990a3..ea6ed5e 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -919,7 +919,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) pk->pubkey_algo == PUBKEY_ALGO_EDDSA? "(public-key(ecc(curve%s)(flags eddsa)(q%m)))": (pk->pubkey_algo == PUBKEY_ALGO_ECDH - && openpgp_oid_is_crv25519 (pk->pkey[0]))? + && openpgp_oid_is_cv25519 (pk->pkey[0]))? "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))": "(public-key(ecc(curve%s)(q%m)))", curve, pk->pkey[1]); diff --git a/g10/pkglue.c b/g10/pkglue.c index 232c489..7de2fa7 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -227,7 +227,7 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, rc = gpg_error_from_syserror (); else { - int with_djb_tweak_flag = openpgp_oid_is_crv25519 (pkey[0]); + int with_djb_tweak_flag = openpgp_oid_is_cv25519 (pkey[0]); /* Now use the ephemeral secret to compute the shared point. */ rc = gcry_sexp_build (&s_pkey, NULL, ----------------------------------------------------------------------- Summary of changes: common/openpgp-oid.c | 8 +++--- common/util.h | 2 +- g10/keyid.c | 2 +- g10/pkglue.c | 60 ++++++++++++++++++++++++++++++++++++--- tests/openpgp/verify.scm | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 16:27:52 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 25 Aug 2016 16:27:52 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-318-g9fc72e9 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 9fc72e928bf2cf239bd3b0facdf33ceb1acc975b (commit) via c875f07e559a7c53fc173b4c3f9f5715f3fbb8f8 (commit) via 4e37d0bb1255558ce20e1a5ac83a2d06a37f8b0b (commit) via 5a92cc96da183ebb19867a2a910f53ba41e76ae9 (commit) via f311b92ceaedb12c9e00a722b6b47bbe6b50871e (commit) from 053e6e0a7b8ea38ad9d4160c84814867bbb9fcf6 (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 9fc72e928bf2cf239bd3b0facdf33ceb1acc975b Author: Andre Heinecke Date: Thu Aug 25 16:25:49 2016 +0200 qt: Fix and extend TofuInfo test. * lang/qt/tests/t-tofuinfo.cpp: Delete executed jobs. (testTofuKeyList): New. (testSupported): Activate for 2.1.16 (signAndVerify): Disable sigcount tests. diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index d306167..30f7bea 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -62,10 +62,7 @@ class TofuInfoTest: public QGpgMETest bool testSupported() { - /* GnuPG currently returns different values for different uid's - * on the first verify. This breaks this test. so its disabled - * for now. See GnuPG-Bug 2405 */ - return !(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "3.0.0"); + return !(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.16"); } void testTofuCopy(TofuInfo other, const TofuInfo &orig) @@ -90,9 +87,12 @@ class TofuInfoTest: public QGpgMETest keys.push_back(key); QByteArray signedData; auto sigResult = job->exec(keys, what.toUtf8(), NormalSignatureMode, signedData); + delete job; auto info = keys[0].userID(0).tofuInfo(); - Q_ASSERT(info.signCount() == expected - 1); + if (expected != -1) { + Q_ASSERT(info.signCount() == expected - 1); + } Q_ASSERT(!sigResult.error()); @@ -100,6 +100,7 @@ class TofuInfoTest: public QGpgMETest QByteArray verified; auto result = verifyJob->exec(signedData, verified); + delete verifyJob; Q_ASSERT(!result.error()); Q_ASSERT(verified == what.toUtf8()); @@ -113,7 +114,9 @@ class TofuInfoTest: public QGpgMETest Q_ASSERT(!strcmp (key.primaryFingerprint(), sig.fingerprint())); auto stats = key2.userID(0).tofuInfo(); Q_ASSERT(!stats.isNull()); - Q_ASSERT(stats.signCount() == expected); + if (expected != -1) { + Q_ASSERT(stats.signCount() == expected); + } } private Q_SLOTS: @@ -142,6 +145,7 @@ private Q_SLOTS: QByteArray plaintext; auto result = job->exec(data1, plaintext); + delete job; Q_ASSERT(!result.isNull()); Q_ASSERT(!result.error()); @@ -168,6 +172,7 @@ private Q_SLOTS: job = openpgp()->verifyOpaqueJob(true); result = job->exec(data1, plaintext); + delete job; Q_ASSERT(!result.isNull()); Q_ASSERT(!result.error()); @@ -188,6 +193,7 @@ private Q_SLOTS: /* Verify that another call yields the same result */ job = openpgp()->verifyOpaqueJob(true); result = job->exec(data1, plaintext); + delete job; Q_ASSERT(!result.isNull()); Q_ASSERT(!result.error()); @@ -215,14 +221,49 @@ private Q_SLOTS: std::vector keys; GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("zulu at example.net"), true, keys); + delete job; Q_ASSERT(!keys.empty()); Key key = keys[0]; Q_ASSERT(!key.isNull()); - signAndVerify(QStringLiteral("Hello"), key, 1); - signAndVerify(QStringLiteral("Hello2"), key, 2); - signAndVerify(QStringLiteral("Hello3"), key, 3); - signAndVerify(QStringLiteral("Hello4"), key, 4); + signAndVerify(QStringLiteral("Hello"), key, -1); + signAndVerify(QStringLiteral("Hello2"), key, -1); + signAndVerify(QStringLiteral("Hello3"), key, -1); + signAndVerify(QStringLiteral("Hello4"), key, -1); + } + + void testTofuKeyList() + { + if (!testSupported()) { + return; + } + + /* First check that the key has no tofu info. */ + auto *job = openpgp()->keyListJob(false, false, false); + std::vector keys; + auto result = job->exec(QStringList() << QStringLiteral("zulu at example.net"), + true, keys); + delete job; + Q_ASSERT(!keys.empty()); + auto key = keys[0]; + Q_ASSERT(!key.isNull()); + Q_ASSERT(key.userID(0).tofuInfo().isNull()); + signAndVerify(QStringLiteral("Hello"), key, -1); + signAndVerify(QStringLiteral("Hello"), key, -1); + + /* Now another one but with tofu */ + job = openpgp()->keyListJob(false, false, false); + job->addMode(GpgME::WithTofu); + result = job->exec(QStringList() << QStringLiteral("zulu at example.net"), + true, keys); + delete job; + Q_ASSERT(!result.error()); + Q_ASSERT(!keys.empty()); + auto key2 = keys[0]; + Q_ASSERT(!key2.isNull()); + auto info = key2.userID(0).tofuInfo(); + Q_ASSERT(!info.isNull()); + Q_ASSERT(info.signCount()); } void initTestCase() commit c875f07e559a7c53fc173b4c3f9f5715f3fbb8f8 Author: Andre Heinecke Date: Thu Aug 25 16:23:58 2016 +0200 qt: Fix keyring copy in tests * lang/qt/test/t-encrypt.cpp, lang/qt/test/t-tofuinfo.cpp: Assert on copy failure. * lang/qt/test/t-support.cpp (copyKeyrings): Fix path. diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp index 44cea96..3d4cfa9 100644 --- a/lang/qt/tests/t-encrypt.cpp +++ b/lang/qt/tests/t-encrypt.cpp @@ -242,7 +242,7 @@ public Q_SLOT: Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); agentConf.write("allow-loopback-pinentry"); agentConf.close(); - copyKeyrings(gpgHome, mDir.path()); + Q_ASSERT(copyKeyrings(gpgHome, mDir.path())); } private: diff --git a/lang/qt/tests/t-support.cpp b/lang/qt/tests/t-support.cpp index 73e8d5c..27c0132 100644 --- a/lang/qt/tests/t-support.cpp +++ b/lang/qt/tests/t-support.cpp @@ -50,7 +50,7 @@ bool QGpgMETest::copyKeyrings(const QString &src, const QString &dest) bool is21dir = QFileInfo(src + QDir::separator() + QStringLiteral("pubring.kbx")).exists(); const QString name = is21dir ? QStringLiteral("pubring.kbx") : QStringLiteral("pubring.gpg"); - if (!QFile::copy(src + name, dest + QDir::separator() + name)) { + if (!QFile::copy(src + QDir::separator() + name, dest + QDir::separator() + name)) { return false; } if (!is21dir) { diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index 7eea1ea..d306167 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -239,7 +239,7 @@ private Q_SLOTS: Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); agentConf.write("allow-loopback-pinentry"); agentConf.close(); - copyKeyrings(gpgHome, mDir.path()); + Q_ASSERT(copyKeyrings(gpgHome, mDir.path())); } private: QTemporaryDir mDir; commit 4e37d0bb1255558ce20e1a5ac83a2d06a37f8b0b Author: Andre Heinecke Date: Thu Aug 25 16:22:12 2016 +0200 qt: Add generic flag support for keylistjobs * lang/qt/src/keylistjob.h (addMode): New. * lang/qt/src/qgpgmekeylistjob.h (addMode): New. * lang/qt/src/qgpgmekeylistjob.cpp (addMode: New. -- Instead of new API for each new thing lets be a bit more generic / open. diff --git a/lang/qt/src/keylistjob.h b/lang/qt/src/keylistjob.h index fc7a048..8dc736e 100644 --- a/lang/qt/src/keylistjob.h +++ b/lang/qt/src/keylistjob.h @@ -96,6 +96,9 @@ public: virtual GpgME::KeyListResult exec(const QStringList &patterns, bool secretOnly, std::vector &keys) = 0; + /** Add a flag to the keylistmode used. */ + virtual void addMode(GpgME::KeyListMode mode) = 0; + Q_SIGNALS: void nextKey(const GpgME::Key &key); void result(const GpgME::KeyListResult &result, const std::vector &keys = std::vector(), const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error()); diff --git a/lang/qt/src/qgpgmekeylistjob.cpp b/lang/qt/src/qgpgmekeylistjob.cpp index 49a3c03..1169c46 100644 --- a/lang/qt/src/qgpgmekeylistjob.cpp +++ b/lang/qt/src/qgpgmekeylistjob.cpp @@ -151,6 +151,11 @@ void QGpgMEKeyListJob::resultHook(const result_type &tuple) Q_EMIT nextKey(key); } } + +void QGpgMEKeyListJob::addMode(KeyListMode mode) +{ + context()->addKeyListMode(mode); +} #if 0 void QGpgMEKeyListJob::showErrorDialog(QWidget *parent, const QString &caption) const { diff --git a/lang/qt/src/qgpgmekeylistjob.h b/lang/qt/src/qgpgmekeylistjob.h index cbe1e94..2d5406a 100644 --- a/lang/qt/src/qgpgmekeylistjob.h +++ b/lang/qt/src/qgpgmekeylistjob.h @@ -74,9 +74,10 @@ public: /* from KeyListJob */ GpgME::KeyListResult exec(const QStringList &patterns, bool secretOnly, std::vector &keys) Q_DECL_OVERRIDE; + void addMode(GpgME::KeyListMode mode) Q_DECL_OVERRIDE; + /* from ThreadedJobMixin */ void resultHook(const result_type &result) Q_DECL_OVERRIDE; - private: GpgME::KeyListResult mResult; bool mSecretOnly; commit 5a92cc96da183ebb19867a2a910f53ba41e76ae9 Author: Andre Heinecke Date: Thu Aug 25 16:19:39 2016 +0200 qt: Ensure that current src dir is included first * lang/qt/src/Makefile.am: Reorder include directives. -- This fixes the problem that QGpgME would pick up gpgme or gpgme++ headers from an installed version. diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 8f6d773..59206ed 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -199,8 +199,9 @@ nodist_include_HEADERS = qgpgme_version.h libqgpgme_la_SOURCES = $(qgpgme_sources) $(qgpgme_headers) $(private_qgpgme_headers) -AM_CPPFLAGS = @GPGME_QT_CFLAGS@ @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \ - -DBUILDING_QGPGME -I$(top_srcdir)/lang/cpp/src +AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/lang/cpp/src \ + @GPGME_QT_CFLAGS@ @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \ + -DBUILDING_QGPGME libqgpgme_la_LIBADD = ../../cpp/src/libgpgmepp.la ../../../src/libgpgme.la \ @LIBASSUAN_LIBS@ @GPGME_QT_LIBS@ commit f311b92ceaedb12c9e00a722b6b47bbe6b50871e Author: Andre Heinecke Date: Thu Aug 25 16:17:46 2016 +0200 cpp: Add WithTofu Keylist Mode * lang/cpp/src/context.cpp: Handle WithTofu. * lang/cpp/src/global.h (KeyListMode): Add WithTofu. * lang/cpp/src/util.h (add_to_gpgme_keylist_mode_t): Handle WithTofu. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 62cad20..564cff5 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1420,6 +1420,7 @@ std::ostream &operator<<(std::ostream &os, KeyListMode mode) CHECK(Signatures); CHECK(Validate); CHECK(Ephemeral); + CHECK(WithTofu); #undef CHECK return os << ')'; } diff --git a/lang/cpp/src/global.h b/lang/cpp/src/global.h index 3f12323..15cc027 100644 --- a/lang/cpp/src/global.h +++ b/lang/cpp/src/global.h @@ -61,7 +61,8 @@ enum KeyListMode { Signatures = 0x4, SignatureNotations = 0x8, Validate = 0x10, - Ephemeral = 0x20 + Ephemeral = 0x20, + WithTofu = 0x40 }; enum SignatureMode { NormalSignatureMode, Detached, Clearsigned }; diff --git a/lang/cpp/src/util.h b/lang/cpp/src/util.h index 8ccb0bf..b0d47e3 100644 --- a/lang/cpp/src/util.h +++ b/lang/cpp/src/util.h @@ -76,6 +76,9 @@ static inline gpgme_keylist_mode_t add_to_gpgme_keylist_mode_t(unsigned int oldm if (newmodes & GpgME::Validate) { oldmode |= GPGME_KEYLIST_MODE_VALIDATE; } + if (newmodes & GpgME::WithTofu) { + oldmode |= GPGME_KEYLIST_MODE_WITH_TOFU; + } #ifndef NDEBUG if (newmodes & ~(GpgME::Local | GpgME::Extern | GpgME::Signatures | GpgME::SignatureNotations | GpgME::Ephemeral | GpgME::Validate)) { //std::cerr << "GpgME::Context: keylist mode must be one of Local, " ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/context.cpp | 1 + lang/cpp/src/global.h | 3 +- lang/cpp/src/util.h | 3 ++ lang/qt/src/Makefile.am | 5 ++-- lang/qt/src/keylistjob.h | 3 ++ lang/qt/src/qgpgmekeylistjob.cpp | 5 ++++ lang/qt/src/qgpgmekeylistjob.h | 3 +- lang/qt/tests/t-encrypt.cpp | 2 +- lang/qt/tests/t-support.cpp | 2 +- lang/qt/tests/t-tofuinfo.cpp | 63 +++++++++++++++++++++++++++++++++------- 10 files changed, 73 insertions(+), 17 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Aug 25 17:17:10 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 25 Aug 2016 17:17:10 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-319-g05570bd 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 05570bd3d05fb3d7934c1122f0d5ef5fdbaa7974 (commit) from 9fc72e928bf2cf239bd3b0facdf33ceb1acc975b (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 05570bd3d05fb3d7934c1122f0d5ef5fdbaa7974 Author: Andre Heinecke Date: Thu Aug 25 17:16:25 2016 +0200 qt: Fix 2.1 t-support copy * lang/qt/src/t-support.cpp (copyKeyring): Fix seckey copy. diff --git a/lang/qt/tests/t-support.cpp b/lang/qt/tests/t-support.cpp index 27c0132..2b21ce7 100644 --- a/lang/qt/tests/t-support.cpp +++ b/lang/qt/tests/t-support.cpp @@ -63,7 +63,9 @@ bool QGpgMETest::copyKeyrings(const QString &src, const QString &dest) return false; } foreach (QString f, dir.entryList(QDir::Files)) { - if (!QFile::copy(src + QDir::separator() + f, dest + QDir::separator() + f)) { + if (!QFile::copy(dir.path() + QDir::separator() + f, + dest + QDir::separator() + + QStringLiteral("private-keys-v1.d") + QDir::separator() + f)) { return false; } } ----------------------------------------------------------------------- Summary of changes: lang/qt/tests/t-support.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 29 07:59:56 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 29 Aug 2016 07:59:56 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-12-gbdbd036 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 bdbd03608b6f508ac4732f9986a046de8a85a311 (commit) from 0a5a854510fda6e6990938a3fca424df868fe676 (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 bdbd03608b6f508ac4732f9986a046de8a85a311 Author: Werner Koch Date: Mon Aug 29 07:55:06 2016 +0200 gpg: Make decryption of -R work w/o --try-secret-key or --default-key. * g10/getkey.c (enum_secret_keys): At state 3 enumerate the keys in all cases not just when --try-all-secrets is used. -- Regression-due-to: 82b90eee100cf1c9680517059b2d35e295dd992a Reported-by: Carola Grunwald Signed-off-by: Werner Koch diff --git a/g10/getkey.c b/g10/getkey.c index 90083ba..8b17598 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3620,17 +3620,14 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) c->state++; break; - case 3: /* Init search context to try all keys. */ - if (opt.try_all_secrets) + case 3: /* Init search context to enum all secret keys. */ + err = getkey_bynames (&c->ctx, NULL, NULL, 1, &keyblock); + if (err) { - err = getkey_bynames (&c->ctx, NULL, NULL, 1, &keyblock); - if (err) - { - release_kbnode (keyblock); - keyblock = NULL; - getkey_end (c->ctx); - c->ctx = NULL; - } + release_kbnode (keyblock); + keyblock = NULL; + getkey_end (c->ctx); + c->ctx = NULL; } c->state++; break; ----------------------------------------------------------------------- Summary of changes: g10/getkey.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 29 11:53:25 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 29 Aug 2016 11:53:25 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-13-g2aa0701 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 2aa0701013f703ad93e17da3345c493c08aa04ee (commit) from bdbd03608b6f508ac4732f9986a046de8a85a311 (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 2aa0701013f703ad93e17da3345c493c08aa04ee Author: Werner Koch Date: Mon Aug 29 11:45:47 2016 +0200 common: Add a default socket name feature. * common/logging.c (log_set_socket_dir_cb): New. (socket_dir_cb): New. (set_file_fd): Allow "socket://". (fun_writer): Implement default socket name. * common/init.c (_init_common_subsystems): Register default socket. -- This change allows the use of log-file socket:// in any configuration file. Signed-off-by: Werner Koch diff --git a/common/init.c b/common/init.c index 591c854..8a86266 100644 --- a/common/init.c +++ b/common/init.c @@ -222,6 +222,9 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp) /* --version et al shall use estream as well. */ argparse_register_outfnc (writestring_via_estream); + + /* Logging shall use the standard socket directory as fallback. */ + log_set_socket_dir_cb (gnupg_socketdir); } diff --git a/common/logging.c b/common/logging.c index c70ba35..9a7ed1d 100644 --- a/common/logging.c +++ b/common/logging.c @@ -104,6 +104,7 @@ static int with_pid; static int no_registry; #endif static int (*get_pid_suffix_cb)(unsigned long *r_value); +static const char * (*socket_dir_cb)(void); static int running_detached; static int force_prefixes; @@ -218,6 +219,7 @@ fun_writer (void *cookie_arg, const void *buffer, size_t size) struct sockaddr_in srvr_addr_in; #ifndef HAVE_W32_SYSTEM struct sockaddr_un srvr_addr_un; + const char *name_for_err = ""; #endif size_t addrlen; struct sockaddr *srvr_addr = NULL; @@ -237,23 +239,41 @@ fun_writer (void *cookie_arg, const void *buffer, size_t size) pf = PF_INET; } #ifndef HAVE_W32_SYSTEM - else if (!strncmp (name, "socket://", 9) && name[9]) + else if (!strncmp (name, "socket://", 9)) name += 9; #endif if (af == AF_LOCAL) { -#ifdef HAVE_W32_SYSTEM addrlen = 0; -#else +#ifndef HAVE_W32_SYSTEM memset (&srvr_addr, 0, sizeof srvr_addr); srvr_addr_un.sun_family = af; - strncpy (srvr_addr_un.sun_path, - name, sizeof (srvr_addr_un.sun_path)-1); - srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0; - srvr_addr = (struct sockaddr *)&srvr_addr_un; - addrlen = SUN_LEN (&srvr_addr_un); -#endif + if (!*name && (name = socket_dir_cb ()) && *name) + { + if (strlen (name) + 7 < sizeof (srvr_addr_un.sun_path)-1) + { + strncpy (srvr_addr_un.sun_path, + name, sizeof (srvr_addr_un.sun_path)-1); + strcat (srvr_addr_un.sun_path, "/S.log"); + srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0; + srvr_addr = (struct sockaddr *)&srvr_addr_un; + addrlen = SUN_LEN (&srvr_addr_un); + name_for_err = srvr_addr_un.sun_path; + } + } + else + { + if (*name && strlen (name) < sizeof (srvr_addr_un.sun_path)-1) + { + strncpy (srvr_addr_un.sun_path, + name, sizeof (srvr_addr_un.sun_path)-1); + srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0; + srvr_addr = (struct sockaddr *)&srvr_addr_un; + addrlen = SUN_LEN (&srvr_addr_un); + } + } +#endif /*!HAVE_W32SYSTEM*/ } else { @@ -352,8 +372,8 @@ fun_writer (void *cookie_arg, const void *buffer, size_t size) { if (!cookie->quiet && !running_detached && isatty (es_fileno (es_stderr))) - es_fprintf (es_stderr, "can't connect to '%s': %s\n", - cookie->name, strerror(errno)); + es_fprintf (es_stderr, "can't connect to '%s%s': %s\n", + cookie->name, name_for_err, strerror(errno)); sock_close (cookie->fd); cookie->fd = -1; } @@ -462,7 +482,7 @@ set_file_fd (const char *name, int fd) if (name && !strncmp (name, "tcp://", 6) && name[6]) want_socket = 1; #ifndef HAVE_W32_SYSTEM - else if (name && !strncmp (name, "socket://", 9) && name[9]) + else if (name && !strncmp (name, "socket://", 9)) want_socket = 2; #endif /*HAVE_W32_SYSTEM*/ #ifdef HAVE_W32CE_SYSTEM @@ -554,6 +574,15 @@ log_set_fd (int fd) } +/* Set a function to retrieve the directory name of a socket if + * only "socket://" has been given to log_set_file. */ +void +log_set_socket_dir_cb (const char *(*fnc)(void)) +{ + socket_dir_cb = fnc; +} + + void log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value)) { diff --git a/common/logging.h b/common/logging.h index 2f0b504..165a573 100644 --- a/common/logging.h +++ b/common/logging.h @@ -42,6 +42,7 @@ int log_get_errorcount (int clear); void log_inc_errorcount (void); void log_set_file( const char *name ); void log_set_fd (int fd); +void log_set_socket_dir_cb (const char *(*fnc)(void)); void log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value)); void log_set_prefix (const char *text, unsigned int flags); const char *log_get_prefix (unsigned int *flags); diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index d52fb89..b6b70ea 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -163,7 +163,8 @@ verbose commands to @sc{dirmngr}, such as @option{-vv}. @item --log-file @var{file} @opindex log-file Append all logging output to @var{file}. This is very helpful in -seeing what the agent actually does. +seeing what the agent actually does. Use @file{socket://} to log to +socket. @item --debug-level @var{level} @opindex debug-level diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index b481dd6..b890c21 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -312,11 +312,12 @@ should in general not be used to avoid X-sniffing attacks. @item --log-file @var{file} @opindex log-file @efindex HKCU\Software\GNU\GnuPG:DefaultLogFile -Append all logging output to @var{file}. This is very helpful in seeing -what the agent actually does. If neither a log file nor a log file -descriptor has been set on a Windows platform, the Registry entry - at code{HKCU\Software\GNU\GnuPG:DefaultLogFile}, if set, is used to specify -the logging output. +Append all logging output to @var{file}. This is very helpful in +seeing what the agent actually does. Use @file{socket://} to log to +socket. If neither a log file nor a log file descriptor has been set +on a Windows platform, the Registry entry + at code{HKCU\Software\GNU\GnuPG:DefaultLogFile}, if set, is used to +specify the logging output. @anchor{option --no-allow-mark-trusted} diff --git a/doc/gpg.texi b/doc/gpg.texi index fbcaa15..68b21b6 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2697,9 +2697,8 @@ Write log output to file descriptor @code{n} and not to STDERR. @item --log-file @code{file} @itemx --logger-file @code{file} @opindex log-file -Same as @option{--logger-fd}, except the logger data is written to file - at code{file}. Note that @option{--log-file} is only implemented for -GnuPG-2. +Same as @option{--logger-fd}, except the logger data is written to +file @code{file}. Use @file{socket://} to log to socket. @item --attribute-fd @code{n} @opindex attribute-fd diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index dae26b2..7cee0f3 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -384,6 +384,7 @@ Do not print a warning when the so called "secure memory" cannot be used. @item --log-file @var{file} @opindex log-file When running in server mode, append all logging output to @var{file}. +Use @file{socket://} to log to socket. @end table diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index c145814..85a80f0 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -239,7 +239,8 @@ debugging. @item --log-file @var{file} @opindex log-file Append all logging output to @var{file}. This is very helpful in -seeing what the agent actually does. +seeing what the agent actually does. Use @file{socket://} to log to +socket. @item --pcsc-driver @var{library} diff --git a/doc/tools.texi b/doc/tools.texi index d6cf56e..18f5d77 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -103,12 +103,14 @@ This waits for connections on the local socket @file{/home/foo/.gnupg/S.log} and shows all log entries. To make this work the option @option{log-file} needs to be used with all modules which logs are to be shown. The value for that option must be given -with a special prefix (e.g. in the conf file): +with a special prefix (e.g. in the conf files): @example log-file socket:///home/foo/.gnupg/S.log @end example +If only @code{socket://} is used a default socket file named + at file{S.log} in the standard socket directory is used. For debugging purposes it is also possible to do remote logging. Take care if you use this feature because the information is send in the clear over the network. Use this syntax in the conf files: @@ -1737,8 +1739,8 @@ Try to be as quiet as possible. @item --log-file @var{file} @opindex log-file -Append all logging output to @var{file}. Default is to write logging -information to STDERR. +Append all logging output to @var{file}. Use @file{socket://} to log +to socket. Default is to write logging information to STDERR. @end table ----------------------------------------------------------------------- Summary of changes: common/init.c | 3 +++ common/logging.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ common/logging.h | 1 + doc/dirmngr.texi | 3 ++- doc/gpg-agent.texi | 11 ++++++----- doc/gpg.texi | 5 ++--- doc/gpgsm.texi | 1 + doc/scdaemon.texi | 3 ++- doc/tools.texi | 8 +++++--- 9 files changed, 63 insertions(+), 25 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 29 11:55:31 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 29 Aug 2016 11:55:31 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-14-g8e3fa5a 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 8e3fa5a4b205c534de2142e5d071712f957cf06a (commit) from 2aa0701013f703ad93e17da3345c493c08aa04ee (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 8e3fa5a4b205c534de2142e5d071712f957cf06a Author: Werner Koch Date: Mon Aug 29 11:53:06 2016 +0200 gpgconf: Print the plain socket directory with --list-dirs. * tools/gpgconf.c (list_dirs): Add plain socketdir out. Signed-off-by: Werner Koch diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 221e3e2..bdebadb 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -163,6 +163,7 @@ list_dirs (estream_t fp, char **names) { "libdir", gnupg_libdir, NULL }, { "datadir", gnupg_datadir, NULL }, { "localedir", gnupg_localedir, NULL }, + { "socketdir", gnupg_socketdir, NULL }, { "dirmngr-socket", dirmngr_socket_name, NULL,}, { "agent-ssh-socket", gnupg_socketdir, GPG_AGENT_SSH_SOCK_NAME }, { "agent-socket", gnupg_socketdir, GPG_AGENT_SOCK_NAME }, ----------------------------------------------------------------------- Summary of changes: tools/gpgconf.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Aug 29 20:07:33 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 29 Aug 2016 20:07:33 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-15-g8b3e691 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 8b3e691ffbaaa218d309d5aaf8f37532308558ff (commit) from 8e3fa5a4b205c534de2142e5d071712f957cf06a (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 8b3e691ffbaaa218d309d5aaf8f37532308558ff Author: Werner Koch Date: Mon Aug 29 20:05:02 2016 +0200 w32: Fix build regression due to 2aa0701. * common/logging.c (fun_writer): Always declare 'name_for_err'. -- Regression-due-to: 2aa0701013f703ad93e17da3345c493c08aa04ee Signed-off-by: Werner Koch diff --git a/common/logging.c b/common/logging.c index 9a7ed1d..019d312 100644 --- a/common/logging.c +++ b/common/logging.c @@ -219,8 +219,8 @@ fun_writer (void *cookie_arg, const void *buffer, size_t size) struct sockaddr_in srvr_addr_in; #ifndef HAVE_W32_SYSTEM struct sockaddr_un srvr_addr_un; - const char *name_for_err = ""; #endif + const char *name_for_err = ""; size_t addrlen; struct sockaddr *srvr_addr = NULL; unsigned short port = 0; ----------------------------------------------------------------------- Summary of changes: common/logging.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 Tue Aug 30 16:07:08 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 30 Aug 2016 16:07:08 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-23-g371ae66 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 371ae66e9d5c7524431773c4a479fcae1ea3b652 (commit) via 3beeaa70bdbde65f93adbb30d52b9c376963ac42 (commit) via d0451440c036106895a291f9ca1c53c2d5159f8f (commit) via 6052c147091935fc0321ba24f4a44146df70ef01 (commit) via 33e97813d72996d22a295773c64261f5588ce9dd (commit) via 4c2abb221b29c9e8e0876fe986472b562ee1c99f (commit) via 0858f141a8b8d0c098a0c6097176b7225c4a9db8 (commit) via 8dda861ad80228da76cd5c97467008c87b8b6eee (commit) from 8b3e691ffbaaa218d309d5aaf8f37532308558ff (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 371ae66e9d5c7524431773c4a479fcae1ea3b652 Author: Neal H. Walfield Date: Tue Aug 30 15:37:45 2016 +0200 g10: Improve TOFU batch update code. * g10/gpg.h (tofu): Rename field batch_update_ref to batch_updated_wanted. * g10/tofu.c (struct tofu_dbs_s): Rename field batch_update to in_batch_transaction. (begin_transaction): Only end an extant batch transaction if we are not in a normal transaction. When ending a batch transaction, really end it. Update ctrl->tofu.batch_update_started when starting a batch transaction. (end_transaction): Only release a batch transaction if ONLY_BATCH is true. When releasing a batch transaction, assert that there is no open normal transaction. Only allow DBS to be NULL if ONLY_BATCH is true. (tofu_begin_batch_update): Don't update ctrl->tofu.batch_update_started. (opendbs): Call end_transaction unconditionally. -- Signed-off-by: Neal H. Walfield diff --git a/g10/gpg.h b/g10/gpg.h index 154da0d..33a3af6 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -83,7 +83,7 @@ struct server_control_s struct { tofu_dbs_t dbs; int in_transaction; - int batch_update_ref; + int batch_updated_wanted; time_t batch_update_started; } tofu; diff --git a/g10/tofu.c b/g10/tofu.c index 338fb3e..f84609e 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -81,7 +81,7 @@ struct tofu_dbs_s sqlite3_stmt *register_insert; } s; - int batch_update; + int in_batch_transaction; }; @@ -169,26 +169,39 @@ begin_transaction (ctrl_t ctrl, int only_batch) log_assert (dbs); - if (ctrl->tofu.batch_update_ref + /* If we've been in batch update mode for a while (on average, more + * than 500 ms), to prevent starving other gpg processes, we drop + * and retake the batch lock. + * + * Note: if we wanted higher resolution, we could use + * npth_clock_gettime. */ + if (/* No real transactions. */ + ctrl->tofu.in_transaction == 0 + /* There is an open batch transaction. */ + && dbs->in_batch_transaction + /* And some time has gone by since it was started. */ && ctrl->tofu.batch_update_started != gnupg_get_time ()) { - /* We've been in batch update mode for a while (on average, more - * than 500 ms). To prevent starving other gpg processes, we - * drop and retake the batch lock. - * - * Note: if we wanted higher resolution, we could use - * npth_clock_gettime. */ - if (dbs->batch_update) - end_transaction (ctrl, 1); + /* If we are in a batch update, then batch updates better have + been enabled. */ + log_assert (ctrl->tofu.batch_updated_wanted); - ctrl->tofu.batch_update_started = gnupg_get_time (); + end_transaction (ctrl, 2); /* Yield to allow another process a chance to run. */ gpgrt_yield (); } - if (ctrl->tofu.batch_update_ref && !dbs->batch_update) + if (/* Batch mode is enabled. */ + ctrl->tofu.batch_updated_wanted + /* But we don't have an open batch transaction. */ + && !dbs->in_batch_transaction) { + /* We are in batch mode, but we don't have an open batch + * transaction. Since the batch save point must be the outer + * save point, it must be taken before the inner save point. */ + log_assert (ctrl->tofu.in_transaction == 0); + rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch, NULL, NULL, &err, "savepoint batch;", SQLITE_ARG_END); @@ -200,7 +213,8 @@ begin_transaction (ctrl_t ctrl, int only_batch) return gpg_error (GPG_ERR_GENERAL); } - dbs->batch_update = 1; + dbs->in_batch_transaction = 1; + ctrl->tofu.batch_update_started = gnupg_get_time (); } if (only_batch) @@ -235,35 +249,44 @@ end_transaction (ctrl_t ctrl, int only_batch) int rc; char *err = NULL; - if (!dbs) - return 0; /* Shortcut to allow for easier cleanup code. */ - - if ((!ctrl->tofu.batch_update_ref || only_batch == 2) && dbs->batch_update) + if (only_batch) { - /* The batch transaction is still in open, but we left batch - * mode. */ - dbs->batch_update = 0; + if (!dbs) + return 0; /* Shortcut to allow for easier cleanup code. */ - rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch_commit, - NULL, NULL, &err, - "release batch;", SQLITE_ARG_END); - if (rc) + /* If we are releasing the batch transaction, then we better not + be in a normal transaction. */ + log_assert (ctrl->tofu.in_transaction == 0); + + if (/* Batch mode disabled? */ + (!ctrl->tofu.batch_updated_wanted || only_batch == 2) + /* But, we still have an open batch transaction? */ + && dbs->in_batch_transaction) { - log_error (_("error committing transaction on TOFU database: %s\n"), - err); - sqlite3_free (err); - return gpg_error (GPG_ERR_GENERAL); + /* The batch transaction is still in open, but we've left + * batch mode. */ + dbs->in_batch_transaction = 0; + + rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch_commit, + NULL, NULL, &err, + "release batch;", SQLITE_ARG_END); + if (rc) + { + log_error (_("error committing transaction on TOFU database: %s\n"), + err); + sqlite3_free (err); + return gpg_error (GPG_ERR_GENERAL); + } + + return 0; } - /* Releasing an outer transaction releases an open inner - transactions. We're done. */ return 0; } - if (only_batch) - return 0; - + log_assert (dbs); log_assert (ctrl->tofu.in_transaction > 0); + rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, "release inner%d;", ctrl->tofu.in_transaction); if (rc) @@ -287,8 +310,7 @@ rollback_transaction (ctrl_t ctrl) int rc; char *err = NULL; - if (!dbs) - return 0; /* Shortcut to allow for easier cleanup code. */ + log_assert (dbs); log_assert (ctrl->tofu.in_transaction > 0); /* Be careful to not any progress made by closed transactions in @@ -313,19 +335,16 @@ rollback_transaction (ctrl_t ctrl) void tofu_begin_batch_update (ctrl_t ctrl) { - if (!ctrl->tofu.batch_update_ref) - ctrl->tofu.batch_update_started = gnupg_get_time (); - - ctrl->tofu.batch_update_ref ++; + ctrl->tofu.batch_updated_wanted ++; } void tofu_end_batch_update (ctrl_t ctrl) { - log_assert (ctrl->tofu.batch_update_ref > 0); - ctrl->tofu.batch_update_ref --; + log_assert (ctrl->tofu.batch_updated_wanted > 0); + ctrl->tofu.batch_updated_wanted --; - if (!ctrl->tofu.batch_update_ref) + if (!ctrl->tofu.batch_updated_wanted) end_transaction (ctrl, 1); } @@ -693,14 +712,13 @@ tofu_closedbs (ctrl_t ctrl) tofu_dbs_t dbs; sqlite3_stmt **statements; - log_assert(ctrl->tofu.in_transaction == 0); + log_assert (ctrl->tofu.in_transaction == 0); dbs = ctrl->tofu.dbs; if (!dbs) return; /* Not initialized. */ - if (dbs->batch_update) - end_transaction (ctrl, 2); + end_transaction (ctrl, 2); /* Arghh, that is a surprising use of the struct. */ for (statements = (void *) &dbs->s; commit 3beeaa70bdbde65f93adbb30d52b9c376963ac42 Author: Neal H. Walfield Date: Tue Aug 30 12:33:23 2016 +0200 g10: Improve TOFU debugging output and some comments. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 055f68d..338fb3e 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -702,7 +702,7 @@ tofu_closedbs (ctrl_t ctrl) if (dbs->batch_update) end_transaction (ctrl, 2); - /* Arghh, that is asurprising use of the struct. */ + /* Arghh, that is a surprising use of the struct. */ for (statements = (void *) &dbs->s; (void *) statements < (void *) &(&dbs->s)[1]; statements ++) @@ -777,24 +777,25 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, if (rc) { log_debug ("TOFU: Error reading from binding database" - " (reading policy for <%s, %s>): %s\n", + " (reading policy for ): %s\n", fingerprint, email, err); sqlite3_free (err); } - } - if (DBG_TRUST) - { - if (policy_old != TOFU_POLICY_NONE) - log_debug ("Changing TOFU trust policy for binding <%s, %s>" - " from %s to %s.\n", - fingerprint, email, - tofu_policy_str (policy_old), - tofu_policy_str (policy)); - else - log_debug ("Set TOFU trust policy for binding <%s, %s> to %s.\n", - fingerprint, email, - tofu_policy_str (policy)); + if (DBG_TRUST) + { + if (policy_old != TOFU_POLICY_NONE) + log_debug ("Changing TOFU trust policy for binding" + " from %s to %s.\n", + fingerprint, email, + tofu_policy_str (policy_old), + tofu_policy_str (policy)); + else + log_debug ("Setting TOFU trust policy for new binding" + " to %s.\n", + fingerprint, email, + tofu_policy_str (policy)); + } } if (policy_old == policy) @@ -827,7 +828,7 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, if (rc) { log_error (_("error updating TOFU database: %s\n"), err); - print_further_info (" insert bindings <%s, %s> = %s", + print_further_info (" insert bindings = %s", fingerprint, email, tofu_policy_str (policy)); sqlite3_free (err); goto leave; @@ -1072,7 +1073,7 @@ get_policy (tofu_dbs_t dbs, const char *fingerprint, const char *email, /* If CONFLICT is set, then policy should be TOFU_POLICY_ASK. But, just in case, we do the check again here and ignore the conflict - is POLICY is not TOFU_POLICY_ASK. */ + if POLICY is not TOFU_POLICY_ASK. */ if (conflict) { if (policy == TOFU_POLICY_ASK && *strlist->next->d) @@ -1553,7 +1554,8 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, { policy = opt.tofu_default_policy; if (DBG_TRUST) - log_debug ("TOFU: binding <%s, %s>'s policy is auto (default: %s).\n", + log_debug ("TOFU: binding 's policy is " + " auto (default: %s).\n", fingerprint, email, tofu_policy_str (opt.tofu_default_policy)); } @@ -1566,7 +1568,7 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, /* The saved judgement is auto -> auto, good, unknown or bad. * We don't need to ask the user anything. */ if (DBG_TRUST) - log_debug ("TOFU: Known binding <%s, %s>'s policy: %s\n", + log_debug ("TOFU: Known binding 's policy: %s\n", fingerprint, email, tofu_policy_str (policy)); trust_level = tofu_policy_to_trust_level (policy); goto out; @@ -1646,8 +1648,8 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, log_assert (policy == TOFU_POLICY_NONE); if (DBG_TRUST) - log_debug ("TOFU: New binding <%s, %s>, no conflict.\n", - email, fingerprint); + log_debug ("TOFU: New binding , no conflict.\n", + fingerprint, email); if (record_binding (dbs, fingerprint, email, user_id, TOFU_POLICY_AUTO, 0) != 0) commit d0451440c036106895a291f9ca1c53c2d5159f8f Author: Neal H. Walfield Date: Tue Aug 30 12:36:55 2016 +0200 g10: If a key has no valid user ids, change TOFU to return TRUST_NEVER. * g10/tofu.c (tofu_get_validity): If a key has no valid (non-expired) user ids, change TOFU to return TRUST_NEVER. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index da09cd5..055f68d 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2444,6 +2444,8 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, char *fingerprint = NULL; strlist_t user_id; int trust_level = TRUST_UNKNOWN; + int bindings = 0; + int bindings_valid = 0; dbs = opendbs (ctrl); if (! dbs) @@ -2457,7 +2459,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, begin_transaction (ctrl, 0); - for (user_id = user_id_list; user_id; user_id = user_id->next) + for (user_id = user_id_list; user_id; user_id = user_id->next, bindings ++) { char *email = email_from_user_id (user_id->d); @@ -2481,6 +2483,9 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, if (user_id->flags) tl = TRUST_EXPIRED; + if (tl != TRUST_EXPIRED) + bindings_valid ++; + if (may_ask && tl != TRUST_ULTIMATE && tl != TRUST_EXPIRED) show_statistics (dbs, fingerprint, email, user_id->d, NULL, NULL); @@ -2512,6 +2517,16 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, end_transaction (ctrl, 0); xfree (fingerprint); + + if (bindings_valid == 0) + { + if (DBG_TRUST) + log_debug ("no (of %d) valid bindings." + " Can't get TOFU validity for this set of user ids.\n", + bindings); + return TRUST_NEVER; + } + return trust_level; } commit 6052c147091935fc0321ba24f4a44146df70ef01 Author: Neal H. Walfield Date: Mon Aug 29 16:16:44 2016 +0200 g10: Change tofu_register & tofu_get_validity to process multiple uids. * g10/tofu.c (tofu_register): Take a list of user ids, not a single user id. Only register the bindings, don't compute the trust. Thus, change return type to an int and remove the may_ask parameter. Update callers. (tofu_get_validity): Take a list of user ids, not a single user id. Update callers. Observe signatures made by expired user ids, but don't include them in the trust calculation. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 809dac9..da09cd5 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2164,8 +2164,9 @@ email_from_user_id (const char *user_id) return email; } -/* Register the signature with the binding . - The fingerprint is taken from the primary key packet PK. +/* Register the signature with the bindings , + for each USER_ID in USER_ID_LIST. The fingerprint is taken from + the primary key packet PK. SIG_DIGEST_BIN is the binary representation of the message's digest. SIG_DIGEST_BIN_LEN is its length. @@ -2181,159 +2182,152 @@ email_from_user_id (const char *user_id) This is necessary if there is a conflict or the binding's policy is TOFU_POLICY_ASK. - This function returns the binding's trust level on return. If an - error occurs, this function returns TRUST_UNKNOWN. */ -int -tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, + This function returns 0 on success and an error code if an error + occured. */ +gpg_error_t +tofu_register (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, const byte *sig_digest_bin, int sig_digest_bin_len, - time_t sig_time, const char *origin, int may_ask) + time_t sig_time, const char *origin) { + gpg_error_t rc; tofu_dbs_t dbs; char *fingerprint = NULL; + strlist_t user_id; char *email = NULL; char *err = NULL; - int rc; - int trust_level = TRUST_UNKNOWN; char *sig_digest; unsigned long c; - int already_verified = 0; - - sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len); dbs = opendbs (ctrl); if (! dbs) { + rc = gpg_error (GPG_ERR_GENERAL); log_error (_("error opening TOFU database: %s\n"), - gpg_strerror (GPG_ERR_GENERAL)); - goto die; + gpg_strerror (rc)); + return rc; } - fingerprint = hexfingerprint (pk, NULL, 0); - - if (! *user_id) - { - log_debug ("TOFU: user id is empty. Can't continue.\n"); - goto die; - } + /* We do a query and then an insert. Make sure they are atomic + by wrapping them in a transaction. */ + rc = begin_transaction (ctrl, 0); + if (rc) + return rc; - email = email_from_user_id (user_id); + sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len); + fingerprint = hexfingerprint (pk, NULL, 0); if (! origin) /* The default origin is simply "unknown". */ origin = "unknown"; - /* It's necessary to get the trust so that we are certain that the - binding has been registered. */ - trust_level = get_trust (dbs, pk, fingerprint, email, user_id, may_ask); - if (trust_level == _tofu_GET_TRUST_ERROR) - /* An error. */ + for (user_id = user_id_list; user_id; user_id = user_id->next) { - trust_level = TRUST_UNKNOWN; - goto die; - } + email = email_from_user_id (user_id->d); - /* We do a query and then an insert. Make sure they are atomic - by wrapping them in a transaction. */ - rc = begin_transaction (ctrl, 0); - if (rc) - goto die; - - /* If we've already seen this signature before, then don't add - it again. */ - rc = gpgsql_stepx - (dbs->db, &dbs->s.register_already_seen, - get_single_unsigned_long_cb2, &c, &err, - "select count (*)\n" - " from signatures left join bindings\n" - " on signatures.binding = bindings.oid\n" - " where fingerprint = ? and email = ? and sig_time = ?\n" - " and sig_digest = ?", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_LONG_LONG, (long long) sig_time, - SQLITE_ARG_STRING, sig_digest, - SQLITE_ARG_END); - if (rc) - { - log_error (_("error reading TOFU database: %s\n"), err); - print_further_info ("checking existence"); - sqlite3_free (err); - } - else if (c > 1) - /* Duplicates! This should not happen. In particular, - because is the - primary key! */ - log_debug ("SIGNATURES DB contains duplicate records" - " <%s, %s, 0x%lx, %s, %s>." - " Please report.\n", - fingerprint, email, (unsigned long) sig_time, - sig_digest, origin); - else if (c == 1) - { - already_verified = 1; - if (DBG_TRUST) - log_debug ("Already observed the signature" - " <%s, %s, 0x%lx, %s, %s>\n", - fingerprint, email, (unsigned long) sig_time, - sig_digest, origin); - } - else if (opt.dry_run) - { - log_info ("TOFU database update skipped due to --dry-run\n"); - } - else - /* This is the first time that we've seen this signature. - Record it. */ - { if (DBG_TRUST) - log_debug ("TOFU: Saving signature <%s, %s, %s>\n", - fingerprint, email, sig_digest); - - log_assert (c == 0); + log_debug ("TOFU: Registering signature %s with binding" + " \n", + sig_digest, fingerprint, email); + + /* Make sure the binding exists and record any TOFU + conflicts. */ + if (get_trust (dbs, pk, fingerprint, email, user_id->d, 0) + == _tofu_GET_TRUST_ERROR) + { + rc = gpg_error (GPG_ERR_GENERAL); + xfree (email); + break; + } + /* If we've already seen this signature before, then don't add + it again. */ rc = gpgsql_stepx - (dbs->db, &dbs->s.register_insert, NULL, NULL, &err, - "insert into signatures\n" - " (binding, sig_digest, origin, sig_time, time)\n" - " values\n" - " ((select oid from bindings\n" - " where fingerprint = ? and email = ?),\n" - " ?, ?, ?, strftime('%s', 'now'));", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_STRING, sig_digest, SQLITE_ARG_STRING, origin, + (dbs->db, &dbs->s.register_already_seen, + get_single_unsigned_long_cb2, &c, &err, + "select count (*)\n" + " from signatures left join bindings\n" + " on signatures.binding = bindings.oid\n" + " where fingerprint = ? and email = ? and sig_time = ?\n" + " and sig_digest = ?", + SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, SQLITE_ARG_LONG_LONG, (long long) sig_time, + SQLITE_ARG_STRING, sig_digest, SQLITE_ARG_END); if (rc) - { - log_error (_("error updating TOFU database: %s\n"), err); - print_further_info ("insert signatures"); - sqlite3_free (err); - } + { + log_error (_("error reading TOFU database: %s\n"), err); + print_further_info ("checking existence"); + sqlite3_free (err); + } + else if (c > 1) + /* Duplicates! This should not happen. In particular, + because is the + primary key! */ + log_debug ("SIGNATURES DB contains duplicate records" + " ." + " Please report.\n", + fingerprint, email, (unsigned long) sig_time, + sig_digest, origin); + else if (c == 1) + { + if (DBG_TRUST) + log_debug ("Already observed the signature and binding" + " \n", + fingerprint, email, (unsigned long) sig_time, + sig_digest, origin); + } + else if (opt.dry_run) + { + log_info ("TOFU database update skipped due to --dry-run\n"); + } + else + /* This is the first time that we've seen this signature and + binding. Record it. */ + { + if (DBG_TRUST) + log_debug ("TOFU: Saving signature" + " \n", + fingerprint, email, sig_digest); + + log_assert (c == 0); + + rc = gpgsql_stepx + (dbs->db, &dbs->s.register_insert, NULL, NULL, &err, + "insert into signatures\n" + " (binding, sig_digest, origin, sig_time, time)\n" + " values\n" + " ((select oid from bindings\n" + " where fingerprint = ? and email = ?),\n" + " ?, ?, ?, strftime('%s', 'now'));", + SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, + SQLITE_ARG_STRING, sig_digest, SQLITE_ARG_STRING, origin, + SQLITE_ARG_LONG_LONG, (long long) sig_time, + SQLITE_ARG_END); + if (rc) + { + log_error (_("error updating TOFU database: %s\n"), err); + print_further_info ("insert signatures"); + sqlite3_free (err); + } + } + + xfree (email); + + if (rc) + break; } - /* It only matters whether we abort or commit the transaction - (so long as we do something) if we execute the insert. */ if (rc) - rc = rollback_transaction (ctrl); + rollback_transaction (ctrl); else rc = end_transaction (ctrl, 0); - if (rc) - { - sqlite3_free (err); - goto die; - } - die: - if (may_ask && trust_level != TRUST_ULTIMATE) - /* It's only appropriate to show the statistics in an interactive - context. */ - show_statistics (dbs, fingerprint, email, user_id, - already_verified ? NULL : sig_digest, NULL); - - xfree (email); xfree (fingerprint); xfree (sig_digest); - return trust_level; + return rc; } /* Combine a trust level returned from the TOFU trust model with a @@ -2431,8 +2425,9 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, } -/* Return the validity (TRUST_NEVER, etc.) of the binding - . +/* Return the validity (TRUST_NEVER, etc.) of the bindings + , for each USER_ID in USER_ID_LIST. If + USER_ID_LIST->FLAG is set, then the id is considered to be expired. PK is the primary key packet. @@ -2442,43 +2437,80 @@ tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, Returns TRUST_UNDEFINED if an error occurs. */ int -tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, +tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, int may_ask) { tofu_dbs_t dbs; char *fingerprint = NULL; - char *email = NULL; - int trust_level = TRUST_UNDEFINED; + strlist_t user_id; + int trust_level = TRUST_UNKNOWN; dbs = opendbs (ctrl); if (! dbs) { log_error (_("error opening TOFU database: %s\n"), gpg_strerror (GPG_ERR_GENERAL)); - goto die; + return TRUST_UNDEFINED; } fingerprint = hexfingerprint (pk, NULL, 0); - if (! *user_id) + begin_transaction (ctrl, 0); + + for (user_id = user_id_list; user_id; user_id = user_id->next) { - log_debug ("user id is empty." - " Can't get TOFU validity for this binding.\n"); - goto die; - } + char *email = email_from_user_id (user_id->d); - email = email_from_user_id (user_id); + /* Always call get_trust to make sure the binding is + registered. */ + int tl = get_trust (dbs, pk, fingerprint, email, user_id->d, may_ask); + if (tl == _tofu_GET_TRUST_ERROR) + { + /* An error. */ + trust_level = TRUST_UNDEFINED; + xfree (email); + goto die; + } - trust_level = get_trust (dbs, pk, fingerprint, email, user_id, may_ask); - if (trust_level == _tofu_GET_TRUST_ERROR) - /* An error. */ - trust_level = TRUST_UNDEFINED; + if (DBG_TRUST) + log_debug ("TOFU: validity for : %s%s.\n", + fingerprint, email, + trust_value_to_string (tl), + user_id->flags ? " (but expired)" : ""); + + if (user_id->flags) + tl = TRUST_EXPIRED; - if (may_ask && trust_level != TRUST_ULTIMATE) - show_statistics (dbs, fingerprint, email, user_id, NULL, NULL); + if (may_ask && tl != TRUST_ULTIMATE && tl != TRUST_EXPIRED) + show_statistics (dbs, fingerprint, email, user_id->d, NULL, NULL); + + if (tl == TRUST_NEVER) + trust_level = TRUST_NEVER; + else if (tl == TRUST_EXPIRED) + /* Ignore expired bindings in the trust calculation. */ + ; + else if (tl > trust_level) + { + /* The expected values: */ + log_assert (tl == TRUST_UNKNOWN || tl == TRUST_UNDEFINED + || tl == TRUST_MARGINAL || tl == TRUST_FULLY + || tl == TRUST_ULTIMATE); + + /* We assume the following ordering: */ + log_assert (TRUST_UNKNOWN < TRUST_UNDEFINED); + log_assert (TRUST_UNDEFINED < TRUST_MARGINAL); + log_assert (TRUST_MARGINAL < TRUST_FULLY); + log_assert (TRUST_FULLY < TRUST_ULTIMATE); + + trust_level = tl; + } + + xfree (email); + } die: - xfree (email); + end_transaction (ctrl, 0); + xfree (fingerprint); return trust_level; } diff --git a/g10/tofu.h b/g10/tofu.h index d6854e9..b9826c9 100644 --- a/g10/tofu.h +++ b/g10/tofu.h @@ -59,7 +59,7 @@ enum tofu_policy TOFU_POLICY_ASK = 5, - /* Privat evalue used only within tofu.c. */ + /* Private value used only within tofu.c. */ _tofu_GET_POLICY_ERROR = 100 }; @@ -72,16 +72,19 @@ const char *tofu_policy_str (enum tofu_policy policy); (e.g., TRUST_BAD) in light of the current configuration. */ int tofu_policy_to_trust_level (enum tofu_policy policy); -/* Register the binding and the signature - described by SIGS_DIGEST and SIG_TIME, which it generated. Origin - describes where the signed data came from, e.g., "email:claws" - (default: "unknown"). If MAY_ASK is 1, then this function may - interact with the user in the case of a conflict or if the - binding's policy is ask. This function returns the binding's trust - level. If an error occurs, it returns TRUST_UNKNOWN. */ -int tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, - const byte *sigs_digest, int sigs_digest_len, - time_t sig_time, const char *origin, int may_ask); +/* Register the bindings , for each USER_ID in + USER_ID_LIST, and the signature described by SIGS_DIGEST and + SIG_TIME, which it generated. Origin describes where the signed + data came from, e.g., "email:claws" (default: "unknown"). Note: + this function does not interact with the user, If there is a + conflict, or if the binding's policy is ask, the actual interaction + is deferred until tofu_get_validity is called.. Set the string + list FLAG to indicate that a specified user id is expired. This + function returns 0 on success and an error code on failure. */ +gpg_error_t tofu_register (ctrl_t ctrl, PKT_public_key *pk, + strlist_t user_id_list, + const byte *sigs_digest, int sigs_digest_len, + time_t sig_time, const char *origin); /* Combine a trust level returned from the TOFU trust model with a trust level returned by the PGP trust model. This is primarily of @@ -92,12 +95,15 @@ int tofu_wot_trust_combine (int tofu, int wot); gpg_error_t tofu_write_tfs_record (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, const char *user_id); -/* Determine the validity (TRUST_NEVER, etc.) of the binding - . If MAY_ASK is 1, then this function may - interact with the user. If not, TRUST_UNKNOWN is returned. If an - error occurs, TRUST_UNDEFINED is returned. */ +/* Determine the validity (TRUST_NEVER, etc.) of the binding . If MAY_ASK is 1, then this function may interact with + the user. If not, TRUST_UNKNOWN is returned if an interaction is + required. Set the string list FLAGS to indicate that a specified + user id is expired. If an error occurs, TRUST_UNDEFINED is + returned. */ int tofu_get_validity (ctrl_t ctrl, - PKT_public_key *pk, const char *user_id, int may_ask); + PKT_public_key *pk, strlist_t user_id_list, + int may_ask); /* Set the policy for all non-revoked user ids in the keyblock KB to POLICY. */ diff --git a/g10/trustdb.c b/g10/trustdb.c index dd74d18..4181240 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -988,7 +988,7 @@ tdb_get_validity_core (ctrl_t ctrl, int may_ask) { TRUSTREC trec, vrec; - gpg_error_t err; + gpg_error_t err = 0; ulong recno; #ifdef USE_TOFU unsigned int tofu_validity = TRUST_UNKNOWN; @@ -1022,21 +1022,18 @@ tdb_get_validity_core (ctrl_t ctrl, #ifdef USE_TOFU if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP) { - kbnode_t user_id_node = NULL; - kbnode_t n = NULL; /* Silence -Wmaybe-uninitialized. */ - int user_ids = 0; - int user_ids_expired = 0; + kbnode_t kb = NULL; + kbnode_t n = NULL; + strlist_t user_id_list = NULL; - /* If the caller didn't supply a user id then iterate over all - uids. */ + /* If the caller didn't supply a user id then use all uids. */ if (! uid) - user_id_node = n = get_pubkeyblock (main_pk->keyid); + kb = n = get_pubkeyblock (main_pk->keyid); - while (uid - || (n = find_next_kbnode (n, PKT_USER_ID))) + while (uid || (n = find_next_kbnode (n, PKT_USER_ID))) { - unsigned int tl; PKT_user_id *user_id; + int expired = 0; if (uid) user_id = uid; @@ -1044,8 +1041,8 @@ tdb_get_validity_core (ctrl_t ctrl, user_id = n->pkt->pkt.user_id; /* If the user id is revoked or expired, then skip it. */ - if (user_id->is_revoked || user_id->is_expired) - { + if (user_id->is_revoked || user_id->is_expired) + { if (DBG_TRUST) { char *s; @@ -1060,42 +1057,48 @@ tdb_get_validity_core (ctrl_t ctrl, s, user_id->name); } - continue; - } + if (user_id->is_revoked) + continue; - user_ids ++; + expired = 1; + } - if (sig) - tl = tofu_register (ctrl, main_pk, user_id->name, - sig->digest, sig->digest_len, - sig->timestamp, "unknown", - may_ask); - else - tl = tofu_get_validity (ctrl, main_pk, user_id->name, may_ask); - - if (tl == TRUST_EXPIRED) - user_ids_expired ++; - else if (tl == TRUST_UNDEFINED || tl == TRUST_UNKNOWN) - ; - else if (tl == TRUST_NEVER) - tofu_validity = TRUST_NEVER; - else - { - log_assert (tl == TRUST_MARGINAL - || tl == TRUST_FULLY - || tl == TRUST_ULTIMATE); + add_to_strlist (&user_id_list, user_id->name); + user_id_list->flags = expired; - if (tl > tofu_validity) - /* XXX: We we really want the max? */ - tofu_validity = tl; - } + if (uid) + /* If the caller specified a user id, then we stop + now. */ + break; + } - if (uid) - /* If the caller specified a user id, then we stop - now. */ - break; - } - release_kbnode (user_id_node); + /* Process the user ids in the order they appear in the key + block. */ + strlist_rev (&user_id_list); + + /* It only makes sense to observe any signature before getting + the validity. This is because if the current signature + results in a conflict, then we damn well want to take that + into account. */ + if (sig) + { + err = tofu_register (ctrl, main_pk, user_id_list, + sig->digest, sig->digest_len, + sig->timestamp, "unknown"); + if (err) + { + log_error ("TOFU: error registering signature: %s\n", + gpg_strerror (err)); + + tofu_validity = TRUST_UNKNOWN; + } + } + if (! err) + tofu_validity = tofu_get_validity (ctrl, main_pk, user_id_list, + may_ask); + + free_strlist (user_id_list); + release_kbnode (kb); } #endif /*USE_TOFU*/ commit 33e97813d72996d22a295773c64261f5588ce9dd Author: Neal H. Walfield Date: Mon Aug 29 15:13:45 2016 +0200 g10: Support nested transactions on the TOFU DB. * g10/gpg.h (struct server_control_s): New field in_transaction. * g10/tofu.c (struct tofu_dbs_s): Remove fields savepoint_inner and savepoint_inner_commit. (begin_transaction): Increment CTRL->TOFU.IN_TRANSACTION. Name the savepoint according to the nesting level. (end_transaction): Name the savepoint according to the nesting level. Decrement CTRL->TOFU.IN_TRANSACTION. (rollback_transaction): Likewise. Only ever rollback a non-batch transaction. (opendbs): Assert that there are no outstanding transactions. -- Signed-off-by: Neal H. Walfield diff --git a/g10/gpg.h b/g10/gpg.h index 1aaff2f..154da0d 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -82,6 +82,7 @@ struct server_control_s /* Local data for tofu.c */ struct { tofu_dbs_t dbs; + int in_transaction; int batch_update_ref; time_t batch_update_started; } tofu; diff --git a/g10/tofu.c b/g10/tofu.c index e15b564..809dac9 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -70,9 +70,6 @@ struct tofu_dbs_s sqlite3_stmt *savepoint_batch; sqlite3_stmt *savepoint_batch_commit; - sqlite3_stmt *savepoint_inner; - sqlite3_stmt *savepoint_inner_commit; - sqlite3_stmt *record_binding_get_old_policy; sqlite3_stmt *record_binding_update; sqlite3_stmt *record_binding_update2; @@ -209,9 +206,12 @@ begin_transaction (ctrl_t ctrl, int only_batch) if (only_batch) return 0; - rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_inner, - NULL, NULL, &err, - "savepoint inner;", SQLITE_ARG_END); + log_assert(ctrl->tofu.in_transaction >= 0); + ctrl->tofu.in_transaction ++; + + rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, + "savepoint inner%d;", + ctrl->tofu.in_transaction); if (rc) { log_error (_("error beginning transaction on TOFU database: %s\n"), @@ -263,9 +263,9 @@ end_transaction (ctrl_t ctrl, int only_batch) if (only_batch) return 0; - rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_inner_commit, - NULL, NULL, &err, - "release inner;", SQLITE_ARG_END); + log_assert (ctrl->tofu.in_transaction > 0); + rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, + "release inner%d;", ctrl->tofu.in_transaction); if (rc) { log_error (_("error committing transaction on TOFU database: %s\n"), @@ -274,6 +274,8 @@ end_transaction (ctrl_t ctrl, int only_batch) return gpg_error (GPG_ERR_GENERAL); } + ctrl->tofu.in_transaction --; + return 0; } @@ -287,18 +289,15 @@ rollback_transaction (ctrl_t ctrl) if (!dbs) return 0; /* Shortcut to allow for easier cleanup code. */ + log_assert (ctrl->tofu.in_transaction > 0); - if (dbs->batch_update) - { - /* Just undo the most recent update; don't revert any progress - made by the batch transaction. */ - rc = sqlite3_exec (dbs->db, "rollback to inner;", NULL, NULL, &err); - } - else - { - /* Rollback the whole she-bang. */ - rc = sqlite3_exec (dbs->db, "rollback;", NULL, NULL, &err); - } + /* Be careful to not any progress made by closed transactions in + batch mode. */ + rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, + "rollback to inner%d;", + ctrl->tofu.in_transaction); + + ctrl->tofu.in_transaction --; if (rc) { @@ -694,6 +693,8 @@ tofu_closedbs (ctrl_t ctrl) tofu_dbs_t dbs; sqlite3_stmt **statements; + log_assert(ctrl->tofu.in_transaction == 0); + dbs = ctrl->tofu.dbs; if (!dbs) return; /* Not initialized. */ commit 4c2abb221b29c9e8e0876fe986472b562ee1c99f Author: Neal H. Walfield Date: Tue Aug 30 11:29:52 2016 +0200 g10: Print the info text in more situations. * g10/tofu.c (ask_about_binding): Print the info text when the policy is ask and there are multiple bindings with the email address. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index e433f79..e15b564 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1372,7 +1372,8 @@ ask_about_binding (tofu_dbs_t dbs, if ((*policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0) - || (*policy == TOFU_POLICY_ASK && conflict)) + || (*policy == TOFU_POLICY_ASK + && (conflict || bindings_with_this_email_count > 0))) { /* This is a conflict. */ commit 0858f141a8b8d0c098a0c6097176b7225c4a9db8 Author: Neal H. Walfield Date: Tue Aug 30 11:28:17 2016 +0200 g10: Print the formatted text. * g10/tofu.c (ask_about_binding): Print the formatted text, not the unformatted text. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 9d562c2..e433f79 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1393,7 +1393,7 @@ ask_about_binding (tofu_dbs_t dbs, "call the person to make sure this new key is legitimate."; } textbuf = format_text (text, 0, 72, 80); - es_fprintf (fp, "\n%s\n", text); + es_fprintf (fp, "\n%s\n", textbuf); xfree (textbuf); } commit 8dda861ad80228da76cd5c97467008c87b8b6eee Author: Neal H. Walfield Date: Mon Aug 29 14:05:16 2016 +0200 g10: When showing a user id's trust, pass the current signature. * g10/mainproc.c (check_sig_and_print): Consistently pass SIG to get_validity. -- Signed-off-by: Neal H. Walfield diff --git a/g10/mainproc.c b/g10/mainproc.c index 3d3f88b..2626189 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1943,7 +1943,7 @@ check_sig_and_print (CTX c, kbnode_t node) does not print a LF we need to compute the validity before calling that function. */ if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY)) - valid = get_validity (c->ctrl, pk, un->pkt->pkt.user_id, NULL, 0); + valid = get_validity (c->ctrl, pk, un->pkt->pkt.user_id, sig, 0); else valid = 0; /* Not used. */ ----------------------------------------------------------------------- Summary of changes: g10/gpg.h | 3 +- g10/mainproc.c | 2 +- g10/tofu.c | 513 ++++++++++++++++++++++++++++++++------------------------- g10/tofu.h | 38 +++-- g10/trustdb.c | 93 ++++++----- 5 files changed, 364 insertions(+), 285 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 30 16:28:55 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 30 Aug 2016 16:28:55 +0200 Subject: [git] gnupg-doc - branch, master, updated. cacafde8472b5daee4ae9d3379c724214f7afc52 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 cacafde8472b5daee4ae9d3379c724214f7afc52 (commit) via e68197609a027beb3764038f04e1205709574705 (commit) via b1400219a4f1eac47f741114ae8d3d126ed04ced (commit) via ce3bd45e6fb85571ec9dc02b32ec4a41c223a616 (commit) from a3200d8cf1cabc9d013068d3cfe210e5eddceef6 (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 cacafde8472b5daee4ae9d3379c724214f7afc52 Author: Werner Koch Date: Tue Aug 30 16:26:37 2016 +0200 blog: New article on how to install WKS. diff --git a/misc/blog.gnupg.org/20160830-web-key-service.org b/misc/blog.gnupg.org/20160830-web-key-service.org new file mode 100644 index 0000000..3d27755 --- /dev/null +++ b/misc/blog.gnupg.org/20160830-web-key-service.org @@ -0,0 +1,387 @@ +# Some notes on our new Web Key Service +#+STARTUP: showall +#+AUTHOR: Werner +#+DATE: August 30, 2106 + +** Key Discovery Made Simple + + A major hassle with sending encrypted mails is to find the key + matching the recipients mail address. A na?ve method is to look + for the key at a keyserver. In most cases this works surprisingly + well. However, there is no guarantee that this key really matches + the mail address --- anyone can create a key and put an arbitrary + mail address there. It is quite disturbing to receive a mail which + you can't decrypt because it was encrypted to another key. + + GnuPG 2.1 provides an simple but efficient solution to store a key + under a well known URL and lookup it up via https. For practical + deployment of this method (as well as for OpenPGP DANE) a method to + publishing a key is required. The new [[https://tools.ietf.org/id/draft-koch-openpgp-webkey-service-01.html][Web Key Service]] protocol + such a protocol and GnuPG 2.1.15 comes with the tools to implement + this. Aside from GnuPG the other pre-requisites are: + + - A mail server for your domain with the full authority on the user + mail addresses for this domain. + + - A Unix system where you have an account to receive mails to a + dedicated mail address and to send mails via the sendmail tool. + An account on the mail server will be the best choice. + + - A web server for the same domain to deliver static pages over TLS. + Re-direction to a different server is possible + + - The ability to install the latest GnuPG version from source. + + Here is a first step by step description on how to install and test + that service. + +*** Install GnuPG 2.1 + + Your system will already have a gpg version but we want the very + latest one and we want to install it locally. + + First you should create a new account on the machine. Let's use + =webkey=. Nothing special is required; thus a simple + + : # adduser --disabled-password webkey + + as root will do. Add an =.ssh/authorized_keys= file to make it + easy to access. Now download GnuPG (as of this writing version + 2.1.15): + + : $ cd ~webkey + : $ wget ftp://ftp.gnupg.org/gcrypt/gnupg/gnupg-2.1.15.tar.bz2 + : $ wget ftp://ftp.gnupg.org/gcrypt/gnupg/gnupg-2.1.15.tar.bz2.sig + : $ wget -O - https://gnupg.org/signature_key.html | gpg --import + : $ gpg --verify gnupg-2.1.15.tar.bz2.sig gnupg-2.1.15.tar.bz2 + + The last line uses the standard gpg to check that the integrity of + the tarball. Then please verify that the displayed fingerprints + match the desired ones; see + https://gnupg.org/download/integrity_check.html for more on this. + + The easiest way to install the latest GnuPG version is to use + Speedo, which downloads, verifies and builds all dependent + packages. To do this first unpack the tarball: + + : $ tar xjf gnupg-2.1.5.tar.bz2 + + On non GNU system you may need to use this instead: + + : $ zcat gnupg-2.1.5.tar.bz2 | tar xf - + + Then run: + + : $ make -f ~/b-w32/speedo/gnupg-2.1.15/build-aux/speedo.mk \ + : > INSTALL_PREFIX=. speedo_pkg_gnupg_configure='--enable-gpg2-is-gpg \ + : > --disable-g13 --enable-wks-tools' native + + If you run into errors you are probably missing some development + tools; install them and try again. If all succeeds you will + notice a bunch of new directories below webkey's home directory: + + : PLAY bin include lib libexec sbin share swdb.lst swdb.lst.sig + + Optionally you may delete what is not anymore required: + + : $ rm -rf PLAY include lib swdb.* + + To make use of your new GnuPG installation you need to run this + first (you should add it to webkey's .profile or .bashrc): + + : PATH="$HOME/bin:$PATH" + : LD_LIBRARY_PATH="$(pwd)/lib" + : export LD_LIBRARY_PATH + +*** Prepare the mail and web servers + + The Web Key Service requires a working directory to store keys + pending for publication. As root create a working directory: + + : # mkdir /var/lib/gnupg/wks + : # chown webkey:webkey /var/lib/gnupg/wks + : # chmod 2750 /var/lib/gnupg/wks + + Then under your webkey account create directories for all your + domains. Here we do it for ?example.org?: + + : $ mkdir /var/lib/gnupg/wks/example.org + + Then run + + : $ gpg-wks-server --list-domains + + to create the required sub-directories with the permission set + correctly. In particular the =hu= directory (?hashed-userid?) to + store pending keys most only be accessible by the webkey user. + Running the above command will also remind you to create a file + with the submission address for the domain. Let?s do that: + + : $ cd /var/lib/gnupg/wks/example.org + : $ echo key-submission at example.org >submission-address + + The submission address is the address the client uses to contact + the Web Key Service. To make this actually work, that address + needs to be redirected to the webkey user; use the alias file of + your MTA to do this. + + To setup the web server there are at least two ways: If the web + server is on the same machine it is possible to use symlinks to + publish the working directories. For example: + + : $ cd /var/www/example.org/htdocs + : $ mkdir -p .well-known/openpgpkey + : $ cd .well-known/openpgpkey + : $ ln -s /var/lib/gnupg/wks/example.org/hu . + : $ ln -s /var/lib/gnupg/wks/example.org/submission-address . + + The more flexible way is the use of rsync optionally using an ssh + connection to a remote web server. This can be done with a cron + job; run =crontab -e= and add this line (the backslashes below are + used to indicate line wrapping here; do not enter them into the + crontab but use a single long line): + + : */4 * * * * rsync -r -p --chmod=Fa+r --delete \ + : /var/lib/gnupg/wks/example/hu/ \ + : webserver:/var/www/all/example.org/.well-known/openpgpkey/hu/ + + This job syncs every 4 minutes the local copy of the published + keys to the server. The submission-address file does not change + and thus it is sufficient to copy it once by hand to the server. + +*** Create submission key + + The protocol suggests that the key to be published is send with an + encrypted mail to the service. Thus you need to create a key for + the submission address: + + : $ gpg --batch --passphrase '' --quick-gen-key key-submission at example.org + : $ gpg --with-wkd-hash -K key-submission at example.org + + The output of the last command looks similar to this: + + #+begin_example + sec rsa2048 2016-08-30 [SC] + C0FCF8642D830C53246211400346653590B3795B + uid [ultimate] key-submission at example.org + bxzcxpxk8h87z1k7bzk86xn5aj47intu at example.org + ssb rsa2048 2016-08-30 [E] + #+end_example + + Take the hash of the string ?key-submission?, which is + =bxzcxpxk8h87z1k7bzk86xn5aj47intu= and manually publish that key: + + : $ gpg --export-options export-minimal --export key-submission at example.org + : > -o /var/lib/gnupg/wks/example.org/hu/bxzcxpxk8h87z1k7bzk86xn5aj47intu + + Make sure that the created file is world readable. We will + eventually provide a tool to make that step easier. + +*** Install the WKS server tool + + The tool gpg-wks-server implements the server part of the web key + service protocol. There are several ways to install this tool, + what I describe here is a setup which allows easy debugging. + + First install procmail and make sure that your MTA (Exim, Postfix, + sendmail) can run procmail as delivery agent. In most cases it is + sufficient to create the file =.procmailrc= in the home directory + (e.g. =/home/webkey/.procmailrc=). Here is that file; you need to + replace ?example.org? by your own domain name: + + #+begin_example + PATH=$HOME/bin:/usr/bin:/bin:/usr/local/bin + LD_LIBRARY_PATH=$HOME/lib + + MAILDIR=$HOME/Mail + LOGFILE=$HOME/Mail/from + LOCKFILE=$HOME/Mail/.lockmail + VERBOSE=yes + + :0 + * ^FROM_DAEMON + from-daemon/ + + :0 c + archive/ + + :0 + * !^From: webkey at example.org + * !^X-WKS-Loop: webkey.example.org + |$HOME/bin/gpg-wks-server -v --receive \ + --header X-WKS-Loop=webkey.example.org \ + --from webkey at example.org --send -o $HOME/send.log + + :0 + cruft/ + #+end_example + + What it does: The first 6 lines set environment variables for + use by this tool and programs invoked. In particular the setting + of =PATH= and =LD_LIBRARY_PATH= is important so that + gpg-wks-server can properly work. + + The first rule (rules are started with a colon line) detects mails + sent from daemon processes. We don't want them and thus we save + them to the Maildir style folder =Mail/from-daemon= for later + inspection. For a production system it would be better to + directly send those mails to the bit bucket by replacing the last + line of that rule with =/dev/null=. + + The second rule stores a copy of all incoming mails to the folder + =Mail/archive=. This is useful for debugging and to view the flow + of mails. The 'c' after the ':0' means continue with the next + rule after having processed this rule (i.e. storing to the archive + folder). By the way, do not forget the trailing slash at folder + names; without a slash a plain mbox style would be written (you can + use an mbox too, but Maildir is considered a better way to store + mails). + + The third rule is the heart of this procmail script (in procmail + parlance ?recipe?). The two lines starting with an asterisk give + two conditions on when this rule shall be skipped: If the mail + comes from us or if the mail has our loop detection mail header. + The command run on this mail is the wks server in a mode which + uses the /usr/lib/sendmail tool for sending responses to the + mail. The output of the tool is stored to the file =send.log= + in the home directory; to append to a log file use =-o -= and + redirect to a log file. + + The final rule stores all not processed mails to the =cruft/= + folder. This can as well be replaced by =/dev/null=/ + + Finally add an entry to your crontab (run =crontab -e=) to expire non + confirmed publication requests: At the top of your crontab add: + + : PATH=/home/webkey/bin:/usr/local/bin:/usr/bin:/bin + : LD_LIBRARY_PATH=/home/webkey/lib + : + : 42 3 * * * gpg-wks-server --cron + + so that the server tool is run each night at, say, 3:42. + + +*** Test your installation + + To test the Web Key Service, you can create some test accounts for + your domain and run the protocol. For a proper test, do not just + use a different account on the server but use client box. + + Developers of [[https://userbase.kde.org/KMail][KMail]] should already be able to use its brand new + builtin support for the Web Key Service. + + Integration of the Web Key Service into the other mail clients has + not yet been done. Thus you need to run the test manually. In + this example we assume that on you own box a sendmail like tool is + installed and you also installed GnuPG 2.1 along with the client + part of Web Key Service (gpg-wks-client which may require that you + pass --enable-wks-tools to the configure run). + + An easy way of testing the system exists for [[http://www.mutt.org][Mutt]] users: By adding + the two lines + + : application/vnd.gnupg.wks; /usr/local/bin/gpg-wks-client \ + : -v --read --send; needsterminal; description=WKS message + + to =/etc/mailcap= Mutt will do the decryption job and then call + the wks-client for the protocol handling. It can be expected that + Mutt users have a /usr/lib/sendmail installed which is required + here. Note that =--read= is used which tells the client that the + input mail has already been decrypted. + + For all others the protocol can be run by hand. Let?s assume, you + have the key + +#+begin_example +sub cv25519 2016-07-15 [E] + C444189BD549468C97992D7D3C79E8F960C69FCE +pub ed25519 2016-06-28 [SC] + 64944BC035493D929EF2A2B9D19D22B06EE78668 +uid [ultimate] dewey at test.gnupg.org +sub cv25519 2016-06-28 [E] + B3746B6927FF8021486561D83452DE414E0B5CCD +#+end_example + + which in fact is a real key of our own test environment. To + publish that key you send the key to the mail provider: + + : $ /usr/local/libexec/gpg-wks-client --create --send \ + : > 64944BC035493D929EF2A2B9D19D22B06EE78668 dewey at test.gnupg.org + + + As already mention, =--send= invokes =/usr/lib/sendmail= and sends + out the mail. If that option is not used, the mail is + written to stdout (or to the file given with =--output=) and the + user is responsible to feed this to the mail system. If this all + works a single message will be show: + +#+begin_example +gpg-wks-client: submitting request to 'key-submission at test.gnupg.org' +#+end_example + + Now, wait until you receive a mail back from your provider. In + this example that mail was received and stored in the file + =new/1472561079.6352_1.foobar=. We feed this file to the + wks-client: + + : $ /usr/local/libexec/gpg-wks-client --receive --send \ + : > < new/1472561079.6352_1.foobar + + which may respond like this: + +#+begin_example +gpg-wks-client: gpg: encrypted with 256-bit ECDH key, ID 3452DE414E[...] +gpg-wks-client: gpg: "dewey at test.gnupg.org" +gpg-wks-client: new 'application/vnd.gnupg.wks' message part +gpg-wks-client: gpg: automatically retrieved 'key-submission at test.g[...] +#+end_example + + and has send the confirmation mail back to the provider. Over + there the confirmation mail is matched to the pending key database + and the key is then published. + + To check that the key has been published, use this: + + : $ gpg -v --auto-key-locate=clear,wkd,local --locate-key dewey at test.gnupg.org + + you should see: + +#+begin_example +gpg: pub ed25519/D19D22B06EE78668 2016-06-28 dewey at test.gnupg.org +gpg: key D19D22B06EE78668: "dewey at test.gnupg.org" not changed +gpg: Total number processed: 1 +gpg: unchanged: 1 +gpg: auto-key-locate found fingerprint 64944BC035493D929EF2A2B9D19D22B06EE78668 +gpg: automatically retrieved 'dewey at test.gnupg.org' via WKD +pub ed25519 2016-06-28 [SC] + 64944BC035493D929EF2A2B9D19D22B06EE78668 +uid [ultimate] dewey at test.gnupg.org +sub cv25519 2016-06-28 [E] + B3746B6927FF8021486561D83452DE414E0B5CCD +#+end_example + + Despite that it tells you that the key did not change (well, you + asked the provider to publish this key), it also tells that the key + was found using the Web Key Directory (WKD). + + You may also use this lower level test: + + : $ gpg-connect-agent --dirmngr --hex 'wkd_get dewey at test.gnupg.org' /bye + + which results in a hex listing of the key + +*** Future work + + The tools are not yet finished and improvements can be expected + over the next few GnuPG releases. For example the server should + send a final mail back to announce that the key has been + published. We are also considering slight changes to the protocol + but the general procedure on how to drive the tools is unlikely to + change. + + We still need to add manual pages to describe the server and + client tools. For now =--help= and the [[https://lists.gnupg.org/mailman/listinfo/gnupg-devel][gnupg-devel]] mailing list + are your best friends. For those who want to integrate support + for the Web Key Service into a MUA but do not want to fiddle with + the server side of things, we are happy to provide mail addresses + for testing. commit e68197609a027beb3764038f04e1205709574705 Author: Werner Koch Date: Tue Aug 30 16:26:02 2016 +0200 swdb: add libksba release info. diff --git a/web/swdb.mac b/web/swdb.mac index 3ac250a..c63a5cf 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -91,11 +91,11 @@ # # LIBKSBA # -#+macro: libksba_ver 1.3.4 -#+macro: libksba_date 2016-05-03 -#+macro: libksba_size 604k -#+macro: libksba_sha1 bc84945400bd1cabfd7b8ba4e20e71082f32bcc9 -#+macro: libksba_sha2 f6c2883cebec5608692d8730843d87f237c0964d923bbe7aa89c05f20558ad4f +#+macro: libksba_ver 1.3.5 +#+macro: libksba_date 2016-08-22 +#+macro: libksba_size 606k +#+macro: libksba_sha1 a98385734a0c3f5b713198e8d6e6e4aeb0b76fde +#+macro: libksba_sha2 41444fd7a6ff73a79ad9728f985e71c9ba8cd3e5e53358e70d5f066d35c1a340 # commit b1400219a4f1eac47f741114ae8d3d126ed04ced Author: Werner Koch Date: Tue Aug 30 16:25:39 2016 +0200 blog: Move Python article out of the way for now. We better wait until gpgme 1.7 has been released. diff --git a/misc/blog.gnupg.org/20160812-python-bindings-for-gpgme.org b/misc/blog.gnupg.org/drafts/20160812-python-bindings-for-gpgme.org similarity index 100% rename from misc/blog.gnupg.org/20160812-python-bindings-for-gpgme.org rename to misc/blog.gnupg.org/drafts/20160812-python-bindings-for-gpgme.org commit ce3bd45e6fb85571ec9dc02b32ec4a41c223a616 Author: Werner Koch Date: Tue Aug 30 16:23:34 2016 +0200 blog: Fix upload script which broke due to recent changes. diff --git a/misc/blog.gnupg.org/upload b/misc/blog.gnupg.org/upload index bffe8d1..e72979f 100755 --- a/misc/blog.gnupg.org/upload +++ b/misc/blog.gnupg.org/upload @@ -20,6 +20,7 @@ emacs23 --batch \ --eval "(require 'assoc)" \ --eval "(require 'org)" \ --eval "(setq gpgweb-root-dir \"$(cd ../../web && pwd)/\")" \ + --eval "(setq gpgweb-stage-dir \"$(cd ../../stage && pwd)/\")" \ --eval "(require 'gpgweb (concat gpgweb-root-dir \"share/gpgweb.el\"))" \ --eval "(setq org-publish-use-timestamps-flag nil)" \ --eval "(setq org-export-html-toplevel-hlevel 1)" \ ----------------------------------------------------------------------- Summary of changes: misc/blog.gnupg.org/20160830-web-key-service.org | 387 +++++++++++++++++++++ .../20160812-python-bindings-for-gpgme.org | 0 misc/blog.gnupg.org/upload | 1 + web/swdb.mac | 10 +- 4 files changed, 393 insertions(+), 5 deletions(-) create mode 100644 misc/blog.gnupg.org/20160830-web-key-service.org rename misc/blog.gnupg.org/{ => drafts}/20160812-python-bindings-for-gpgme.org (100%) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Aug 30 16:33:44 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 30 Aug 2016 16:33:44 +0200 Subject: [git] gnupg-doc - branch, master, updated. 0d4aa0dec5d5dd3c54040fe4ad73545e550eb87b 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 0d4aa0dec5d5dd3c54040fe4ad73545e550eb87b (commit) from cacafde8472b5daee4ae9d3379c724214f7afc52 (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 0d4aa0dec5d5dd3c54040fe4ad73545e550eb87b Author: Werner Koch Date: Tue Aug 30 16:30:27 2016 +0200 blog: fix publication date - we are not yet at the end of the Epoch. diff --git a/misc/blog.gnupg.org/20160830-web-key-service.org b/misc/blog.gnupg.org/20160830-web-key-service.org index 3d27755..79b08b4 100644 --- a/misc/blog.gnupg.org/20160830-web-key-service.org +++ b/misc/blog.gnupg.org/20160830-web-key-service.org @@ -1,7 +1,7 @@ # Some notes on our new Web Key Service #+STARTUP: showall #+AUTHOR: Werner -#+DATE: August 30, 2106 +#+DATE: August 30, 2016 ** Key Discovery Made Simple ----------------------------------------------------------------------- Summary of changes: misc/blog.gnupg.org/20160830-web-key-service.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 08:54:58 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 31 Aug 2016 08:54:58 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-24-g76304a9 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 76304a971fe507ea659b952932ea899463ab7166 (commit) from 371ae66e9d5c7524431773c4a479fcae1ea3b652 (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 76304a971fe507ea659b952932ea899463ab7166 Author: Werner Koch Date: Wed Aug 31 08:37:51 2016 +0200 gpg: Fix regression in gpgv's printing of the keyid. * g10/keyid.c (keystr): Take care of KF_NONE != KF_DEFAULT. -- Debian-bug-id: 836144 Signed-off-by: Werner Koch diff --git a/g10/keyid.c b/g10/keyid.c index ea6ed5e..4380151 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -403,6 +403,8 @@ keystr (u32 *keyid) static char keyid_str[KEYID_STR_SIZE]; int format = opt.keyid_format; + if (format == KF_DEFAULT) + format = KF_NONE; if (format == KF_NONE) format = KF_LONG; ----------------------------------------------------------------------- Summary of changes: g10/keyid.c | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 10:14:27 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 10:14:27 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-25-gb8184d2 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 b8184d2d74e5ddd5eb68836b53fe5568110e14dd (commit) from 76304a971fe507ea659b952932ea899463ab7166 (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 b8184d2d74e5ddd5eb68836b53fe5568110e14dd Author: Neal H. Walfield Date: Wed Aug 31 10:12:53 2016 +0200 gpg: Avoid name spaces clash with future sqlite versions (2). * g10/gpgsql.h (gpgsql_arg_type): Rename SQLITE_ARG_END to GPGSQL_ARG_END, SQLITE_ARG_INT to GPGSQL_ARG_INT, SQLITE_ARG_LONG_LONG to GPGSQL_ARG_LONG_LONG, SQLITE_ARG_STRING to GPGSQL_ARG_STRING, and SQLITE_ARG_BLOB to GPGSQL_ARG_BLOB. -- This commit completes the work started in b1ba460. Signed-off-by: Neal H. Walfield diff --git a/g10/gpgsql.c b/g10/gpgsql.c index 72f51b5..a9b3364 100644 --- a/g10/gpgsql.c +++ b/g10/gpgsql.c @@ -131,25 +131,25 @@ gpgsql_stepx (sqlite3 *db, t = va_arg (va, enum gpgsql_arg_type); switch (t) { - case SQLITE_ARG_INT: + case GPGSQL_ARG_INT: { int value = va_arg (va, int); err = sqlite3_bind_int (stmt, i, value); break; } - case SQLITE_ARG_LONG_LONG: + case GPGSQL_ARG_LONG_LONG: { long long value = va_arg (va, long long); err = sqlite3_bind_int64 (stmt, i, value); break; } - case SQLITE_ARG_STRING: + case GPGSQL_ARG_STRING: { char *text = va_arg (va, char *); err = sqlite3_bind_text (stmt, i, text, -1, SQLITE_STATIC); break; } - case SQLITE_ARG_BLOB: + case GPGSQL_ARG_BLOB: { char *blob = va_arg (va, void *); long long length = va_arg (va, long long); @@ -170,7 +170,7 @@ gpgsql_stepx (sqlite3 *db, } t = va_arg (va, enum gpgsql_arg_type); - log_assert (t == SQLITE_ARG_END); + log_assert (t == GPGSQL_ARG_END); va_end (va); for (;;) diff --git a/g10/gpgsql.h b/g10/gpgsql.h index a540684..8117f45 100644 --- a/g10/gpgsql.h +++ b/g10/gpgsql.h @@ -24,19 +24,19 @@ enum gpgsql_arg_type { - SQLITE_ARG_END = 0xdead001, - SQLITE_ARG_INT, - SQLITE_ARG_LONG_LONG, - SQLITE_ARG_STRING, + GPGSQL_ARG_END = 0xdead001, + GPGSQL_ARG_INT, + GPGSQL_ARG_LONG_LONG, + GPGSQL_ARG_STRING, /* This takes two arguments: the blob as a void * and the length of the blob as a long long. */ - SQLITE_ARG_BLOB + GPGSQL_ARG_BLOB }; int gpgsql_exec_printf (sqlite3 *db, - int (*callback)(void*,int,char**,char**), void *cookie, - char **errmsg, - const char *sql, ...); + int (*callback)(void*,int,char**,char**), void *cookie, + char **errmsg, + const char *sql, ...); typedef int (*gpgsql_stepx_callback) (void *cookie, /* number of columns. */ diff --git a/g10/tofu.c b/g10/tofu.c index f84609e..e1f2851 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -204,7 +204,7 @@ begin_transaction (ctrl_t ctrl, int only_batch) rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch, NULL, NULL, &err, - "savepoint batch;", SQLITE_ARG_END); + "savepoint batch;", GPGSQL_ARG_END); if (rc) { log_error (_("error beginning transaction on TOFU database: %s\n"), @@ -269,7 +269,7 @@ end_transaction (ctrl_t ctrl, int only_batch) rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch_commit, NULL, NULL, &err, - "release batch;", SQLITE_ARG_END); + "release batch;", GPGSQL_ARG_END); if (rc) { log_error (_("error committing transaction on TOFU database: %s\n"), @@ -790,8 +790,8 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, (dbs->db, &dbs->s.record_binding_get_old_policy, get_single_long_cb2, &policy_old, &err, "select policy from bindings where fingerprint = ? and email = ?", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_END); + GPGSQL_ARG_STRING, fingerprint, GPGSQL_ARG_STRING, email, + GPGSQL_ARG_END); if (rc) { log_debug ("TOFU: Error reading from binding database" @@ -839,10 +839,10 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, based on the fingerprint and email since they are unique. */ " (select oid from bindings where fingerprint = ? and email = ?),\n" " ?, ?, ?, strftime('%s','now'), ?);", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_STRING, user_id, SQLITE_ARG_INT, (int) policy, - SQLITE_ARG_END); + GPGSQL_ARG_STRING, fingerprint, GPGSQL_ARG_STRING, email, + GPGSQL_ARG_STRING, fingerprint, GPGSQL_ARG_STRING, email, + GPGSQL_ARG_STRING, user_id, GPGSQL_ARG_INT, (int) policy, + GPGSQL_ARG_END); if (rc) { log_error (_("error updating TOFU database: %s\n"), err); @@ -1036,9 +1036,9 @@ get_policy (tofu_dbs_t dbs, const char *fingerprint, const char *email, strings_collect_cb2, &strlist, &err, "select policy, conflict from bindings\n" " where fingerprint = ? and email = ?", - SQLITE_ARG_STRING, fingerprint, - SQLITE_ARG_STRING, email, - SQLITE_ARG_END); + GPGSQL_ARG_STRING, fingerprint, + GPGSQL_ARG_STRING, email, + GPGSQL_ARG_END); if (rc) { log_error (_("error reading TOFU database: %s\n"), err); @@ -1228,7 +1228,7 @@ ask_about_binding (tofu_dbs_t dbs, (dbs->db, &dbs->s.get_trust_gather_other_user_ids, strings_collect_cb2, &other_user_ids, &sqerr, "select user_id, policy from bindings where fingerprint = ?;", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END); + GPGSQL_ARG_STRING, fingerprint, GPGSQL_ARG_END); if (rc) { log_error (_("error gathering other user IDs: %s\n"), sqerr); @@ -1301,8 +1301,8 @@ ask_about_binding (tofu_dbs_t dbs, " group by fingerprint, time_ago\n" /* Make sure the current key is first. */ " order by fingerprint = ? asc, fingerprint desc, time_ago desc;\n", - SQLITE_ARG_STRING, email, SQLITE_ARG_STRING, fingerprint, - SQLITE_ARG_END); + GPGSQL_ARG_STRING, email, GPGSQL_ARG_STRING, fingerprint, + GPGSQL_ARG_END); if (rc) { strlist_t strlist_iter; @@ -1640,7 +1640,7 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, (dbs->db, &dbs->s.get_trust_bindings_with_this_email, strings_collect_cb2, &bindings_with_this_email, &sqerr, "select distinct fingerprint from bindings where email = ?;", - SQLITE_ARG_STRING, email, SQLITE_ARG_END); + GPGSQL_ARG_STRING, email, GPGSQL_ARG_END); if (rc) { log_error (_("error reading TOFU database: %s\n"), sqerr); @@ -2269,10 +2269,10 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, " on signatures.binding = bindings.oid\n" " where fingerprint = ? and email = ? and sig_time = ?\n" " and sig_digest = ?", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_LONG_LONG, (long long) sig_time, - SQLITE_ARG_STRING, sig_digest, - SQLITE_ARG_END); + GPGSQL_ARG_STRING, fingerprint, GPGSQL_ARG_STRING, email, + GPGSQL_ARG_LONG_LONG, (long long) sig_time, + GPGSQL_ARG_STRING, sig_digest, + GPGSQL_ARG_END); if (rc) { log_error (_("error reading TOFU database: %s\n"), err); @@ -2321,10 +2321,10 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, " ((select oid from bindings\n" " where fingerprint = ? and email = ?),\n" " ?, ?, ?, strftime('%s', 'now'));", - SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email, - SQLITE_ARG_STRING, sig_digest, SQLITE_ARG_STRING, origin, - SQLITE_ARG_LONG_LONG, (long long) sig_time, - SQLITE_ARG_END); + GPGSQL_ARG_STRING, fingerprint, GPGSQL_ARG_STRING, email, + GPGSQL_ARG_STRING, sig_digest, GPGSQL_ARG_STRING, origin, + GPGSQL_ARG_LONG_LONG, (long long) sig_time, + GPGSQL_ARG_END); if (rc) { log_error (_("error updating TOFU database: %s\n"), err); ----------------------------------------------------------------------- Summary of changes: g10/gpgsql.c | 10 +++++----- g10/gpgsql.h | 16 ++++++++-------- g10/tofu.c | 46 +++++++++++++++++++++++----------------------- 3 files changed, 36 insertions(+), 36 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 10:47:07 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 10:47:07 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-26-g268f6b7 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 268f6b7a3403d036882b4af384ba7ab2f8c8355f (commit) from b8184d2d74e5ddd5eb68836b53fe5568110e14dd (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 268f6b7a3403d036882b4af384ba7ab2f8c8355f Author: Neal H. Walfield Date: Wed Aug 31 10:47:05 2016 +0200 gpg: Move state local to tofu.c to a private structure. * g10/gpg.h (struct server_control_s.tofu): Move fields in_transaction and batch_update_started from here... * g10/tofu.c (struct tofu_dbs_s): ... to here. -- Signed-off-by: Neal H. Walfield diff --git a/g10/gpg.h b/g10/gpg.h index 33a3af6..90a8866 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -82,9 +82,7 @@ struct server_control_s /* Local data for tofu.c */ struct { tofu_dbs_t dbs; - int in_transaction; - int batch_updated_wanted; - time_t batch_update_started; + int batch_updated_wanted; } tofu; }; diff --git a/g10/tofu.c b/g10/tofu.c index e1f2851..88833cd 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -82,6 +82,8 @@ struct tofu_dbs_s } s; int in_batch_transaction; + int in_transaction; + time_t batch_update_started; }; @@ -176,11 +178,11 @@ begin_transaction (ctrl_t ctrl, int only_batch) * Note: if we wanted higher resolution, we could use * npth_clock_gettime. */ if (/* No real transactions. */ - ctrl->tofu.in_transaction == 0 + dbs->in_transaction == 0 /* There is an open batch transaction. */ && dbs->in_batch_transaction /* And some time has gone by since it was started. */ - && ctrl->tofu.batch_update_started != gnupg_get_time ()) + && dbs->batch_update_started != gnupg_get_time ()) { /* If we are in a batch update, then batch updates better have been enabled. */ @@ -200,7 +202,7 @@ begin_transaction (ctrl_t ctrl, int only_batch) /* We are in batch mode, but we don't have an open batch * transaction. Since the batch save point must be the outer * save point, it must be taken before the inner save point. */ - log_assert (ctrl->tofu.in_transaction == 0); + log_assert (dbs->in_transaction == 0); rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_batch, NULL, NULL, &err, @@ -214,18 +216,18 @@ begin_transaction (ctrl_t ctrl, int only_batch) } dbs->in_batch_transaction = 1; - ctrl->tofu.batch_update_started = gnupg_get_time (); + dbs->batch_update_started = gnupg_get_time (); } if (only_batch) return 0; - log_assert(ctrl->tofu.in_transaction >= 0); - ctrl->tofu.in_transaction ++; + log_assert(dbs->in_transaction >= 0); + dbs->in_transaction ++; rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, "savepoint inner%d;", - ctrl->tofu.in_transaction); + dbs->in_transaction); if (rc) { log_error (_("error beginning transaction on TOFU database: %s\n"), @@ -256,7 +258,7 @@ end_transaction (ctrl_t ctrl, int only_batch) /* If we are releasing the batch transaction, then we better not be in a normal transaction. */ - log_assert (ctrl->tofu.in_transaction == 0); + log_assert (dbs->in_transaction == 0); if (/* Batch mode disabled? */ (!ctrl->tofu.batch_updated_wanted || only_batch == 2) @@ -285,10 +287,10 @@ end_transaction (ctrl_t ctrl, int only_batch) } log_assert (dbs); - log_assert (ctrl->tofu.in_transaction > 0); + log_assert (dbs->in_transaction > 0); rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, - "release inner%d;", ctrl->tofu.in_transaction); + "release inner%d;", dbs->in_transaction); if (rc) { log_error (_("error committing transaction on TOFU database: %s\n"), @@ -297,7 +299,7 @@ end_transaction (ctrl_t ctrl, int only_batch) return gpg_error (GPG_ERR_GENERAL); } - ctrl->tofu.in_transaction --; + dbs->in_transaction --; return 0; } @@ -311,15 +313,15 @@ rollback_transaction (ctrl_t ctrl) char *err = NULL; log_assert (dbs); - log_assert (ctrl->tofu.in_transaction > 0); + log_assert (dbs->in_transaction > 0); /* Be careful to not any progress made by closed transactions in batch mode. */ rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err, "rollback to inner%d;", - ctrl->tofu.in_transaction); + dbs->in_transaction); - ctrl->tofu.in_transaction --; + dbs->in_transaction --; if (rc) { @@ -712,12 +714,12 @@ tofu_closedbs (ctrl_t ctrl) tofu_dbs_t dbs; sqlite3_stmt **statements; - log_assert (ctrl->tofu.in_transaction == 0); - dbs = ctrl->tofu.dbs; if (!dbs) return; /* Not initialized. */ + log_assert (dbs->in_transaction == 0); + end_transaction (ctrl, 2); /* Arghh, that is a surprising use of the struct. */ ----------------------------------------------------------------------- Summary of changes: g10/gpg.h | 4 +--- g10/tofu.c | 34 ++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 19 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 10:58:21 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 10:58:21 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-27-g70df5a8 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 70df5a8fd781d8774d835384ca28c4d8518bb9d0 (commit) from 268f6b7a3403d036882b4af384ba7ab2f8c8355f (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 70df5a8fd781d8774d835384ca28c4d8518bb9d0 Author: Neal H. Walfield Date: Wed Aug 31 10:58:18 2016 +0200 g10: Drop unused argument. * g10/tofu.c (begin_transaction): Remove unused option only_batch. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 88833cd..62c6efc 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -163,7 +163,7 @@ tofu_policy_to_trust_level (enum tofu_policy policy) /* Start a transaction on DB. */ static gpg_error_t -begin_transaction (ctrl_t ctrl, int only_batch) +begin_transaction (ctrl_t ctrl) { tofu_dbs_t dbs = ctrl->tofu.dbs; int rc; @@ -219,9 +219,6 @@ begin_transaction (ctrl_t ctrl, int only_batch) dbs->batch_update_started = gnupg_get_time (); } - if (only_batch) - return 0; - log_assert(dbs->in_transaction >= 0); dbs->in_transaction ++; @@ -2231,7 +2228,7 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, /* We do a query and then an insert. Make sure they are atomic by wrapping them in a transaction. */ - rc = begin_transaction (ctrl, 0); + rc = begin_transaction (ctrl); if (rc) return rc; @@ -2479,7 +2476,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, fingerprint = hexfingerprint (pk, NULL, 0); - begin_transaction (ctrl, 0); + begin_transaction (ctrl); for (user_id = user_id_list; user_id; user_id = user_id->next, bindings ++) { ----------------------------------------------------------------------- Summary of changes: g10/tofu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 11:52:26 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 11:52:26 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-29-ge4d5e3c 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 e4d5e3cb0d10e8f77c7100d42cfdb32051de1c18 (commit) via 247eef005cf4c34e9a82227e4ab7823e04911be4 (commit) from 70df5a8fd781d8774d835384ca28c4d8518bb9d0 (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 e4d5e3cb0d10e8f77c7100d42cfdb32051de1c18 Author: Neal H. Walfield Date: Wed Aug 31 11:40:33 2016 +0200 g10: Update a key's TOFU policy in a transaction. * g10/tofu.c (tofu_set_policy): Do the update in a transaction. * g10/gpg.c (main): Do a TOFU policy update in a batch transaction. -- Signed-off-by: Neal H. Walfield diff --git a/g10/gpg.c b/g10/gpg.c index 3193e74..a9770d7 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -4664,6 +4664,8 @@ main (int argc, char **argv) if (! hd) g10_exit (1); + tofu_begin_batch_update (ctrl); + for (i = 1; i < argc; i ++) { KEYDB_SEARCH_DESC desc; @@ -4721,8 +4723,9 @@ main (int argc, char **argv) g10_exit (1); } - keydb_release (hd); + tofu_end_batch_update (ctrl); + keydb_release (hd); } #endif /*USE_TOFU*/ break; diff --git a/g10/tofu.c b/g10/tofu.c index 137065a..4285e96 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2584,6 +2584,8 @@ tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy) fingerprint = hexfingerprint (pk, NULL, 0); + begin_transaction (ctrl); + for (; kb; kb = kb->next) { PKT_user_id *user_id; @@ -2605,6 +2607,8 @@ tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy) xfree (email); } + end_transaction (ctrl, 0); + xfree (fingerprint); return 0; } commit 247eef005cf4c34e9a82227e4ab7823e04911be4 Author: Neal H. Walfield Date: Wed Aug 31 11:39:35 2016 +0200 g10: Fix the show old policy functionality when changing a TOFU policy. * g10/tofu.c (record_binding): Fix the show old policy functionality. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 62c6efc..137065a 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -767,10 +767,6 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, char *fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); gpg_error_t rc; char *err = NULL; - /* policy_old needs to be a long and not an enum tofu_policy, - because we pass it by reference to get_single_long_cb2, which - expects a long. */ - long policy_old = TOFU_POLICY_NONE; if (! (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_GOOD @@ -780,11 +776,17 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, log_bug ("%s: Bad value for policy (%d)!\n", __func__, policy); - if (show_old) + if (DBG_TRUST || show_old) { /* Get the old policy. Since this is just for informational * purposes, there is no need to start a transaction or to die * if there is a failure. */ + + /* policy_old needs to be a long and not an enum tofu_policy, + because we pass it by reference to get_single_long_cb2, which + expects a long. */ + long policy_old = TOFU_POLICY_NONE; + rc = gpgsql_stepx (dbs->db, &dbs->s.record_binding_get_old_policy, get_single_long_cb2, &policy_old, &err, @@ -799,28 +801,27 @@ record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, sqlite3_free (err); } - if (DBG_TRUST) + if (policy_old != TOFU_POLICY_NONE) + (show_old ? log_info : log_debug) + ("Changing TOFU trust policy for binding" + " from %s to %s.\n", + fingerprint, show_old ? user_id : email, + tofu_policy_str (policy_old), + tofu_policy_str (policy)); + else + (show_old ? log_info : log_debug) + ("Setting TOFU trust policy for new binding" + " to %s.\n", + fingerprint, show_old ? user_id : email, + tofu_policy_str (policy)); + + if (policy_old == policy) { - if (policy_old != TOFU_POLICY_NONE) - log_debug ("Changing TOFU trust policy for binding" - " from %s to %s.\n", - fingerprint, email, - tofu_policy_str (policy_old), - tofu_policy_str (policy)); - else - log_debug ("Setting TOFU trust policy for new binding" - " to %s.\n", - fingerprint, email, - tofu_policy_str (policy)); + rc = 0; + goto leave; /* Nothing to do. */ } } - if (policy_old == policy) - { - rc = 0; - goto leave; /* Nothing to do. */ - } - if (opt.dry_run) { log_info ("TOFU database update skipped due to --dry-run\n"); ----------------------------------------------------------------------- Summary of changes: g10/gpg.c | 5 ++++- g10/tofu.c | 51 ++++++++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 24 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 12:15:08 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 12:15:08 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-30-g5b48960 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 5b48960a8a2555db7bf992261de9e922838c9913 (commit) from e4d5e3cb0d10e8f77c7100d42cfdb32051de1c18 (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 5b48960a8a2555db7bf992261de9e922838c9913 Author: Neal H. Walfield Date: Wed Aug 31 12:11:58 2016 +0200 g10: Fix error detection. * g10/tofu.c: first_seen == 0 is not an error. -- Signed-off-by: Neal H. Walfield Fixes-commit: 0f1f02ac Regression-due-to: 45bb9a2a diff --git a/g10/tofu.c b/g10/tofu.c index 4285e96..968b89a 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2023,7 +2023,7 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint, } - if (messages == -1 || !first_seen) + if (messages == -1 || first_seen == -1) { write_stats_status (outfp, 0, TOFU_POLICY_NONE, 0, 0); if (!outfp) ----------------------------------------------------------------------- Summary of changes: g10/tofu.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 Wed Aug 31 12:30:24 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 31 Aug 2016 12:30:24 +0200 Subject: [git] gnupg-doc - branch, master, updated. 69bba6517275301d9a62623c54b8352e1b02221c 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 69bba6517275301d9a62623c54b8352e1b02221c (commit) from 0d4aa0dec5d5dd3c54040fe4ad73545e550eb87b (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 69bba6517275301d9a62623c54b8352e1b02221c Author: Werner Koch Date: Wed Aug 31 12:27:56 2016 +0200 blog: Spelling and grammar fixes. Reported-by: gnupg at raf.org diff --git a/misc/blog.gnupg.org/20160830-web-key-service.org b/misc/blog.gnupg.org/20160830-web-key-service.org index 79b08b4..e9db2a7 100644 --- a/misc/blog.gnupg.org/20160830-web-key-service.org +++ b/misc/blog.gnupg.org/20160830-web-key-service.org @@ -64,11 +64,11 @@ Speedo, which downloads, verifies and builds all dependent packages. To do this first unpack the tarball: - : $ tar xjf gnupg-2.1.5.tar.bz2 + : $ tar xjf gnupg-2.1.15.tar.bz2 On non GNU system you may need to use this instead: - : $ zcat gnupg-2.1.5.tar.bz2 | tar xf - + : $ zcat gnupg-2.1.15.tar.bz2 | tar xf - Then run: @@ -113,7 +113,7 @@ to create the required sub-directories with the permission set correctly. In particular the =hu= directory (?hashed-userid?) to - store pending keys most only be accessible by the webkey user. + store pending keys must only be accessible by the webkey user. Running the above command will also remind you to create a file with the submission address for the domain. Let?s do that: @@ -151,7 +151,7 @@ *** Create submission key - The protocol suggests that the key to be published is send with an + The protocol suggests that the key to be published is sent with an encrypted mail to the service. Thus you need to create a key for the submission address: @@ -272,7 +272,7 @@ Integration of the Web Key Service into the other mail clients has not yet been done. Thus you need to run the test manually. In - this example we assume that on you own box a sendmail like tool is + this example we assume that on your own box a sendmail-like tool is installed and you also installed GnuPG 2.1 along with the client part of Web Key Service (gpg-wks-client which may require that you pass --enable-wks-tools to the configure run). @@ -309,11 +309,11 @@ sub cv25519 2016-06-28 [E] : > 64944BC035493D929EF2A2B9D19D22B06EE78668 dewey at test.gnupg.org - As already mention, =--send= invokes =/usr/lib/sendmail= and sends + As already mentioned, =--send= invokes =/usr/lib/sendmail= and sends out the mail. If that option is not used, the mail is written to stdout (or to the file given with =--output=) and the - user is responsible to feed this to the mail system. If this all - works a single message will be show: + user is responsible for feeding this to the mail system. If this all + works a single message will be shown: #+begin_example gpg-wks-client: submitting request to 'key-submission at test.gnupg.org' @@ -336,7 +336,7 @@ gpg-wks-client: new 'application/vnd.gnupg.wks' message part gpg-wks-client: gpg: automatically retrieved 'key-submission at test.g[...] #+end_example - and has send the confirmation mail back to the provider. Over + and has sent the confirmation mail back to the provider. Over there the confirmation mail is matched to the pending key database and the key is then published. ----------------------------------------------------------------------- Summary of changes: misc/blog.gnupg.org/20160830-web-key-service.org | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 13:20:08 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 31 Aug 2016 13:20:08 +0200 Subject: [git] gnupg-doc - branch, master, updated. d8f242e707b5ba78c7e40c71bd90dd2d34bf5780 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 d8f242e707b5ba78c7e40c71bd90dd2d34bf5780 (commit) from 69bba6517275301d9a62623c54b8352e1b02221c (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 d8f242e707b5ba78c7e40c71bd90dd2d34bf5780 Author: Werner Koch Date: Wed Aug 31 13:17:47 2016 +0200 blog: Yet another correction diff --git a/misc/blog.gnupg.org/20160830-web-key-service.org b/misc/blog.gnupg.org/20160830-web-key-service.org index e9db2a7..518cbe9 100644 --- a/misc/blog.gnupg.org/20160830-web-key-service.org +++ b/misc/blog.gnupg.org/20160830-web-key-service.org @@ -72,8 +72,8 @@ Then run: - : $ make -f ~/b-w32/speedo/gnupg-2.1.15/build-aux/speedo.mk \ - : > INSTALL_PREFIX=. speedo_pkg_gnupg_configure='--enable-gpg2-is-gpg \ + : $ make -f gnupg-2.1.15/build-aux/speedo.mk INSTALL_PREFIX=. \ + : > speedo_pkg_gnupg_configure='--enable-gpg2-is-gpg \ : > --disable-g13 --enable-wks-tools' native If you run into errors you are probably missing some development ----------------------------------------------------------------------- Summary of changes: misc/blog.gnupg.org/20160830-web-key-service.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 13:53:45 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 13:53:45 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-31-g28c235a 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 28c235ae757e9036b0b96efc28931fa5cc74f7ee (commit) from 5b48960a8a2555db7bf992261de9e922838c9913 (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 28c235ae757e9036b0b96efc28931fa5cc74f7ee Author: Neal H. Walfield Date: Wed Aug 31 13:53:36 2016 +0200 g10: Always trust ultimately trusted keys. * g10/tofu.c (get_trust): Always return TRUST_ULTIMATE for ultimately trusted keys. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 968b89a..add9266 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1543,30 +1543,30 @@ get_trust (tofu_dbs_t dbs, PKT_public_key *pk, && _tofu_GET_TRUST_ERROR != TRUST_ULTIMATE); policy = get_policy (dbs, fingerprint, email, &conflict); - if (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_NONE) - { /* See if the key is ultimately trusted. If so, we're done. */ - u32 kid[2]; + { + /* See if the key is ultimately trusted. If so, we're done. */ + u32 kid[2]; - keyid_from_pk (pk, kid); + keyid_from_pk (pk, kid); - if (tdb_keyid_is_utk (kid)) - { - if (policy == TOFU_POLICY_NONE) - { - if (record_binding (dbs, fingerprint, email, user_id, - TOFU_POLICY_AUTO, 0) != 0) - { - log_error (_("error setting TOFU binding's trust level" - " to %s\n"), "auto"); - trust_level = _tofu_GET_TRUST_ERROR; - goto out; - } - } + if (tdb_keyid_is_utk (kid)) + { + if (policy == TOFU_POLICY_NONE) + { + if (record_binding (dbs, fingerprint, email, user_id, + TOFU_POLICY_AUTO, 0) != 0) + { + log_error (_("error setting TOFU binding's trust level" + " to %s\n"), "auto"); + trust_level = _tofu_GET_TRUST_ERROR; + goto out; + } + } - trust_level = TRUST_ULTIMATE; - goto out; - } - } + trust_level = TRUST_ULTIMATE; + goto out; + } + } if (policy == TOFU_POLICY_AUTO) { ----------------------------------------------------------------------- Summary of changes: g10/tofu.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 14:17:16 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 14:17:16 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-32-gb69b2cb 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 b69b2cb082e39a7eb56082fa80219f6f14fbd2b4 (commit) from 28c235ae757e9036b0b96efc28931fa5cc74f7ee (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 b69b2cb082e39a7eb56082fa80219f6f14fbd2b4 Author: Neal H. Walfield Date: Wed Aug 31 14:17:13 2016 +0200 doc: Add a help text for tofu.conflict. * doc/help.txt (.gpg.tofu.conflict): New help text. -- Signed-off-by: Neal H. Walfield diff --git a/doc/help.txt b/doc/help.txt index e92cfbe..4c6df7c 100644 --- a/doc/help.txt +++ b/doc/help.txt @@ -358,8 +358,19 @@ revocation certificate. Please keep this text concise. An empty line ends the text. . - - +.gpg.tofu.conflict +# tofu.c +TOFU has detected another key with the same (or a very similar) email +address. It might be that the user created a new key. In this case, +you can safely trust the new key (but, confirm this by asking the +person). However, it could also be that the key is a forgery or there +is an active Man-in-the-Middle (MitM) attack. In this case, you +should mark the key as being bad, so that it is untrusted. Marking a +key as being untrusted means that any signatures will be considered +bad and attempts to encrypt to the key will be flagged. If you are +unsure and can't currently check, you should select either accept once +or reject once. +. .gpgsm.root-cert-not-trusted # This text gets displayed by the audit log if ----------------------------------------------------------------------- Summary of changes: doc/help.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 17:52:52 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Wed, 31 Aug 2016 17:52:52 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-33-gedfb693 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 edfb6934caf16c6afcfd82d684d8ae9c79674d10 (commit) from b69b2cb082e39a7eb56082fa80219f6f14fbd2b4 (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 edfb6934caf16c6afcfd82d684d8ae9c79674d10 Author: Neal H. Walfield Date: Wed Aug 31 17:52:50 2016 +0200 g10: On a TOFU conflict, show whether the uids are expired or revoked * g10/tofu.c (struct signature_stats): Add fields is_expired and is_revoked. (signature_stats_prepend): Clear *stats when allocating it. (ask_about_binding): Also show whether the user ids are expired or revoked. -- Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index add9266..74777b5 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -111,6 +111,7 @@ struct tofu_dbs_s /* Local prototypes. */ static gpg_error_t end_transaction (ctrl_t ctrl, int only_batch); +static char *email_from_user_id (const char *user_id); @@ -913,6 +914,10 @@ struct signature_stats /* Number of signatures during this time. */ unsigned long count; + /* If the corresponding key/user id has been expired / revoked. */ + int is_expired; + int is_revoked; + /* The key that generated this signature. */ char fingerprint[1]; }; @@ -936,7 +941,7 @@ signature_stats_prepend (struct signature_stats **statsp, unsigned long count) { struct signature_stats *stats = - xmalloc (sizeof (*stats) + strlen (fingerprint)); + xmalloc_clear (sizeof (*stats) + strlen (fingerprint)); stats->next = *statsp; *statsp = stats; @@ -1324,6 +1329,7 @@ ask_about_binding (tofu_dbs_t dbs, } else { + KEYDB_HANDLE hd; char *key = NULL; if (! stats || strcmp (stats->fingerprint, fingerprint)) @@ -1335,6 +1341,93 @@ ask_about_binding (tofu_dbs_t dbs, signature_stats_prepend (&stats, fingerprint, TOFU_POLICY_AUTO, 0, 0); } + /* Figure out which user ids are revoked or expired. */ + hd = keydb_new (); + for (stats_iter = stats; stats_iter; stats_iter = stats_iter->next) + { + KEYDB_SEARCH_DESC desc; + kbnode_t kb; + PKT_public_key *pk; + kbnode_t n; + int found_user_id; + + rc = keydb_search_reset (hd); + if (rc) + { + log_error (_("resetting keydb: %s\n"), + gpg_strerror (rc)); + continue; + } + + rc = classify_user_id (stats_iter->fingerprint, &desc, 0); + if (rc) + { + log_error (_("error parsing key specification '%s': %s\n"), + stats_iter->fingerprint, gpg_strerror (rc)); + continue; + } + + rc = keydb_search (hd, &desc, 1, NULL); + if (rc) + { + log_error (_("key \"%s\" not found: %s\n"), + stats_iter->fingerprint, + gpg_strerror (rc)); + continue; + } + + rc = keydb_get_keyblock (hd, &kb); + if (rc) + { + log_error (_("error reading keyblock: %s\n"), + gpg_strerror (rc)); + print_further_info ("fingerprint: %s", stats_iter->fingerprint); + continue; + } + + merge_keys_and_selfsig (kb); + + log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY); + pk = kb->pkt->pkt.public_key; + + if (pk->has_expired) + stats_iter->is_expired = 1; + if (pk->flags.revoked) + stats_iter->is_revoked = 1; + + n = kb; + found_user_id = 0; + while ((n = find_next_kbnode (n, PKT_USER_ID)) && ! found_user_id) + { + PKT_user_id *user_id2 = n->pkt->pkt.user_id; + char *email2; + + if (user_id2->attrib_data) + continue; + + email2 = email_from_user_id (user_id2->name); + + if (strcmp (email, email2) == 0) + { + found_user_id = 1; + + if (user_id2->is_revoked) + stats_iter->is_revoked = 1; + if (user_id2->is_expired) + stats_iter->is_expired = 1; + } + + xfree (email2); + } + release_kbnode (kb); + + if (! found_user_id) + log_info (_("TOFU db may be corrupted: user id (%s)" + " not on key block (%s)\n"), + email, fingerprint); + } + keydb_release (hd); + es_fprintf (fp, _("Statistics for keys with the email address \"%s\":\n"), email); for (stats_iter = stats; stats_iter; stats_iter = stats_iter->next) @@ -1348,6 +1441,18 @@ ask_about_binding (tofu_dbs_t dbs, this_key = strcmp (key, fingerprint) == 0; key_pp = format_hexfingerprint (key, NULL, 0); es_fprintf (fp, " %s (", key_pp); + + if (stats_iter->is_revoked) + { + es_fprintf (fp, _("revoked")); + es_fprintf (fp, _(", ")); + } + else if (stats_iter->is_expired) + { + es_fprintf (fp, _("expired")); + es_fprintf (fp, _(", ")); + } + if (this_key) es_fprintf (fp, _("this key")); else ----------------------------------------------------------------------- Summary of changes: g10/tofu.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 19:08:26 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 31 Aug 2016 19:08:26 +0200 Subject: [git] gnupg-doc - branch, master, updated. 1d36db1e021124124758952c6cf156b9dc172d46 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 1d36db1e021124124758952c6cf156b9dc172d46 (commit) from d8f242e707b5ba78c7e40c71bd90dd2d34bf5780 (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 1d36db1e021124124758952c6cf156b9dc172d46 Author: Werner Koch Date: Wed Aug 31 19:06:06 2016 +0200 web: Add stub for an FAQ entry for WKD diff --git a/web/faq/wkd.org b/web/faq/wkd.org new file mode 100644 index 0000000..702b469 --- /dev/null +++ b/web/faq/wkd.org @@ -0,0 +1,13 @@ +#+TITLE: GnuPG - The Web Key Directory +#+STARTUP: showall indent +#+SETUPFILE: "share/setup.inc" +#+DATE: 2016-08-31 + +* The Web Key Directory + +The Web Key Directory (WKD) is GnuPG?s standard system for key +discovery. That is, it returns a public key for a supplied mail +address. It is a distrubuted system in the same way email is +distributed. + +FIXME: Write a detailed description. ----------------------------------------------------------------------- Summary of changes: web/faq/wkd.org | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 web/faq/wkd.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Aug 31 19:16:15 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 31 Aug 2016 19:16:15 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.15-35-g04c042f 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 04c042f3f2a631bc6e772c33f8da5e7aa7b1902a (commit) via e4eac16330449f3893c11820c15e07d58fb807ff (commit) from edfb6934caf16c6afcfd82d684d8ae9c79674d10 (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 04c042f3f2a631bc6e772c33f8da5e7aa7b1902a Author: Werner Koch Date: Wed Aug 31 18:54:09 2016 +0200 wks: Send a final message to the user. * tools/gpg-wks-server.c (send_congratulation_message): New. (check_and_publish): Call it. Signed-off-by: Werner Koch diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index b4d96b5..221db05 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -1065,6 +1065,124 @@ process_new_key (server_ctx_t ctx, estream_t key) +/* Send a message to tell the user at MBOX that their key has been + * published. FNAME the name of the file with the key. */ +static gpg_error_t +send_congratulation_message (const char *mbox, const char *keyfile) +{ + gpg_error_t err; + estream_t body = NULL; + estream_t bodyenc = NULL; + mime_maker_t mime = NULL; + char *from_buffer = NULL; + const char *from; + strlist_t sl; + + from = from_buffer = get_submission_address (mbox); + if (!from) + { + from = opt.default_from; + if (!from) + { + log_error ("no sender address found for '%s'\n", mbox); + err = gpg_error (GPG_ERR_CONFIGURATION); + goto leave; + } + log_info ("Note: using default sender address '%s'\n", from); + } + + body = es_fopenmem (0, "w+b"); + if (!body) + { + err = gpg_error_from_syserror (); + log_error ("error allocating memory buffer: %s\n", gpg_strerror (err)); + goto leave; + } + /* It is fine to use 8 bit encoding because that is encrypted and + * only our client will see it. */ + es_fputs ("Content-Type: text/plain; charset=utf-8\n" + "Content-Transfer-Encoding: 8bit\n" + "\n", + body); + + es_fprintf (body, + "Hello!\n\n" + "The key for your address '%s' has been published\n" + "and can now be retrieved from the Web Key Directory.\n" + "\n" + "For more information on this system see:\n" + "\n" + " https://gnupg.org/faq/wkd.html\n" + "\n" + "Best regards\n" + "\n" + " Gnu Key Publisher\n\n\n" + "-- \n" + "The GnuPG Project welcomes donations: %s\n", + mbox, "https://gnupg.org/donate"); + + es_rewind (body); + err = encrypt_stream (&bodyenc, body, keyfile); + if (err) + goto leave; + es_fclose (body); + body = NULL; + + err = mime_maker_new (&mime, NULL); + if (err) + goto leave; + err = mime_maker_add_header (mime, "From", from); + if (err) + goto leave; + err = mime_maker_add_header (mime, "To", mbox); + if (err) + goto leave; + err = mime_maker_add_header (mime, "Subject", "Your key has been published"); + if (err) + goto leave; + for (sl = opt.extra_headers; sl; sl = sl->next) + { + err = mime_maker_add_header (mime, sl->d, NULL); + if (err) + goto leave; + } + + err = mime_maker_add_header (mime, "Content-Type", + "multipart/encrypted; " + "protocol=\"application/pgp-encrypted\""); + if (err) + goto leave; + err = mime_maker_add_container (mime, "multipart/encrypted"); + if (err) + goto leave; + + err = mime_maker_add_header (mime, "Content-Type", + "application/pgp-encrypted"); + if (err) + goto leave; + err = mime_maker_add_body (mime, "Version: 1\n"); + if (err) + goto leave; + err = mime_maker_add_header (mime, "Content-Type", + "application/octet-stream"); + if (err) + goto leave; + + err = mime_maker_add_stream (mime, &bodyenc); + if (err) + goto leave; + + err = wks_send_mime (mime); + + leave: + mime_maker_release (mime); + es_fclose (bodyenc); + es_fclose (body); + xfree (from_buffer); + return err; +} + + /* Check that we have send a request with NONCE and publish the key. */ static gpg_error_t check_and_publish (server_ctx_t ctx, const char *address, const char *nonce) @@ -1170,7 +1288,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce) } log_info ("key %s published for '%s'\n", ctx->fpr, address); - + send_congratulation_message (address, fnewname); /* Try to publish as DANE record if the DANE directory exists. */ xfree (fname); @@ -1207,7 +1325,6 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce) log_info ("key %s published for '%s' (DANE record)\n", ctx->fpr, address); } - leave: es_fclose (key); xfree (hash); commit e4eac16330449f3893c11820c15e07d58fb807ff Author: Werner Koch Date: Wed Aug 31 16:39:55 2016 +0200 wks: Relax permission check for the top directory. * tools/gpg-wks-server.c: Allow S_IXOTH for the top directory. Signed-off-by: Werner Koch diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index e872824..b4d96b5 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -17,7 +17,7 @@ * along with this program; if not, see . */ -/* The Web Key Service I-D defines an update protocol to stpre a +/* The Web Key Service I-D defines an update protocol to store a * public key in the Web Key Directory. The current specification is * draft-koch-openpgp-webkey-service-01.txt. */ @@ -302,7 +302,7 @@ main (int argc, char **argv) log_error ("directory '%s' not owned by user\n", opt.directory); exit (2); } - if ((sb.st_mode & S_IRWXO)) + if ((sb.st_mode & (S_IROTH|S_IWOTH))) { log_error ("directory '%s' has too relaxed permissions\n", opt.directory); @@ -878,7 +878,7 @@ store_key_as_pending (const char *dir, estream_t key, } -/* Send a confirmation rewqyest. DIR is the directory used for the +/* Send a confirmation request. DIR is the directory used for the * address MBOX. NONCE is the nonce we want to see in the response to * this mail. FNAME the name of the file with the key. */ static gpg_error_t ----------------------------------------------------------------------- Summary of changes: tools/gpg-wks-server.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org