From cvs at cvs.gnupg.org Wed Feb 1 01:03:39 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 01 Feb 2017 01:03:39 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-46-g8ddc926 Message-ID: This is an 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 8ddc9268f6aedef0e178b174b89245c33d8189dd (commit) from 2e78aa6ff770849415f8eb71ca70c8886e9564c8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8ddc9268f6aedef0e178b174b89245c33d8189dd Author: NIIBE Yutaka Date: Wed Feb 1 08:58:01 2017 +0900 scd: Fix regression tracking the connection count. * scd/scdaemon.c (get_active_connection_count): New. (start_connection_thread): Bump ACTIVE_CONNECTIONS up and down. * scd/command.c (cmd_getinfo): Add subcommand "connections". -- Apply gpg-agent change to scdaemon. See the commit in 2016-08-06: 40d16029ed8b334c371fa7f24ac762d47302826e Then, add kicking the loop, so that main loop can notice the change of the connection. Signed-off-by: NIIBE Yutaka diff --git a/scd/command.c b/scd/command.c index 0ae6d29..bd7e803 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1372,30 +1372,26 @@ static const char hlp_getinfo[] = "Multi purpose command to return certain information. \n" "Supported values of WHAT are:\n" "\n" - "version - Return the version of the program.\n" - "pid - Return the process id of the server.\n" - "\n" - "socket_name - Return the name of the socket.\n" - "\n" - "status - Return the status of the current reader (in the future, may\n" - "also return the status of all readers). The status is a list of\n" - "one-character flags. The following flags are currently defined:\n" - " 'u' Usable card present. This is the normal state during operation.\n" - " 'r' Card removed. A reset is necessary.\n" - "These flags are exclusive.\n" - "\n" - "reader_list - Return a list of detected card readers. Does\n" - " currently only work with the internal CCID driver.\n" - "\n" - "deny_admin - Returns OK if admin commands are not allowed or\n" - " GPG_ERR_GENERAL if admin commands are allowed.\n" - "\n" - "app_list - Return a list of supported applications. One\n" - " application per line, fields delimited by colons,\n" - " first field is the name.\n" - "\n" - "card_list - Return a list of serial numbers of active cards,\n" - " using a status response."; + " version - Return the version of the program.\n" + " pid - Return the process id of the server.\n" + " socket_name - Return the name of the socket.\n" + " connections - Return number of active connections.\n" + " status - Return the status of the current reader (in the future,\n" + " may also return the status of all readers). The status\n" + " is a list of one-character flags. The following flags\n" + " are currently defined:\n" + " 'u' Usable card present.\n" + " 'r' Card removed. A reset is necessary.\n" + " These flags are exclusive.\n" + " reader_list - Return a list of detected card readers. Does\n" + " currently only work with the internal CCID driver.\n" + " deny_admin - Returns OK if admin commands are not allowed or\n" + " GPG_ERR_GENERAL if admin commands are allowed.\n" + " app_list - Return a list of supported applications. One\n" + " application per line, fields delimited by colons,\n" + " first field is the name.\n" + " card_list - Return a list of serial numbers of active cards,\n" + " using a status response."; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { @@ -1422,6 +1418,13 @@ cmd_getinfo (assuan_context_t ctx, char *line) else rc = gpg_error (GPG_ERR_NO_DATA); } + else if (!strcmp (line, "connections")) + { + char numbuf[20]; + + snprintf (numbuf, sizeof numbuf, "%d", get_active_connection_count ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } else if (!strcmp (line, "status")) { ctrl_t ctrl = assuan_get_pointer (ctx); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 7972abd..e4b0ef8 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1150,6 +1150,8 @@ start_connection_thread (void *arg) return NULL; } + active_connections++; + scd_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("handler for fd %d started\n"), @@ -1169,6 +1171,10 @@ start_connection_thread (void *arg) scd_deinit_default_ctrl (ctrl); xfree (ctrl); + + if (--active_connections == 0) + scd_kick_the_loop (); + return NULL; } @@ -1349,3 +1355,10 @@ handle_connections (int listen_fd) log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); npth_attr_destroy (&tattr); } + +/* Return the number of active connections. */ +int +get_active_connection_count (void) +{ + return active_connections; +} diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 37590b6..4797f3d 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -125,6 +125,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...) void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args); void send_client_notifications (app_t app, int removal); void scd_kick_the_loop (void); +int get_active_connection_count (void); /*-- app.c --*/ int scd_update_reader_status_file (void); ----------------------------------------------------------------------- Summary of changes: scd/command.c | 51 +++++++++++++++++++++++++++------------------------ scd/scdaemon.c | 13 +++++++++++++ scd/scdaemon.h | 1 + 3 files changed, 41 insertions(+), 24 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 1 08:21:08 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 01 Feb 2017 08:21:08 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-47-gf518196 Message-ID: This is an 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 f518196ca6202ae97a1e8494afe25e5fbb0e9d47 (commit) from 8ddc9268f6aedef0e178b174b89245c33d8189dd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f518196ca6202ae97a1e8494afe25e5fbb0e9d47 Author: Werner Koch Date: Wed Feb 1 08:18:44 2017 +0100 Fix explanation of commit e175152ef7515921635bf1e00383e812668d13fc. -- diff --git a/agent/cache.c b/agent/cache.c index 4cb158c..41e0905 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -485,10 +485,12 @@ agent_store_cache_hit (const char *key) * * Background: xtrystrdup uses gcry_strdup which may use the secure * memory allocator of Libgcrypt. That allocator takes locks and - * since version 1.14 libgpg-error is nPth aware and thus talking a + * since version 1.14 libgpg-error is nPth aware and thus taking a * lock may now lead to thread switch. Note that this only happens - * when secure memory is allocated, the standard allocator uses - * malloc which is not nPth aware. + * when secure memory is _allocated_ (the standard allocator uses + * malloc which is not nPth aware) but not when calling _xfree_ + * because gcry_free needs to check whether the pointer is in secure + * memory and thus needs to take a lock. */ new = key ? xtrystrdup (key) : NULL; diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index ad19fc2..615c9e6 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -1227,7 +1227,7 @@ is_ip_address (const char *name) if (*s == '.') { if (s[1] == '.') - return 0; /* No: Douple dot. */ + return 0; /* No: Double dot. */ if (atoi (s+1) > 255) return 0; /* No: Ipv4 byte value too large. */ ndots++; ----------------------------------------------------------------------- Summary of changes: agent/cache.c | 8 +++++--- dirmngr/dns-stuff.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 1 16:17:44 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 01 Feb 2017 16:17:44 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-43-ga28d31f Message-ID: This is an 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 a28d31fdb623f2ee30e8094d09f1a0d1ae446a9b (commit) from ba594d85e35e63301755977234d3af88a167a215 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a28d31fdb623f2ee30e8094d09f1a0d1ae446a9b Author: Andre Heinecke Date: Wed Feb 1 16:16:22 2017 +0100 core: Improve mailbox only uid handling * src/key.c (_gpgme_key_append_name): Set email and remove name for uid only keys. -- If we have a name and no email but the name can be parsed as an address we now treat the address as email and remove the name. This fixes downstream users that rely on email to show email addresses and don't expilicity handle this case. E.g. A userid foo at example.com was: uid->name = "foo at example.com" uid->email = "" uid->address = "foo at example.com" It is now: uid->name = "" uid->email = "foo at example.com" uid->address = "foo at example.com" diff --git a/src/key.c b/src/key.c index 38acc71..fed020e 100644 --- a/src/key.c +++ b/src/key.c @@ -242,6 +242,14 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert) free (uid->address); uid->address = uid->email; } + if ((!uid->email || !*uid->email) && uid->address && uid->name + && !strcmp (uid->name, uid->address)) + { + /* Name and address are the same. This is a mailbox only key. + Use address as email and remove name. */ + *uid->name = '\0'; + uid->email = uid->address; + } if (!key->uids) key->uids = uid; ----------------------------------------------------------------------- Summary of changes: src/key.c | 8 ++++++++ 1 file changed, 8 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 1 18:01:04 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 01 Feb 2017 18:01:04 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-48-g7440119 Message-ID: This is an 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 7440119e729d3fdedda8a9b44b70f8959beea8d7 (commit) from f518196ca6202ae97a1e8494afe25e5fbb0e9d47 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7440119e729d3fdedda8a9b44b70f8959beea8d7 Author: Werner Koch Date: Wed Feb 1 17:54:14 2017 +0100 dirmngr: New option --no-use-tor and internal changes. * dirmngr/dns-stuff.c (disable_dns_tormode): New. * dirmngr/dirmngr.c (oNoUseTor): New const. (opts): New option --no-use-tor. (tor_mode): New var. (parse_rereadable_options): Change to use TOR_MODE. (dirmngr_use_tor): New. (set_tor_mode): Call disable_dns_tormode. Implement oNoUseTor. * dirmngr/dirmngr.h (opt): Remove field 'use_tor'. Replace all references by a call to dirmngr_use_tor(). * dirmngr/server.c (cmd_getinfo): Distinguish between default and enforced TOR_MODE. -- This patch replaces the global variable opt.use_tar by a function testing a file local mode flag. This patch prepares for a use-tor-if-available mode. GnuPG-bug-id: 2935 Signed-off-by: Werner Koch diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c index aa82137..337fe6e 100644 --- a/dirmngr/crlfetch.c +++ b/dirmngr/crlfetch.c @@ -198,7 +198,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader) err = http_open_document (&hd, url, NULL, ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0) |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0) - |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0) + |(dirmngr_use_tor()? HTTP_FLAG_FORCE_TOR:0) |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4:0) ), ctrl->http_proxy, NULL, NULL, NULL); @@ -292,7 +292,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader) "LDAP"); err = gpg_error (GPG_ERR_NOT_SUPPORTED); } - else if (opt.use_tor) + else if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("CRL access not possible due to Tor mode\n")); @@ -318,7 +318,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader) gpg_error_t crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader) { - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("CRL access not possible due to Tor mode\n")); @@ -350,7 +350,7 @@ crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader) gpg_error_t ca_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, const char *dn) { - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("CRL access not possible due to Tor mode\n")); @@ -377,7 +377,7 @@ gpg_error_t start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, strlist_t patterns, const ldap_server_t server) { - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("CRL access not possible due to Tor mode\n")); diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 7e640d4..bb07656 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -138,6 +138,7 @@ enum cmd_and_opt_values { oHTTPWrapperProgram, oIgnoreCertExtension, oUseTor, + oNoUseTor, oKeyServer, oNameServer, oDisableCheckOwnSocket, @@ -224,6 +225,7 @@ static ARGPARSE_OPTS opts[] = { N_("|FILE|use the CA certificates in FILE for HKP over TLS")), ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")), + ARGPARSE_s_n (oNoUseTor, "no-use-tor", "@"), ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"), @@ -300,6 +302,16 @@ static volatile int shutdown_pending; /* Flags to indicate that we shall not watch our own socket. */ static int disable_check_own_socket; +/* Flag to control the Tor mode. */ +static enum + { TOR_MODE_AUTO = 0, /* Switch to NO or YES */ + TOR_MODE_NEVER, /* Never use Tor. */ + TOR_MODE_NO, /* Do not use Tor */ + TOR_MODE_YES, /* Use Tor */ + TOR_MODE_FORCE /* Force using Tor */ + } tor_mode; + + /* Counter for the active connections. */ static int active_connections; @@ -482,7 +494,7 @@ set_debug (void) static void set_tor_mode (void) { - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* Enable Tor mode and when called again force a new curcuit * (e.g. on SIGHUP). */ @@ -493,6 +505,26 @@ set_tor_mode (void) log_info ("(is your Libassuan recent enough?)\n"); } } + else + disable_dns_tormode (); +} + + +/* Return true if Tor shall be used. */ +int +dirmngr_use_tor (void) +{ + if (tor_mode == TOR_MODE_AUTO) + { + /* FIXME: Figure out whether Tor is running. */ + } + + if (tor_mode == TOR_MODE_FORCE) + return 2; /* Use Tor (using 2 to indicate force mode) */ + else if (tor_mode == TOR_MODE_YES) + return 1; /* Use Tor */ + else + return 0; /* Do not use Tor. */ } @@ -555,7 +587,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) FREE_STRLIST (opt.ignored_cert_extensions); http_register_tls_ca (NULL); FREE_STRLIST (opt.keyserver); - /* Note: We do not allow resetting of opt.use_tor at runtime. */ + /* Note: We do not allow resetting of TOR_MODE_FORCE at runtime. */ + if (tor_mode != TOR_MODE_FORCE) + tor_mode = TOR_MODE_AUTO; disable_check_own_socket = 0; enable_standard_resolver (0); set_dns_timeout (0); @@ -632,7 +666,13 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str); break; - case oUseTor: opt.use_tor = 1; break; + case oUseTor: + tor_mode = TOR_MODE_FORCE; + break; + case oNoUseTor: + if (tor_mode != TOR_MODE_FORCE) + tor_mode = TOR_MODE_NEVER; + break; case oStandardResolver: enable_standard_resolver (1); break; case oRecursiveResolver: enable_recursive_resolver (1); break; diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index ca07e78..3724c00 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -91,7 +91,6 @@ struct program. */ int running_detached; /* We are running in detached mode. */ - int use_tor; /* Tor mode has been enabled. */ int allow_version_check; /* --allow-version-check is active. */ int force; /* Force loading outdated CRLs. */ @@ -191,7 +190,7 @@ void dirmngr_init_default_ctrl (ctrl_t ctrl); void dirmngr_deinit_default_ctrl (ctrl_t ctrl); void dirmngr_sighup_action (void); const char* dirmngr_get_current_socket_name (void); - +int dirmngr_use_tor (void); /*-- Various housekeeping functions. --*/ void ks_hkp_housekeeping (time_t curtime); diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 615c9e6..f0de357 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -222,6 +222,14 @@ enable_dns_tormode (int new_circuit) } +/* Disable tor mode. */ +void +disable_dns_tormode (void) +{ + tor_mode = 0; +} + + /* Set verbosity and debug mode for this module. */ void set_dns_verbose (int verbose, int debug) diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h index 9eb97fd..9b8303c 100644 --- a/dirmngr/dns-stuff.h +++ b/dirmngr/dns-stuff.h @@ -120,6 +120,7 @@ int recursive_resolver_p (void); /* Put this module eternally into Tor mode. When called agained with * NEW_CIRCUIT request a new TOR circuit for the next DNS query. */ void enable_dns_tormode (int new_circuit); +void disable_dns_tormode (void); /* Change the default IP address of the nameserver to IPADDR. The address needs to be a numerical IP address and will be used for the diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c index 114f2e9..811b72d 100644 --- a/dirmngr/ks-engine-finger.c +++ b/dirmngr/ks-engine-finger.c @@ -83,7 +83,7 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp) *server++ = 0; err = http_raw_connect (&http, server, 79, - ((opt.use_tor? HTTP_FLAG_FORCE_TOR : 0) + ((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0) | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)), NULL); if (err) diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index c787bc6..40f3521 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -265,7 +265,7 @@ tor_not_running_p (ctrl_t ctrl) { assuan_fd_t sock; - if (!opt.use_tor) + if (!dirmngr_use_tor ()) return 0; sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR); @@ -1090,7 +1090,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, /* fixme: AUTH */ NULL, (httpflags |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0) - |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0) + |(dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0) |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)), ctrl->http_proxy, session, @@ -1247,7 +1247,7 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request, break; case GPG_ERR_EACCES: - if (opt.use_tor) + if (dirmngr_use_tor ()) { log_info ("(Tor configuration problem)\n"); dirmngr_status (ctrl, "WARNING", "tor_config_problem 0", diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index dbbf4bb..69642ff 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -88,7 +88,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) /* httphost */ NULL, /* fixme: AUTH */ NULL, ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0) - | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0) + | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0) | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)), ctrl->http_proxy, session, diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 6d520e9..b7aa7cc 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -850,7 +850,7 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, (void) ctrl; - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("LDAP access not possible due to Tor mode\n")); @@ -1033,7 +1033,7 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, (void) ctrl; - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("LDAP access not possible due to Tor mode\n")); @@ -1909,7 +1909,7 @@ ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri, /* Elide a warning. */ (void) ctrl; - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not support LDAP over Tor. */ log_error (_("LDAP access not possible due to Tor mode\n")); diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index b46c785..aff8e32 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -132,7 +132,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md, (void)ctrl; - if (opt.use_tor) + if (dirmngr_use_tor ()) { /* For now we do not allow OCSP via Tor due to possible privacy concerns. Needs further research. */ @@ -174,7 +174,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md, once_more: err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL, ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0) - | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0) + | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0) | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)), ctrl->http_proxy, NULL, NULL, NULL); if (err) diff --git a/dirmngr/server.c b/dirmngr/server.c index c9c4ad4..bca3a61 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -625,7 +625,7 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) else if (!strcmp (key, "honor-keyserver-url-used")) { /* Return an error if we are running in Tor mode. */ - if (opt.use_tor) + if (dirmngr_use_tor ()) err = gpg_error (GPG_ERR_FORBIDDEN); } else @@ -2338,14 +2338,18 @@ cmd_getinfo (assuan_context_t ctx, char *line) } else if (!strcmp (line, "tor")) { - if (opt.use_tor) + int use_tor; + + use_tor = dirmngr_use_tor (); + if (use_tor) { if (!is_tor_running (ctrl)) err = assuan_write_status (ctx, "NO_TOR", "Tor not running"); else err = 0; if (!err) - assuan_set_okay_line (ctx, "- Tor mode is enabled"); + assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled" + /**/ : "- Tor mode is enforced"); } else err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled"); ----------------------------------------------------------------------- Summary of changes: dirmngr/crlfetch.c | 10 +++++----- dirmngr/dirmngr.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- dirmngr/dirmngr.h | 3 +-- dirmngr/dns-stuff.c | 8 ++++++++ dirmngr/dns-stuff.h | 1 + dirmngr/ks-engine-finger.c | 2 +- dirmngr/ks-engine-hkp.c | 6 +++--- dirmngr/ks-engine-http.c | 2 +- dirmngr/ks-engine-ldap.c | 6 +++--- dirmngr/ocsp.c | 4 ++-- dirmngr/server.c | 10 +++++++--- 11 files changed, 75 insertions(+), 23 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 1 18:07:36 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 01 Feb 2017 18:07:36 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-45-g8ede867 Message-ID: This is an 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 8ede86795a1d419c01b4910ec2fd1fb18b629452 (commit) via b5075030bec9b21bf4e515bc1686df3fa43eced2 (commit) from a28d31fdb623f2ee30e8094d09f1a0d1ae446a9b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8ede86795a1d419c01b4910ec2fd1fb18b629452 Author: Andre Heinecke Date: Wed Feb 1 18:06:54 2017 +0100 core: Cleanup gpgme_key_unref frees * src/key.c (gpgme_key_unref): Nowadays we assume free(NULL) is ok. diff --git a/src/key.c b/src/key.c index e33abd0..e2e30db 100644 --- a/src/key.c +++ b/src/key.c @@ -341,14 +341,10 @@ gpgme_key_unref (gpgme_key_t key) while (subkey) { gpgme_subkey_t next = subkey->next; - if (subkey->fpr) - 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->fpr); + free (subkey->curve); + free (subkey->keygrip); + free (subkey->card_number); free (subkey); subkey = next; } @@ -393,15 +389,10 @@ gpgme_key_unref (gpgme_key_t key) uid = next_uid; } - if (key->issuer_serial) - free (key->issuer_serial); - if (key->issuer_name) - free (key->issuer_name); - - if (key->chain_id) - free (key->chain_id); - if (key->fpr) - free (key->fpr); + free (key->issuer_serial); + free (key->issuer_name); + free (key->chain_id); + free (key->fpr); free (key); } commit b5075030bec9b21bf4e515bc1686df3fa43eced2 Author: Andre Heinecke Date: Wed Feb 1 18:03:35 2017 +0100 core: Fix leakage of address for mail only uids * src/key.c (gpgme_key_unref): Always free address if set. (_gpgme_key_append_name): Remove memory optimization for address. -- The check if address is not allocated would now be more complicated then just comparing it to email because email is set to address also when an email was not parsed from the user id. diff --git a/src/key.c b/src/key.c index fed020e..e33abd0 100644 --- a/src/key.c +++ b/src/key.c @@ -236,12 +236,6 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert) &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 ((!uid->email || !*uid->email) && uid->address && uid->name && !strcmp (uid->name, uid->address)) { @@ -394,9 +388,7 @@ gpgme_key_unref (gpgme_key_t key) tofu = tofu_next; } - if (uid->address && uid->address != uid->email) - free (uid->address); - + free (uid->address); free (uid); uid = next_uid; } ----------------------------------------------------------------------- Summary of changes: src/key.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 10:16:19 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 02 Feb 2017 10:16:19 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-48-g0ceeb29 Message-ID: This is an 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 0ceeb2948c7210f120e5ddda1ca20a4bbbf83378 (commit) via d19bea52afe6efb66a46af6aa4d09928c5d05ee5 (commit) via 9b7d81998b734fabeb4fbc697f08fc7795eaa90a (commit) from 8ede86795a1d419c01b4910ec2fd1fb18b629452 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0ceeb2948c7210f120e5ddda1ca20a4bbbf83378 Author: Werner Koch Date: Thu Feb 2 10:13:36 2017 +0100 core: Explain in gpgme.h that most stucts are read-only. -- It is common that developers look up only the header file and do not read the manual. These comments should make it clear that most structures in gpgme.h are read-only and may only be allocated by gpgme. Signed-off-by: Werner Koch diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 769c2c8..67c139b 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -394,6 +394,9 @@ typedef unsigned int gpgme_export_mode_t; typedef unsigned int gpgme_sig_notation_flags_t; +/* An object to hold information about notation data. This structure + * shall be considered read-only and an application must not allocate + * such a structure on its own. */ struct _gpgme_sig_notation { struct _gpgme_sig_notation *next; @@ -431,7 +434,9 @@ typedef struct _gpgme_sig_notation *gpgme_sig_notation_t; * Public structures. */ -/* The engine information structure. */ +/* The engine information structure. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_engine_info { struct _gpgme_engine_info *next; @@ -454,7 +459,9 @@ struct _gpgme_engine_info typedef struct _gpgme_engine_info *gpgme_engine_info_t; -/* An object with TOFU information. */ +/* An object with TOFU information. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_tofu_info { struct _gpgme_tofu_info *next; @@ -491,7 +498,9 @@ struct _gpgme_tofu_info typedef struct _gpgme_tofu_info *gpgme_tofu_info_t; -/* A subkey from a key. */ +/* A subkey from a key. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_subkey { struct _gpgme_subkey *next; @@ -565,7 +574,9 @@ struct _gpgme_subkey typedef struct _gpgme_subkey *gpgme_subkey_t; -/* A signature on a user ID. */ +/* A signature on a user ID. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_key_sig { struct _gpgme_key_sig *next; @@ -634,7 +645,9 @@ struct _gpgme_key_sig typedef struct _gpgme_key_sig *gpgme_key_sig_t; -/* An user ID from a key. */ +/* An user ID from a key. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_user_id { struct _gpgme_user_id *next; @@ -681,7 +694,9 @@ struct _gpgme_user_id typedef struct _gpgme_user_id *gpgme_user_id_t; -/* A key from the keyring. */ +/* A key from the keyring. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_key { /* Internal to GPGME, do not use. */ @@ -762,7 +777,9 @@ struct _gpgme_key typedef struct _gpgme_key *gpgme_key_t; -/* An invalid key object. */ +/* An invalid key object. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_invalid_key { struct _gpgme_invalid_key *next; @@ -1196,6 +1213,9 @@ void gpgme_key_release (gpgme_key_t key); * Encryption. */ +/* An object to return results from an encryption operation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_encrypt_result { /* The list of invalid recipients. */ @@ -1244,6 +1264,9 @@ gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[], * Decryption. */ +/* An object to hold information about a recipient. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_recipient { struct _gpgme_recipient *next; @@ -1262,6 +1285,9 @@ struct _gpgme_recipient }; typedef struct _gpgme_recipient *gpgme_recipient_t; +/* An object to return results from a decryption operation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_decrypt_result { char *unsupported_algorithm; @@ -1307,6 +1333,9 @@ gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher, * Signing. */ +/* An object with signatures data. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_new_signature { struct _gpgme_new_signature *next; @@ -1342,6 +1371,10 @@ struct _gpgme_new_signature }; typedef struct _gpgme_new_signature *gpgme_new_signature_t; + +/* An object to return results from a signing operation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_sign_result { /* The list of invalid signers. */ @@ -1385,6 +1418,9 @@ typedef enum gpgme_sigsum_t; +/* An object to hold the verification status of a signature. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_signature { struct _gpgme_signature *next; @@ -1437,6 +1473,9 @@ struct _gpgme_signature }; typedef struct _gpgme_signature *gpgme_signature_t; +/* An object to return the results of a verify operation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_verify_result { gpgme_signature_t signatures; @@ -1470,6 +1509,9 @@ gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, #define GPGME_IMPORT_SECRET 16 /* The key contained a secret key. */ +/* An object to hold results for one imported key. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_import_status { struct _gpgme_import_status *next; @@ -1488,7 +1530,9 @@ struct _gpgme_import_status }; typedef struct _gpgme_import_status *gpgme_import_status_t; -/* Import result object. */ +/* Import result object. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_import_result { /* Number of considered keys. */ @@ -1594,6 +1638,9 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx, #define GPGME_CREATE_WANTSEC (1 << 11) /* Return the secret key. */ #define GPGME_CREATE_FORCE (1 << 12) /* Force creation. */ +/* An object to return result from a key generation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_genkey_result { /* A primary key was generated. */ @@ -1750,6 +1797,9 @@ gpgme_error_t gpgme_op_tofu_policy (gpgme_ctx_t ctx, * Key listing */ +/* An object to return results from a key listing operation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_keylist_result { unsigned int truncated : 1; @@ -1790,6 +1840,9 @@ gpgme_error_t gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key, * Trust items and operations. */ +/* An object to hold data of a trust item. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_trust_item { /* Internal to GPGME, do not use. */ @@ -1924,6 +1977,9 @@ gpgme_error_t gpgme_op_assuan_transact_ext (gpgme_ctx_t ctx, * Crypto container support. */ +/* An object to return results from a VFS mount operation. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_vfs_mount_result { char *mount_dir; @@ -2112,7 +2168,9 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p); gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp); -/* Information about software versions. */ +/* Information about software versions. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ typedef struct _gpgme_op_query_swdb_result { /* RFU */ @@ -2528,7 +2586,9 @@ int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what, const void *reserved, int idx) _GPGME_DEPRECATED(0,4); -/* Compat. */ +/* Compat. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ struct _gpgme_op_assuan_result { /* Deprecated. Use the second value in a DONE event or the commit d19bea52afe6efb66a46af6aa4d09928c5d05ee5 Author: Werner Koch Date: Thu Feb 2 09:50:47 2017 +0100 core: Un-deprecate gpgme_data_rewind. * src/gpgme.h.in (gpgme_data_rewind): Un-deprecate. * src/data-compat.c (gpgme_data_rewind): Move to ... * src/data.c (gpgme_data_rewind): here. -- That function is very convenient because it is required a lot with memory streams. It also documents the intention of the caller better than gpgme_data_seek with its addition parameters and the need to map system errors. Thus it does not make sense to make it a first class citizen again. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 0fca77a..4405f6c 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ Noteworthy changes in version 1.8.1 (unreleased) cpp: Key::UserID::revoke() NEW. cpp: Key::addUid() NEW. qt: CryptoConfig::stringValueList() NEW. + gpgme_data_rewind UN-DEPRECATE. Noteworthy changes in version 1.8.0 (2016-11-16) diff --git a/src/data-compat.c b/src/data-compat.c index 5c7d543..87eaeef 100644 --- a/src/data-compat.c +++ b/src/data-compat.c @@ -239,16 +239,3 @@ gpgme_data_new_with_read_cb (gpgme_data_t *r_dh, (*r_dh)->data.old_user.handle = read_cb_value; return TRACE_ERR (0); } - - -gpgme_error_t -gpgme_data_rewind (gpgme_data_t dh) -{ - gpgme_error_t err; - TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh); - - err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1) - ? gpg_error_from_syserror () : 0); - - return TRACE_ERR (err); -} diff --git a/src/data.c b/src/data.c index 6964246..e4e9ee3 100644 --- a/src/data.c +++ b/src/data.c @@ -158,6 +158,20 @@ gpgme_data_seek (gpgme_data_t dh, gpgme_off_t offset, int whence) } +/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET). */ +gpgme_error_t +gpgme_data_rewind (gpgme_data_t dh) +{ + gpgme_error_t err; + TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh); + + err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1) + ? gpg_error_from_syserror () : 0); + + return TRACE_ERR (err); +} + + /* Release the data object with the handle DH. */ void gpgme_data_release (gpgme_data_t dh) diff --git a/src/gpgme.h.in b/src/gpgme.h.in index e3ca165..769c2c8 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1165,9 +1165,8 @@ gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh, const char *fname, FILE *fp, @API__OFF_T@ offset, size_t length); -/* Reset the read pointer in DH. Deprecated, please use - gpgme_data_seek instead. */ -gpgme_error_t gpgme_data_rewind (gpgme_data_t dh) _GPGME_DEPRECATED(0,4); +/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET). */ +gpgme_error_t gpgme_data_rewind (gpgme_data_t dh); commit 9b7d81998b734fabeb4fbc697f08fc7795eaa90a Author: Werner Koch Date: Thu Feb 2 09:46:01 2017 +0100 core: Move all deprecated stuff to the end of gpgme.h. Signed-off-by: Werner Koch diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 4fc119f..e3ca165 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1,6 +1,6 @@ /* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*- * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001-2016 g10 Code GmbH + * Copyright (C) 2001-2017 g10 Code GmbH * * This file is part of GPGME. * @@ -294,24 +294,6 @@ typedef enum gpgme_hash_algo_t; -/* The possible signature stati. Deprecated, use error value in sig - status. */ -typedef enum - { - GPGME_SIG_STAT_NONE = 0, - GPGME_SIG_STAT_GOOD = 1, - GPGME_SIG_STAT_BAD = 2, - GPGME_SIG_STAT_NOKEY = 3, - GPGME_SIG_STAT_NOSIG = 4, - GPGME_SIG_STAT_ERROR = 5, - GPGME_SIG_STAT_DIFF = 6, - GPGME_SIG_STAT_GOOD_EXP = 7, - GPGME_SIG_STAT_GOOD_EXPKEY = 8 - } -_gpgme_sig_stat_t; -typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED(0,4); - - /* The available signature modes. */ typedef enum { @@ -322,47 +304,6 @@ typedef enum gpgme_sig_mode_t; -/* The available key and signature attributes. Deprecated, use the - individual result structures instead. */ -typedef enum - { - GPGME_ATTR_KEYID = 1, - GPGME_ATTR_FPR = 2, - GPGME_ATTR_ALGO = 3, - GPGME_ATTR_LEN = 4, - GPGME_ATTR_CREATED = 5, - GPGME_ATTR_EXPIRE = 6, - GPGME_ATTR_OTRUST = 7, - GPGME_ATTR_USERID = 8, - GPGME_ATTR_NAME = 9, - GPGME_ATTR_EMAIL = 10, - GPGME_ATTR_COMMENT = 11, - GPGME_ATTR_VALIDITY = 12, - GPGME_ATTR_LEVEL = 13, - GPGME_ATTR_TYPE = 14, - GPGME_ATTR_IS_SECRET = 15, - GPGME_ATTR_KEY_REVOKED = 16, - GPGME_ATTR_KEY_INVALID = 17, - GPGME_ATTR_UID_REVOKED = 18, - GPGME_ATTR_UID_INVALID = 19, - GPGME_ATTR_KEY_CAPS = 20, - GPGME_ATTR_CAN_ENCRYPT = 21, - GPGME_ATTR_CAN_SIGN = 22, - GPGME_ATTR_CAN_CERTIFY = 23, - GPGME_ATTR_KEY_EXPIRED = 24, - GPGME_ATTR_KEY_DISABLED = 25, - GPGME_ATTR_SERIAL = 26, - GPGME_ATTR_ISSUER = 27, - GPGME_ATTR_CHAINID = 28, - GPGME_ATTR_SIG_STATUS = 29, - GPGME_ATTR_ERRTOK = 30, - GPGME_ATTR_SIG_SUMMARY = 31, - GPGME_ATTR_SIG_CLASS = 32 - } -_gpgme_attr_t; -typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED(0,4); - - /* The available validities for a trust item or key. */ typedef enum { @@ -447,122 +388,6 @@ typedef unsigned int gpgme_export_mode_t; #define GPGME_AUDITLOG_WITH_HELP 128 -/* The possible stati for gpgme_op_edit. The use of that function and - * these status codes are deprecated in favor of gpgme_op_interact. */ -typedef enum - { - GPGME_STATUS_EOF = 0, - /* mkstatus processing starts here */ - GPGME_STATUS_ENTER = 1, - GPGME_STATUS_LEAVE = 2, - GPGME_STATUS_ABORT = 3, - - GPGME_STATUS_GOODSIG = 4, - GPGME_STATUS_BADSIG = 5, - GPGME_STATUS_ERRSIG = 6, - - GPGME_STATUS_BADARMOR = 7, - - GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */ - GPGME_STATUS_KEYEXPIRED = 9, - GPGME_STATUS_KEYREVOKED = 10, - - GPGME_STATUS_TRUST_UNDEFINED = 11, - GPGME_STATUS_TRUST_NEVER = 12, - GPGME_STATUS_TRUST_MARGINAL = 13, - GPGME_STATUS_TRUST_FULLY = 14, - GPGME_STATUS_TRUST_ULTIMATE = 15, - - GPGME_STATUS_SHM_INFO = 16, /* (legacy) */ - GPGME_STATUS_SHM_GET = 17, /* (legacy) */ - GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */ - GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */ - - GPGME_STATUS_NEED_PASSPHRASE = 20, - GPGME_STATUS_VALIDSIG = 21, - GPGME_STATUS_SIG_ID = 22, - GPGME_STATUS_ENC_TO = 23, - GPGME_STATUS_NODATA = 24, - GPGME_STATUS_BAD_PASSPHRASE = 25, - GPGME_STATUS_NO_PUBKEY = 26, - GPGME_STATUS_NO_SECKEY = 27, - GPGME_STATUS_NEED_PASSPHRASE_SYM = 28, - GPGME_STATUS_DECRYPTION_FAILED = 29, - GPGME_STATUS_DECRYPTION_OKAY = 30, - GPGME_STATUS_MISSING_PASSPHRASE = 31, - GPGME_STATUS_GOOD_PASSPHRASE = 32, - GPGME_STATUS_GOODMDC = 33, - GPGME_STATUS_BADMDC = 34, - GPGME_STATUS_ERRMDC = 35, - GPGME_STATUS_IMPORTED = 36, - GPGME_STATUS_IMPORT_OK = 37, - GPGME_STATUS_IMPORT_PROBLEM = 38, - GPGME_STATUS_IMPORT_RES = 39, - GPGME_STATUS_FILE_START = 40, - GPGME_STATUS_FILE_DONE = 41, - GPGME_STATUS_FILE_ERROR = 42, - - GPGME_STATUS_BEGIN_DECRYPTION = 43, - GPGME_STATUS_END_DECRYPTION = 44, - GPGME_STATUS_BEGIN_ENCRYPTION = 45, - GPGME_STATUS_END_ENCRYPTION = 46, - - GPGME_STATUS_DELETE_PROBLEM = 47, - GPGME_STATUS_GET_BOOL = 48, - GPGME_STATUS_GET_LINE = 49, - GPGME_STATUS_GET_HIDDEN = 50, - GPGME_STATUS_GOT_IT = 51, - GPGME_STATUS_PROGRESS = 52, - GPGME_STATUS_SIG_CREATED = 53, - GPGME_STATUS_SESSION_KEY = 54, - GPGME_STATUS_NOTATION_NAME = 55, - GPGME_STATUS_NOTATION_DATA = 56, - GPGME_STATUS_POLICY_URL = 57, - GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */ - GPGME_STATUS_END_STREAM = 59, /* (legacy) */ - GPGME_STATUS_KEY_CREATED = 60, - GPGME_STATUS_USERID_HINT = 61, - GPGME_STATUS_UNEXPECTED = 62, - GPGME_STATUS_INV_RECP = 63, - GPGME_STATUS_NO_RECP = 64, - GPGME_STATUS_ALREADY_SIGNED = 65, - GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */ - GPGME_STATUS_EXPSIG = 67, - GPGME_STATUS_EXPKEYSIG = 68, - GPGME_STATUS_TRUNCATED = 69, - GPGME_STATUS_ERROR = 70, - GPGME_STATUS_NEWSIG = 71, - GPGME_STATUS_REVKEYSIG = 72, - GPGME_STATUS_SIG_SUBPACKET = 73, - GPGME_STATUS_NEED_PASSPHRASE_PIN = 74, - GPGME_STATUS_SC_OP_FAILURE = 75, - GPGME_STATUS_SC_OP_SUCCESS = 76, - GPGME_STATUS_CARDCTRL = 77, - GPGME_STATUS_BACKUP_KEY_CREATED = 78, - GPGME_STATUS_PKA_TRUST_BAD = 79, - GPGME_STATUS_PKA_TRUST_GOOD = 80, - GPGME_STATUS_PLAINTEXT = 81, - GPGME_STATUS_INV_SGNR = 82, - GPGME_STATUS_NO_SGNR = 83, - GPGME_STATUS_SUCCESS = 84, - GPGME_STATUS_DECRYPTION_INFO = 85, - GPGME_STATUS_PLAINTEXT_LENGTH = 86, - GPGME_STATUS_MOUNTPOINT = 87, - GPGME_STATUS_PINENTRY_LAUNCHED = 88, - GPGME_STATUS_ATTRIBUTE = 89, - GPGME_STATUS_BEGIN_SIGNING = 90, - GPGME_STATUS_KEY_NOT_CREATED = 91, - GPGME_STATUS_INQUIRE_MAXLEN = 92, - GPGME_STATUS_FAILURE = 93, - GPGME_STATUS_KEY_CONSIDERED = 94, - GPGME_STATUS_TOFU_USER = 95, - GPGME_STATUS_TOFU_STATS = 96, - GPGME_STATUS_TOFU_STATS_LONG = 97, - GPGME_STATUS_NOTATION_FLAGS = 98 - } -gpgme_status_code_t; - - /* The available signature notation flags. */ #define GPGME_SIG_NOTATION_HUMAN_READABLE 1 #define GPGME_SIG_NOTATION_CRITICAL 2 @@ -976,13 +801,6 @@ typedef gpgme_error_t (*gpgme_interact_cb_t) (void *opaque, const char *keyword, const char *args, int fd); -/* The callback type used by the deprecated functions gpgme_op_edit - * and gpgme_op_card_edit. */ -typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque, - gpgme_status_code_t status, - const char *args, int fd); - - /* @@ -1122,33 +940,6 @@ unsigned int gpgme_signers_count (const gpgme_ctx_t ctx); /* Return the SEQth signer's key in CTX. */ gpgme_key_t gpgme_signers_enum (const gpgme_ctx_t ctx, int seq); -/* Retrieve the signature status of signature IDX in CTX after a - successful verify operation in R_STAT (if non-null). The creation - time stamp of the signature is returned in R_CREATED (if non-null). - The function returns a string containing the fingerprint. - Deprecated, use verify result directly. */ -const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx, - _gpgme_sig_stat_t *r_stat, - time_t *r_created) _GPGME_DEPRECATED(0,4); - -/* Retrieve certain attributes of a signature. IDX is the index - number of the signature after a successful verify operation. WHAT - is an attribute where GPGME_ATTR_EXPIRE is probably the most useful - one. WHATIDX is to be passed as 0 for most attributes . */ -unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx, - _gpgme_attr_t what, int whatidx) - _GPGME_DEPRECATED(0,4); -const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx, - _gpgme_attr_t what, int whatidx) - _GPGME_DEPRECATED(0,4); - - -/* Get the key used to create signature IDX in CTX and return it in - R_KEY. */ -gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key) - _GPGME_DEPRECATED(0,4); - - /* Clear all notation data from the context. */ void gpgme_sig_notation_clear (gpgme_ctx_t ctx); @@ -1360,15 +1151,6 @@ gpg_error_t gpgme_data_set_flag (gpgme_data_t dh, gpgme_data_type_t gpgme_data_identify (gpgme_data_t dh, int reserved); -/* Create a new data buffer which retrieves the data from the callback - function READ_CB. Deprecated, please use gpgme_data_new_from_cbs - instead. */ -gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh, - int (*read_cb) (void*,char *, - size_t,size_t*), - void *read_cb_value) - _GPGME_DEPRECATED(0,4); - /* Create a new data buffer filled with the content of file FNAME. COPY must be non-zero. For delayed read, please use gpgme_data_new_from_fd or gpgme_data_new_from_stream instead. */ @@ -1409,40 +1191,6 @@ void gpgme_key_ref (gpgme_key_t key); void gpgme_key_unref (gpgme_key_t key); void gpgme_key_release (gpgme_key_t key); -/* Return the value of the attribute WHAT of KEY, which has to be - representable by a string. IDX specifies the sub key or user ID - for attributes related to sub keys or user IDs. Deprecated, use - key structure directly instead. */ -const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what, - const void *reserved, int idx) - _GPGME_DEPRECATED(0,4); - -/* Return the value of the attribute WHAT of KEY, which has to be - representable by an unsigned integer. IDX specifies the sub key or - user ID for attributes related to sub keys or user IDs. - Deprecated, use key structure directly instead. */ -unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what, - const void *reserved, int idx) - _GPGME_DEPRECATED(0,4); - -/* Return the value of the attribute WHAT of a signature on user ID - UID_IDX in KEY, which has to be representable by a string. IDX - specifies the signature. Deprecated, use key structure directly - instead. */ -const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx, - _gpgme_attr_t what, - const void *reserved, int idx) - _GPGME_DEPRECATED(0,4); - -/* Return the value of the attribute WHAT of a signature on user ID - UID_IDX in KEY, which has to be representable by an unsigned - integer string. IDX specifies the signature. Deprecated, use key - structure directly instead. */ -unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, - _gpgme_attr_t what, - const void *reserved, int idx) - _GPGME_DEPRECATED(0,4); - /* @@ -1797,8 +1545,6 @@ gpgme_import_result_t gpgme_op_import_result (gpgme_ctx_t ctx); /* Import the key in KEYDATA into the keyring. */ gpgme_error_t gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata); gpgme_error_t gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata); -gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata, - int *nr) _GPGME_DEPRECATED(0,4); /* Import the keys from the array KEYS into the keyring. */ gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t keys[]); @@ -1989,21 +1735,6 @@ gpgme_error_t gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key, void *fnc_value, gpgme_data_t out); -gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key, - gpgme_edit_cb_t fnc, void *fnc_value, - gpgme_data_t out) _GPGME_DEPRECATED(1,7); -gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key, - gpgme_edit_cb_t fnc, void *fnc_value, - gpgme_data_t out) _GPGME_DEPRECATED(1,7); -gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key, - gpgme_edit_cb_t fnc, void *fnc_value, - gpgme_data_t out) - _GPGME_DEPRECATED(1,7); -gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key, - gpgme_edit_cb_t fnc, void *fnc_value, - gpgme_data_t out) - _GPGME_DEPRECATED(1,7); - /* Set the Tofu policy of KEY to POLCIY. */ gpgme_error_t gpgme_op_tofu_policy_start (gpgme_ctx_t ctx, @@ -2113,26 +1844,6 @@ void gpgme_trust_item_ref (gpgme_trust_item_t item); item is destroyed. */ void gpgme_trust_item_unref (gpgme_trust_item_t item); -/* Release the trust item ITEM. Deprecated, use - gpgme_trust_item_unref. */ -void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED(0,4); - -/* Return the value of the attribute WHAT of ITEM, which has to be - representable by a string. Deprecated, use trust item structure - directly. */ -const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item, - _gpgme_attr_t what, - const void *reserved, int idx) - _GPGME_DEPRECATED(0,4); - -/* Return the value of the attribute WHAT of KEY, which has to be - representable by an integer. IDX specifies a running index if the - attribute appears more than once in the key. Deprecated, use trust - item structure directly. */ -int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what, - const void *reserved, int idx) - _GPGME_DEPRECATED(0,4); - /* @@ -2209,30 +1920,6 @@ gpgme_error_t gpgme_op_assuan_transact_ext (gpgme_ctx_t ctx, void *stat_cb_value, gpgme_error_t *op_err); -/* Compat. */ -struct _gpgme_op_assuan_result -{ - /* Deprecated. Use the second value in a DONE event or the - synchronous variant gpgme_op_assuan_transact_ext. */ - gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME(1,2); -}; -typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t; - - -/* Return the result of the last Assuan command. */ -gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx) - _GPGME_DEPRECATED(1,2); - -gpgme_error_t -gpgme_op_assuan_transact (gpgme_ctx_t ctx, - const char *command, - gpgme_assuan_data_cb_t data_cb, - void *data_cb_value, - gpgme_assuan_inquire_cb_t inq_cb, - void *inq_cb_value, - gpgme_assuan_status_cb_t status_cb, - void *status_cb_value) _GPGME_DEPRECATED(1,2); - /* * Crypto container support. @@ -2553,8 +2240,321 @@ char *gpgme_addrspec_from_uid (const char *uid); /* - * Deprecated types. + * Deprecated types, constants and functions. */ + +/* The possible stati for gpgme_op_edit. The use of that function and + * these status codes are deprecated in favor of gpgme_op_interact. */ +typedef enum + { + GPGME_STATUS_EOF = 0, + /* mkstatus processing starts here */ + GPGME_STATUS_ENTER = 1, + GPGME_STATUS_LEAVE = 2, + GPGME_STATUS_ABORT = 3, + + GPGME_STATUS_GOODSIG = 4, + GPGME_STATUS_BADSIG = 5, + GPGME_STATUS_ERRSIG = 6, + + GPGME_STATUS_BADARMOR = 7, + + GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */ + GPGME_STATUS_KEYEXPIRED = 9, + GPGME_STATUS_KEYREVOKED = 10, + + GPGME_STATUS_TRUST_UNDEFINED = 11, + GPGME_STATUS_TRUST_NEVER = 12, + GPGME_STATUS_TRUST_MARGINAL = 13, + GPGME_STATUS_TRUST_FULLY = 14, + GPGME_STATUS_TRUST_ULTIMATE = 15, + + GPGME_STATUS_SHM_INFO = 16, /* (legacy) */ + GPGME_STATUS_SHM_GET = 17, /* (legacy) */ + GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */ + GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */ + + GPGME_STATUS_NEED_PASSPHRASE = 20, + GPGME_STATUS_VALIDSIG = 21, + GPGME_STATUS_SIG_ID = 22, + GPGME_STATUS_ENC_TO = 23, + GPGME_STATUS_NODATA = 24, + GPGME_STATUS_BAD_PASSPHRASE = 25, + GPGME_STATUS_NO_PUBKEY = 26, + GPGME_STATUS_NO_SECKEY = 27, + GPGME_STATUS_NEED_PASSPHRASE_SYM = 28, + GPGME_STATUS_DECRYPTION_FAILED = 29, + GPGME_STATUS_DECRYPTION_OKAY = 30, + GPGME_STATUS_MISSING_PASSPHRASE = 31, + GPGME_STATUS_GOOD_PASSPHRASE = 32, + GPGME_STATUS_GOODMDC = 33, + GPGME_STATUS_BADMDC = 34, + GPGME_STATUS_ERRMDC = 35, + GPGME_STATUS_IMPORTED = 36, + GPGME_STATUS_IMPORT_OK = 37, + GPGME_STATUS_IMPORT_PROBLEM = 38, + GPGME_STATUS_IMPORT_RES = 39, + GPGME_STATUS_FILE_START = 40, + GPGME_STATUS_FILE_DONE = 41, + GPGME_STATUS_FILE_ERROR = 42, + + GPGME_STATUS_BEGIN_DECRYPTION = 43, + GPGME_STATUS_END_DECRYPTION = 44, + GPGME_STATUS_BEGIN_ENCRYPTION = 45, + GPGME_STATUS_END_ENCRYPTION = 46, + + GPGME_STATUS_DELETE_PROBLEM = 47, + GPGME_STATUS_GET_BOOL = 48, + GPGME_STATUS_GET_LINE = 49, + GPGME_STATUS_GET_HIDDEN = 50, + GPGME_STATUS_GOT_IT = 51, + GPGME_STATUS_PROGRESS = 52, + GPGME_STATUS_SIG_CREATED = 53, + GPGME_STATUS_SESSION_KEY = 54, + GPGME_STATUS_NOTATION_NAME = 55, + GPGME_STATUS_NOTATION_DATA = 56, + GPGME_STATUS_POLICY_URL = 57, + GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */ + GPGME_STATUS_END_STREAM = 59, /* (legacy) */ + GPGME_STATUS_KEY_CREATED = 60, + GPGME_STATUS_USERID_HINT = 61, + GPGME_STATUS_UNEXPECTED = 62, + GPGME_STATUS_INV_RECP = 63, + GPGME_STATUS_NO_RECP = 64, + GPGME_STATUS_ALREADY_SIGNED = 65, + GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */ + GPGME_STATUS_EXPSIG = 67, + GPGME_STATUS_EXPKEYSIG = 68, + GPGME_STATUS_TRUNCATED = 69, + GPGME_STATUS_ERROR = 70, + GPGME_STATUS_NEWSIG = 71, + GPGME_STATUS_REVKEYSIG = 72, + GPGME_STATUS_SIG_SUBPACKET = 73, + GPGME_STATUS_NEED_PASSPHRASE_PIN = 74, + GPGME_STATUS_SC_OP_FAILURE = 75, + GPGME_STATUS_SC_OP_SUCCESS = 76, + GPGME_STATUS_CARDCTRL = 77, + GPGME_STATUS_BACKUP_KEY_CREATED = 78, + GPGME_STATUS_PKA_TRUST_BAD = 79, + GPGME_STATUS_PKA_TRUST_GOOD = 80, + GPGME_STATUS_PLAINTEXT = 81, + GPGME_STATUS_INV_SGNR = 82, + GPGME_STATUS_NO_SGNR = 83, + GPGME_STATUS_SUCCESS = 84, + GPGME_STATUS_DECRYPTION_INFO = 85, + GPGME_STATUS_PLAINTEXT_LENGTH = 86, + GPGME_STATUS_MOUNTPOINT = 87, + GPGME_STATUS_PINENTRY_LAUNCHED = 88, + GPGME_STATUS_ATTRIBUTE = 89, + GPGME_STATUS_BEGIN_SIGNING = 90, + GPGME_STATUS_KEY_NOT_CREATED = 91, + GPGME_STATUS_INQUIRE_MAXLEN = 92, + GPGME_STATUS_FAILURE = 93, + GPGME_STATUS_KEY_CONSIDERED = 94, + GPGME_STATUS_TOFU_USER = 95, + GPGME_STATUS_TOFU_STATS = 96, + GPGME_STATUS_TOFU_STATS_LONG = 97, + GPGME_STATUS_NOTATION_FLAGS = 98 + } +gpgme_status_code_t; + +/* The callback type used by the deprecated functions gpgme_op_edit + * and gpgme_op_card_edit. */ +typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque, + gpgme_status_code_t status, + const char *args, int fd); + +gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key, + gpgme_edit_cb_t fnc, void *fnc_value, + gpgme_data_t out) _GPGME_DEPRECATED(1,7); +gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key, + gpgme_edit_cb_t fnc, void *fnc_value, + gpgme_data_t out) _GPGME_DEPRECATED(1,7); +gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key, + gpgme_edit_cb_t fnc, void *fnc_value, + gpgme_data_t out) + _GPGME_DEPRECATED(1,7); +gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key, + gpgme_edit_cb_t fnc, void *fnc_value, + gpgme_data_t out) + _GPGME_DEPRECATED(1,7); + +/* The possible signature stati. Deprecated, use error value in sig + status. */ +typedef enum + { + GPGME_SIG_STAT_NONE = 0, + GPGME_SIG_STAT_GOOD = 1, + GPGME_SIG_STAT_BAD = 2, + GPGME_SIG_STAT_NOKEY = 3, + GPGME_SIG_STAT_NOSIG = 4, + GPGME_SIG_STAT_ERROR = 5, + GPGME_SIG_STAT_DIFF = 6, + GPGME_SIG_STAT_GOOD_EXP = 7, + GPGME_SIG_STAT_GOOD_EXPKEY = 8 + } +_gpgme_sig_stat_t; +typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED(0,4); + +/* The available key and signature attributes. Deprecated, use the + individual result structures instead. */ +typedef enum + { + GPGME_ATTR_KEYID = 1, + GPGME_ATTR_FPR = 2, + GPGME_ATTR_ALGO = 3, + GPGME_ATTR_LEN = 4, + GPGME_ATTR_CREATED = 5, + GPGME_ATTR_EXPIRE = 6, + GPGME_ATTR_OTRUST = 7, + GPGME_ATTR_USERID = 8, + GPGME_ATTR_NAME = 9, + GPGME_ATTR_EMAIL = 10, + GPGME_ATTR_COMMENT = 11, + GPGME_ATTR_VALIDITY = 12, + GPGME_ATTR_LEVEL = 13, + GPGME_ATTR_TYPE = 14, + GPGME_ATTR_IS_SECRET = 15, + GPGME_ATTR_KEY_REVOKED = 16, + GPGME_ATTR_KEY_INVALID = 17, + GPGME_ATTR_UID_REVOKED = 18, + GPGME_ATTR_UID_INVALID = 19, + GPGME_ATTR_KEY_CAPS = 20, + GPGME_ATTR_CAN_ENCRYPT = 21, + GPGME_ATTR_CAN_SIGN = 22, + GPGME_ATTR_CAN_CERTIFY = 23, + GPGME_ATTR_KEY_EXPIRED = 24, + GPGME_ATTR_KEY_DISABLED = 25, + GPGME_ATTR_SERIAL = 26, + GPGME_ATTR_ISSUER = 27, + GPGME_ATTR_CHAINID = 28, + GPGME_ATTR_SIG_STATUS = 29, + GPGME_ATTR_ERRTOK = 30, + GPGME_ATTR_SIG_SUMMARY = 31, + GPGME_ATTR_SIG_CLASS = 32 + } +_gpgme_attr_t; +typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED(0,4); + +/* Retrieve the signature status of signature IDX in CTX after a + successful verify operation in R_STAT (if non-null). The creation + time stamp of the signature is returned in R_CREATED (if non-null). + The function returns a string containing the fingerprint. + Deprecated, use verify result directly. */ +const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx, + _gpgme_sig_stat_t *r_stat, + time_t *r_created) _GPGME_DEPRECATED(0,4); + +/* Retrieve certain attributes of a signature. IDX is the index + number of the signature after a successful verify operation. WHAT + is an attribute where GPGME_ATTR_EXPIRE is probably the most useful + one. WHATIDX is to be passed as 0 for most attributes . */ +unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx, + _gpgme_attr_t what, int whatidx) + _GPGME_DEPRECATED(0,4); +const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx, + _gpgme_attr_t what, int whatidx) + _GPGME_DEPRECATED(0,4); + + +/* Get the key used to create signature IDX in CTX and return it in + R_KEY. */ +gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key) + _GPGME_DEPRECATED(0,4); + +/* Create a new data buffer which retrieves the data from the callback + function READ_CB. Deprecated, please use gpgme_data_new_from_cbs + instead. */ +gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh, + int (*read_cb) (void*,char *, + size_t,size_t*), + void *read_cb_value) + _GPGME_DEPRECATED(0,4); + +/* Return the value of the attribute WHAT of KEY, which has to be + representable by a string. IDX specifies the sub key or user ID + for attributes related to sub keys or user IDs. Deprecated, use + key structure directly instead. */ +const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what, + const void *reserved, int idx) + _GPGME_DEPRECATED(0,4); + +/* Return the value of the attribute WHAT of KEY, which has to be + representable by an unsigned integer. IDX specifies the sub key or + user ID for attributes related to sub keys or user IDs. + Deprecated, use key structure directly instead. */ +unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what, + const void *reserved, int idx) + _GPGME_DEPRECATED(0,4); + +/* Return the value of the attribute WHAT of a signature on user ID + UID_IDX in KEY, which has to be representable by a string. IDX + specifies the signature. Deprecated, use key structure directly + instead. */ +const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx, + _gpgme_attr_t what, + const void *reserved, int idx) + _GPGME_DEPRECATED(0,4); + +/* Return the value of the attribute WHAT of a signature on user ID + UID_IDX in KEY, which has to be representable by an unsigned + integer string. IDX specifies the signature. Deprecated, use key + structure directly instead. */ +unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, + _gpgme_attr_t what, + const void *reserved, int idx) + _GPGME_DEPRECATED(0,4); + + +gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata, + int *nr) _GPGME_DEPRECATED(0,4); + +/* Release the trust item ITEM. Deprecated, use + gpgme_trust_item_unref. */ +void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED(0,4); + +/* Return the value of the attribute WHAT of ITEM, which has to be + representable by a string. Deprecated, use trust item structure + directly. */ +const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item, + _gpgme_attr_t what, + const void *reserved, int idx) + _GPGME_DEPRECATED(0,4); + +/* Return the value of the attribute WHAT of KEY, which has to be + representable by an integer. IDX specifies a running index if the + attribute appears more than once in the key. Deprecated, use trust + item structure directly. */ +int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what, + const void *reserved, int idx) + _GPGME_DEPRECATED(0,4); + +/* Compat. */ +struct _gpgme_op_assuan_result +{ + /* Deprecated. Use the second value in a DONE event or the + synchronous variant gpgme_op_assuan_transact_ext. */ + gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME(1,2); +}; +typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t; + + +/* Return the result of the last Assuan command. */ +gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx) + _GPGME_DEPRECATED(1,2); + +gpgme_error_t +gpgme_op_assuan_transact (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) _GPGME_DEPRECATED(1,2); + + + typedef gpgme_ctx_t GpgmeCtx _GPGME_DEPRECATED(0,4); typedef gpgme_data_t GpgmeData _GPGME_DEPRECATED(0,4); typedef gpgme_error_t GpgmeError _GPGME_DEPRECATED(0,4); ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + src/data-compat.c | 13 - src/data.c | 14 ++ src/gpgme.h.in | 713 +++++++++++++++++++++++++++++------------------------- 4 files changed, 401 insertions(+), 340 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 11:57:18 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 02 Feb 2017 11:57:18 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-9-g4bfc211 Message-ID: This is an 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 4bfc2117b70415a5c5d3f0a0ac9086e168350d83 (commit) from 55c497904dd0794ca5cfcafe369943736b0d4e62 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4bfc2117b70415a5c5d3f0a0ac9086e168350d83 Author: NIIBE Yutaka Date: Wed Feb 1 19:45:39 2017 +0900 Add Base64 decoder. * NEWS: Add interface changes. * src/Makefile.am (libgpg_error_la_SOURCES): Add b64dec.c. * src/b64dec.c: New. Taken from gpgme. Prefix function names with _gpgrt_. Change API a bit, not exposing the structure. * src/gpg-error.def.in: Export Base64 functions. * src/gpg-error.vers: Likewise. * src/visibility.c, src/visibility.h: Likewise. * src/gpg-error.h.in: Add Base64 struct and functions. * src/gpgrt-int.h: Add Base64 internal functions. * tests/Makefile.am (TESTS): Add t-b64dec. * tests/t-b64dec.c: New. Signed-off-by: NIIBE Yutaka diff --git a/NEWS b/NEWS index 572385f..912dd0c 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,13 @@ Noteworthy changes in version 1.27 (unreleased) [C2_/A2_/R_] * Fixed macro GPGRT_GCC_VERSION. + * Interface changes relative to the 1.26 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgrt_b64state_t NEW type. + gpgrt_b64dec_start NEW. + gpgrt_b64dec_proc NEW. + gpgrt_b64dec_finish NEW. + Noteworthy changes in version 1.26 (2016-12-21) [C21/A21/R0] ----------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index 1eb8287..d849c42 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,7 +179,7 @@ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \ gpgrt-int.h init.c init.h version.c lock.h thread.h \ estream.c estream-printf.c estream-printf.h \ strsource.c strerror.c code-to-errno.c code-from-errno.c \ - visibility.c visibility.h + visibility.c visibility.h b64dec.c nodist_libgpg_error_la_SOURCES = gpg-error.h # libgpg_error_la_DEPENDENCIES = \ diff --git a/src/b64dec.c b/src/b64dec.c new file mode 100644 index 0000000..d846a6a --- /dev/null +++ b/src/b64dec.c @@ -0,0 +1,279 @@ +/* b64dec.c - Simple Base64 decoder. + * Copyright (C) 2008, 2011 Free Software Foundation, Inc. + * Copyright (C) 2008, 2011, 2016 g10 Code GmbH + * + * 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 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 +#include +#include +#include +#include + +#include "gpgrt-int.h" + +struct _gpgrt_b64state +{ + int idx; + int quad_count; + char *title; + unsigned char radbuf[4]; + int stop_seen:1; + int invalid_encoding:1; + gpg_error_t lasterr; +}; + +/* The reverse base-64 list used for base-64 decoding. */ +static unsigned char const asctobin[128] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff + }; + +enum decoder_states + { + s_init, s_idle, s_lfseen, s_beginseen, s_waitheader, s_waitblank, s_begin, + s_b64_0, s_b64_1, s_b64_2, s_b64_3, + s_waitendtitle, s_waitend + }; + + + +/* Allocate and initialize the context for the base64 decoder. If + TITLE is NULL a plain base64 decoding is done. If it is the empty + string the decoder will skip everything until a "-----BEGIN " line + has been seen, decoding ends at a "----END " line. */ +gpgrt_b64state_t +_gpgrt_b64dec_start (const char *title) +{ + gpgrt_b64state_t state; + char *t = NULL; + + if (title) + { + t = strdup (title); + if (!t) + return NULL; + } + + state = calloc (1, sizeof (struct _gpgrt_b64state)); + if (!state) + { + free (t); + return NULL; + } + + if (t) + { + state->title = t; + state->idx = s_init; + } + else + state->idx = s_b64_0; + + return state; +} + + +/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Stores the + new length of the buffer at R_NBYTES. */ +gpg_error_t +_gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t length, + size_t *r_nbytes) +{ + enum decoder_states ds = state->idx; + unsigned char val = state->radbuf[0]; + int pos = state->quad_count; + char *d, *s; + + if (state->lasterr) + return state->lasterr; + + if (state->stop_seen) + { + *r_nbytes = 0; + state->lasterr = gpg_error (GPG_ERR_EOF); + free (state->title); + state->title = NULL; + return state->lasterr; + } + + for (s=d=buffer; length && !state->stop_seen; length--, s++) + { + again: + switch (ds) + { + case s_idle: + if (*s == '\n') + { + ds = s_lfseen; + pos = 0; + } + break; + case s_init: + ds = s_lfseen; + case s_lfseen: + if (*s != "-----BEGIN "[pos]) + { + ds = s_idle; + goto again; + } + else if (pos == 10) + { + pos = 0; + ds = s_beginseen; + } + else + pos++; + break; + case s_beginseen: + if (*s != "PGP "[pos]) + ds = s_begin; /* Not a PGP armor. */ + else if (pos == 3) + ds = s_waitheader; + else + pos++; + break; + case s_waitheader: + if (*s == '\n') + ds = s_waitblank; + break; + case s_waitblank: + if (*s == '\n') + ds = s_b64_0; /* blank line found. */ + else if (*s == ' ' || *s == '\r' || *s == '\t') + ; /* Ignore spaces. */ + else + { + /* Armor header line. Note that we don't care that our + * FSM accepts a header prefixed with spaces. */ + ds = s_waitheader; /* Wait for next header. */ + } + break; + case s_begin: + if (*s == '\n') + ds = s_b64_0; + break; + case s_b64_0: + case s_b64_1: + case s_b64_2: + case s_b64_3: + { + int c; + + if (*s == '-' && state->title) + { + /* Not a valid Base64 character: assume end + header. */ + ds = s_waitend; + } + else if (*s == '=') + { + /* Pad character: stop */ + if (ds == s_b64_1) + *d++ = val; + ds = state->title? s_waitendtitle : s_waitend; + } + else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t') + ; /* Skip white spaces. */ + else if ( (*s & 0x80) + || (c = asctobin[*(unsigned char *)s]) == 255) + { + /* Skip invalid encodings. */ + state->invalid_encoding = 1; + } + else if (ds == s_b64_0) + { + val = c << 2; + ds = s_b64_1; + } + else if (ds == s_b64_1) + { + val |= (c>>4)&3; + *d++ = val; + val = (c<<4)&0xf0; + ds = s_b64_2; + } + else if (ds == s_b64_2) + { + val |= (c>>2)&15; + *d++ = val; + val = (c<<6)&0xc0; + ds = s_b64_3; + } + else + { + val |= c&0x3f; + *d++ = val; + ds = s_b64_0; + } + } + break; + case s_waitendtitle: + if (*s == '-') + ds = s_waitend; + break; + case s_waitend: + if ( *s == '\n') + state->stop_seen = 1; + break; + default: + assert (!"invalid state"); + } + } + + + state->idx = ds; + state->radbuf[0] = val; + state->quad_count = pos; + *r_nbytes = (d -(char*) buffer); + return 0; +} + + +/* Return an error code in case an encoding error has been found + during decoding. */ +gpg_error_t +_gpgrt_b64dec_finish (gpgrt_b64state_t state) +{ + gpg_error_t err; + + if (state->lasterr) + err = state->lasterr; + else + { + free (state->title); + err = state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; + } + free (state); + + return err; +} diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 19e87fa..ad65f8c 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -152,4 +152,8 @@ EXPORTS gpgrt_get_syscall_clamp @112 + gpgrt_b64dec_start @113 + gpgrt_b64dec_proc @114 + gpgrt_b64dec_finish @115 + ;; end of file with public symbols for Windows. diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index c603314..19bdeed 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -853,6 +853,16 @@ int gpgrt_vsnprintf (char *buf,size_t bufsize, # define es_bsprintf gpgrt_bsprintf # define es_vbsprintf gpgrt_vbsprintf #endif /*GPGRT_ENABLE_ES_MACROS*/ + +/* Base64 decode functions. */ + +struct _gpgrt_b64state; +typedef struct _gpgrt_b64state *gpgrt_b64state_t; + +gpgrt_b64state_t gpgrt_b64dec_start (const char *title); +gpg_error_t gpgrt_b64dec_proc (gpgrt_b64state_t state, + void *buffer, size_t length, size_t *r_nbytes); +gpg_error_t gpgrt_b64dec_finish (gpgrt_b64state_t state); #ifdef __cplusplus } diff --git a/src/gpg-error.vers b/src/gpg-error.vers index 802ff3d..e44128c 100644 --- a/src/gpg-error.vers +++ b/src/gpg-error.vers @@ -126,6 +126,10 @@ GPG_ERROR_1.0 { gpg_err_deinit; gpgrt_set_alloc_func; + gpgrt_b64dec_start; + gpgrt_b64dec_proc; + gpgrt_b64dec_finish; + local: *; }; diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index fba2585..d624e84 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -312,4 +312,10 @@ int _gpgrt_w32_pollable_create (void *_GPGRT__RESTRICT *_GPGRT__RESTRICT cookie, int _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout); #endif +gpgrt_b64state_t _gpgrt_b64dec_start (const char *title); +gpg_error_t _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, + size_t length, size_t *r_nbytes); +gpg_error_t _gpgrt_b64dec_finish (gpgrt_b64state_t state); + + #endif /*_GPGRT_GPGRT_INT_H*/ diff --git a/src/visibility.c b/src/visibility.c index 89b5623..b637e7a 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -711,3 +711,22 @@ gpgrt_vsnprintf (char *buf, size_t bufsize, { return _gpgrt_estream_vsnprintf (buf, bufsize, format, arg_ptr); } + +gpgrt_b64state_t +gpgrt_b64dec_start (const char *title) +{ + return _gpgrt_b64dec_start (title); +} + +gpg_error_t +gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, + size_t length, size_t *r_nbytes) +{ + return _gpgrt_b64dec_proc (state, buffer, length, r_nbytes); +} + +gpg_error_t +gpgrt_b64dec_finish (gpgrt_b64state_t state) +{ + return _gpgrt_b64dec_finish (state); +} diff --git a/src/visibility.h b/src/visibility.h index 479186f..da8e228 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -145,6 +145,10 @@ MARK_VISIBLE (gpgrt_set_syscall_clamp) MARK_VISIBLE (gpgrt_get_syscall_clamp) MARK_VISIBLE (gpgrt_set_alloc_func) +MARK_VISIBLE (gpgrt_b64dec_start) +MARK_VISIBLE (gpgrt_b64dec_proc) +MARK_VISIBLE (gpgrt_b64dec_finish) + #undef MARK_VISIBLE #else /*!_GPGRT_INCL_BY_VISIBILITY_C*/ @@ -255,6 +259,9 @@ MARK_VISIBLE (gpgrt_set_alloc_func) #define gpgrt_get_syscall_clamp _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_set_alloc_func _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_b64dec_start _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_b64dec_proc _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_b64dec_finish _gpgrt_USE_UNDERSCORED_FUNCTION #endif /*!_GPGRT_INCL_BY_VISIBILITY_C*/ diff --git a/tests/Makefile.am b/tests/Makefile.am index 92b97f2..a3c6cbd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,7 +27,7 @@ endif gpg_error_lib = ../src/libgpg-error.la -TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll +TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll t-b64dec AM_CPPFLAGS = -I$(top_builddir)/src $(extra_includes) diff --git a/tests/t-b64dec.c b/tests/t-b64dec.c new file mode 100644 index 0000000..aae208b --- /dev/null +++ b/tests/t-b64dec.c @@ -0,0 +1,123 @@ +/* t-b64dec.c - b64dec test. + Copyright (C) 2017 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error 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. + + libgpg-error 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 libgpgme-error; if not, write to the Free + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#if HAVE_STDLIB_H +#include +#endif + +#include + +static const char *test_b64_string = "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29" + "mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgd" + "W5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIEx" + "pY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb" + "247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXI" + "gb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4="; + +static const char *test_string = "libgpg-error 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."; + +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + errcount++; \ + } while(0) + +static int errcount; + +static gpg_error_t +test_b64dec_string (const char *string, const char *expected) +{ + gpg_error_t err; + gpgrt_b64state_t state; + char *buffer; + size_t len; + + len = strlen (string); + buffer = malloc (strlen (string) + 1); + if (!buffer) + { + err = gpg_error_from_syserror (); + return err; + } + + state = gpgrt_b64dec_start (""); + if (!state) + { + err = gpg_error_from_syserror (); + free (buffer); + return err; + } + + err = gpgrt_b64dec_proc (state, buffer, len, &len); + if (err) + { + if (gpg_err_code (err) != GPG_ERR_EOF) + { + free (buffer); + free (state); + return err; + } + } + + err = gpgrt_b64dec_finish (state); + if (err) + { + free (buffer); + return err; + } + + if (strncmp (buffer, expected, len) == 0) + err = 0; + else + err = GPG_ERR_INTERNAL; + + free (buffer); + return err; +} + + + +int +main (int argc, char **argv) +{ + gpg_error_t err; + + (void)argc; + (void)argv; + + err = test_b64dec_string (test_b64_string, test_string); + + if (err) + { + fail (1); + return 1; + } + else + return 0; +} ----------------------------------------------------------------------- Summary of changes: NEWS | 7 ++ src/Makefile.am | 2 +- src/b64dec.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/gpg-error.def.in | 4 + src/gpg-error.h.in | 10 ++ src/gpg-error.vers | 4 + src/gpgrt-int.h | 6 ++ src/visibility.c | 19 ++++ src/visibility.h | 7 ++ tests/Makefile.am | 2 +- tests/t-b64dec.c | 123 +++++++++++++++++++++++ 11 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 src/b64dec.c create mode 100644 tests/t-b64dec.c hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 12:02:53 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 02 Feb 2017 12:02:53 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-10-g67e51f9 Message-ID: This is an 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 67e51f9957f875ca854f25f4a9a63aeb831c55c4 (commit) from 4bfc2117b70415a5c5d3f0a0ac9086e168350d83 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 67e51f9957f875ca854f25f4a9a63aeb831c55c4 Author: NIIBE Yutaka Date: Thu Feb 2 20:02:12 2017 +0900 syscfg: Add a sh3 architecture. * src/syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h: New. * src/Makefile.am (lock_obj_pub): Add it. -- Signed-off-by: NIIBE Yutaka diff --git a/src/Makefile.am b/src/Makefile.am index d849c42..06ba1cd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,6 +66,7 @@ lock_obj_pub = \ syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnuspe.h \ syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h \ + syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sh4-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sparc-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sparc64-unknown-linux-gnu.h \ diff --git a/src/syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h b/src/syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h new file mode 100644 index 0000000..a2ff11f --- /dev/null +++ b/src/syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h @@ -0,0 +1,23 @@ +## lock-obj-pub.sh3-unknown-linux-gnu.h +## File created by gen-posix-lock-obj - DO NOT EDIT +## To be included by mkheader into gpg-error.h + +typedef struct +{ + long _vers; + union { + volatile char _priv[24]; + long _x_align; + long *_xp_align; + } u; +} gpgrt_lock_t; + +#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0}}} +## +## Local Variables: +## mode: c +## buffer-read-only: t +## End: +## ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 1 + ...pub.sh4-unknown-linux-gnu.h => lock-obj-pub.sh3-unknown-linux-gnu.h} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) copy src/syscfg/{lock-obj-pub.sh4-unknown-linux-gnu.h => lock-obj-pub.sh3-unknown-linux-gnu.h} (92%) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 12:43:32 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 02 Feb 2017 12:43:32 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-50-g15050ce Message-ID: This is an 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 15050ce5fce4ed815503db7c029abb38d08970d6 (commit) via 563420a88f8a4f561a2faea4d2b4a1c58b375fd8 (commit) from 0ceeb2948c7210f120e5ddda1ca20a4bbbf83378 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 15050ce5fce4ed815503db7c029abb38d08970d6 Author: Werner Koch Date: Thu Feb 2 12:35:59 2017 +0100 core: Replace all calls to *sprintf by gpgrt_*sprintf. * configure.ac (vasprintf): Remove check. * src/vasprintf.c: Remove file. * src/util.h (vasprintf, asprintf): Remove prototypes. Replace all calls to vasprintf and asprintf by gpgrt_vasprintf or gpgrt_asprintf. Also take care to use gpgrt_free on the returned value. * src/w32-util.c (_gpgme_get_gpgconf_path): Replace a gpgrt_asprintf by _gpgme_strconcat. (snprintf): New macro to use gpgrt_snprintf instead of the system's standard snprintf. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 1cad7b5..9903751 100644 --- a/configure.ac +++ b/configure.ac @@ -632,11 +632,6 @@ AC_MSG_NOTICE([checking for libraries]) AC_FUNC_FSEEKO -AC_REPLACE_FUNCS(vasprintf) -if test "$ac_cv_func_vasprintf" != yes; then - GNUPG_CHECK_VA_COPY -fi - # Try to find a thread-safe version of ttyname(). gnupg_REPLACE_TTYNAME_R if test "$ac_cv_func_ttyname_r" != yes; then diff --git a/src/debug.c b/src/debug.c index 1dd3723..e9bfc40 100644 --- a/src/debug.c +++ b/src/debug.c @@ -313,7 +313,7 @@ _gpgme_debug_begin (void **line, int level, const char *format, ...) } va_start (arg_ptr, format); - res = vasprintf ((char **) line, format, arg_ptr); + res = gpgrt_vasprintf ((char **) line, format, arg_ptr); va_end (arg_ptr); if (res < 0) *line = NULL; @@ -333,16 +333,16 @@ _gpgme_debug_add (void **line, const char *format, ...) return; va_start (arg_ptr, format); - res = vasprintf (&toadd, format, arg_ptr); + res = gpgrt_vasprintf (&toadd, format, arg_ptr); va_end (arg_ptr); if (res < 0) { - free (*line); + gpgrt_free (*line); *line = NULL; } - res = asprintf (&result, "%s%s", *(char **) line, toadd); - free (toadd); - free (*line); + res = gpgrt_asprintf (&result, "%s%s", *(char **) line, toadd); + gpgrt_free (toadd); + gpgrt_free (*line); if (res < 0) *line = NULL; else @@ -361,7 +361,7 @@ _gpgme_debug_end (void **line) /* The smallest possible level is 1, so force logging here by using that. */ _gpgme_debug (1, "%s", *line); - free (*line); + gpgrt_free (*line); *line = NULL; } diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 3e3b89f..78efb4c 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -265,7 +265,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_display) { - if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) + if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0) { err = gpg_error_from_syserror (); free (dft_display); @@ -275,7 +275,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -304,14 +304,14 @@ llass_new (void **engine, const char *file_name, const char *home_dir, ways, e.g., when /dev/pts is not accessible under chroot. */ if (!rc) { - if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { err = gpg_error_from_syserror (); goto leave; } err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; @@ -320,7 +320,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_ttytype) { - if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0) { err = gpg_error_from_syserror (); free (dft_ttytype); @@ -330,7 +330,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -408,13 +408,13 @@ llass_set_locale (void *engine, int category, const char *value) if (!value) return 0; - if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) err = gpg_error_from_syserror (); else { err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); } return err; } diff --git a/src/engine-g13.c b/src/engine-g13.c index 972c3a8..bb06d35 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -270,7 +270,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_display) { - if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) + if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0) { free (dft_display); err = gpg_error_from_syserror (); @@ -280,7 +280,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -304,14 +304,14 @@ g13_new (void **engine, const char *file_name, const char *home_dir, ways, e.g., when /dev/pts is not accessible under chroot. */ if (!rc) { - if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { err = gpg_error_from_syserror (); goto leave; } err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; @@ -320,7 +320,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_ttytype) { - if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0) { free (dft_ttytype); err = gpg_error_from_syserror (); @@ -330,7 +330,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -400,13 +400,13 @@ g13_set_locale (void *engine, int category, const char *value) if (!value) return 0; - if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) err = gpg_error_from_syserror (); else { err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); } return err; diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 75ba4bd..21ca02a 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -74,6 +74,10 @@ struct fd_data_map_s }; +/* NB.: R_LINE is allocated an gpgrt function and thus gpgrt_free + * shall be used to release it. This takes care of custom memory + * allocators and avoids problems on Windows with different runtimes + * used for libgpg-error/gpgrt and gpgme. */ typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline); struct engine_gpg @@ -1346,7 +1350,7 @@ read_colon_line (engine_gpg_t gpg) } while (linep && *linep); - free (line); + gpgrt_free (line); } else gpg->colon.fnc (gpg->colon.fnc_value, buffer); @@ -2513,7 +2517,7 @@ gpg_keylist_preprocess (char *line, char **r_line) n = strlen (field[1]); if (n > 16) { - if (asprintf (r_line, + if (gpgrt_asprintf (r_line, "pub:o%s:%s:%s:%s:%s:%s::::::::\n" "fpr:::::::::%s:", field[6], field[3], field[2], field[1] + n - 16, @@ -2522,7 +2526,7 @@ gpg_keylist_preprocess (char *line, char **r_line) } else { - if (asprintf (r_line, + if (gpgrt_asprintf (r_line, "pub:o%s:%s:%s:%s:%s:%s::::::::", field[6], field[3], field[2], field[1], field[4], field[5]) < 0) @@ -2580,7 +2584,7 @@ gpg_keylist_preprocess (char *line, char **r_line) } *dst = '\0'; - if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:", + if (gpgrt_asprintf (r_line, "uid:o%s::::%s:%s:::%s:", field[4], field[2], field[3], uid) < 0) return gpg_error_from_syserror (); } diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index d1be049..20bd88f 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -396,7 +396,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_display) { - if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) + if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0) { free (dft_display); err = gpg_error_from_syserror (); @@ -406,7 +406,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -430,14 +430,14 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, ways, e.g., when /dev/pts is not accessible under chroot. */ if (!rc) { - if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { err = gpg_error_from_syserror (); goto leave; } err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; @@ -446,7 +446,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_ttytype) { - if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0) { free (dft_ttytype); err = gpg_error_from_syserror (); @@ -456,7 +456,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -561,13 +561,13 @@ gpgsm_set_locale (void *engine, int category, const char *value) if (!value) return 0; - if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) err = gpg_error_from_syserror (); else { err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); } return err; @@ -1642,10 +1642,10 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only, gpgsm_assuan_simple_command (gpgsm, "GETINFO agent-check", NULL, NULL); /* Always send list-mode option because RESET does not reset it. */ - if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) + if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) return gpg_error_from_syserror (); err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL); - free (line); + gpgrt_free (line); if (err) return err; @@ -1726,10 +1726,10 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only, list_mode |= 2; /* Always send list-mode option because RESET does not reset it. */ - if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) + if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) return gpg_error_from_syserror (); err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL); - free (line); + gpgrt_free (line); if (err) return err; @@ -1860,10 +1860,11 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out, can reset any previously set value in case the default is requested. */ - if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0) + if (gpgrt_asprintf (&assuan_cmd, + "OPTION include-certs %i", include_certs) < 0) return gpg_error_from_syserror (); err = gpgsm_assuan_simple_command (gpgsm, assuan_cmd, NULL, NULL); - free (assuan_cmd); + gpgrt_free (assuan_cmd); if (err) return err; } @@ -2048,7 +2049,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags) if (!key || !key->subkeys || !key->subkeys->fpr) return gpg_error (GPG_ERR_INV_CERT_OBJ); - if (asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0) + if (gpgrt_asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0) return gpg_error_from_syserror (); gpgsm_clear_fd (gpgsm, OUTPUT_FD); @@ -2057,7 +2058,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags) gpgsm->inline_data = NULL; err = start (gpgsm, line); - free (line); + gpgrt_free (line); return err; } diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index ee7b1d2..ff5227e 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -316,7 +316,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_display) { - if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) + if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0) { err = gpg_error_from_syserror (); free (dft_display); @@ -326,7 +326,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -350,14 +350,14 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir, ways, e.g., when /dev/pts is not accessible under chroot. */ if (!rc) { - if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { err = gpg_error_from_syserror (); goto leave; } err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; @@ -366,7 +366,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir, goto leave; if (dft_ttytype) { - if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) + if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0) { err = gpg_error_from_syserror (); free (dft_ttytype); @@ -376,7 +376,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir, err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); if (err) goto leave; } @@ -441,13 +441,13 @@ uiserver_set_locale (void *engine, int category, const char *value) if (!value) return 0; - if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) err = gpg_error_from_syserror (); else { err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); - free (optstr); + gpgrt_free (optstr); } return err; @@ -982,7 +982,7 @@ _uiserver_decrypt (void *engine, int verify, else return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); - if (asprintf (&cmd, "DECRYPT%s%s%s", protocol, + if (gpgrt_asprintf (&cmd, "DECRYPT%s%s%s", protocol, verify ? "" : " --no-verify", export_session_key ? " --export-session-key" : "") < 0) return gpg_error_from_syserror (); @@ -992,20 +992,20 @@ _uiserver_decrypt (void *engine, int verify, map_data_enc (uiserver->input_cb.data)); if (err) { - free (cmd); + gpgrt_free (cmd); return gpg_error (GPG_ERR_GENERAL); /* FIXME */ } uiserver->output_cb.data = plain; err = uiserver_set_fd (uiserver, OUTPUT_FD, 0); if (err) { - free (cmd); + gpgrt_free (cmd); return gpg_error (GPG_ERR_GENERAL); /* FIXME */ } uiserver->inline_data = NULL; err = start (engine, cmd); - free (cmd); + gpgrt_free (cmd); return err; } @@ -1114,7 +1114,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, if (!recp || plain || ciph) return gpg_error (GPG_ERR_INV_VALUE); - if (asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol, + if (gpgrt_asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol, (flags & GPGME_ENCRYPT_EXPECT_SIGN) ? " --expect-sign" : "") < 0) return gpg_error_from_syserror (); @@ -1124,7 +1124,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, if (!plain || !ciph) return gpg_error (GPG_ERR_INV_VALUE); - if (asprintf (&cmd, "ENCRYPT%s", protocol) < 0) + if (gpgrt_asprintf (&cmd, "ENCRYPT%s", protocol) < 0) return gpg_error_from_syserror (); } @@ -1135,7 +1135,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, map_data_enc (uiserver->input_cb.data)); if (err) { - free (cmd); + gpgrt_free (cmd); return err; } } @@ -1147,7 +1147,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, : map_data_enc (uiserver->output_cb.data)); if (err) { - free (cmd); + gpgrt_free (cmd); return err; } } @@ -1159,13 +1159,13 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, err = set_recipients (uiserver, recp); if (err) { - free (cmd); + gpgrt_free (cmd); return err; } } err = start (uiserver, cmd); - free (cmd); + gpgrt_free (cmd); return err; } @@ -1195,7 +1195,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out, else return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); - if (asprintf (&cmd, "SIGN%s%s", protocol, + if (gpgrt_asprintf (&cmd, "SIGN%s%s", protocol, (mode == GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0) return gpg_error_from_syserror (); @@ -1220,10 +1220,10 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out, err = gpg_error (GPG_ERR_INV_VALUE); gpgme_key_unref (key); if (err) - { - free (cmd); - return err; - } + { + gpgrt_free (cmd); + return err; + } } uiserver->input_cb.data = in; @@ -1231,7 +1231,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out, map_data_enc (uiserver->input_cb.data)); if (err) { - free (cmd); + gpgrt_free (cmd); return err; } uiserver->output_cb.data = out; @@ -1239,13 +1239,13 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out, : map_data_enc (uiserver->output_cb.data)); if (err) { - free (cmd); + gpgrt_free (cmd); return err; } uiserver->inline_data = NULL; err = start (uiserver, cmd); - free (cmd); + gpgrt_free (cmd); return err; } @@ -1274,7 +1274,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, else return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); - if (asprintf (&cmd, "VERIFY%s", protocol) < 0) + if (gpgrt_asprintf (&cmd, "VERIFY%s", protocol) < 0) return gpg_error_from_syserror (); uiserver->input_cb.data = sig; @@ -1282,7 +1282,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, map_data_enc (uiserver->input_cb.data)); if (err) { - free (cmd); + gpgrt_free (cmd); return err; } if (plaintext) @@ -1302,7 +1302,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text, if (!err) err = start (uiserver, cmd); - free (cmd); + gpgrt_free (cmd); return err; } diff --git a/src/util.h b/src/util.h index a1be6e7..b27c583 100644 --- a/src/util.h +++ b/src/util.h @@ -95,11 +95,12 @@ _gpgme_stpcpy (char *a, const char *b) #define stpcpy(a,b) _gpgme_stpcpy ((a), (b)) #endif /*!HAVE_STPCPY*/ -#if !HAVE_VASPRINTF -#include -int vasprintf (char **result, const char *format, va_list args); -int asprintf (char **result, const char *format, ...); -#endif + +/* Due to a bug in mingw32's snprintf related to the 'l' modifier and + for increased portability we use our snprintf on all systems. */ +#undef snprintf +#define snprintf gpgrt_snprintf + #if REPLACE_TTYNAME_R int _gpgme_ttyname_r (int fd, char *buf, size_t buflen); diff --git a/src/vasprintf.c b/src/vasprintf.c deleted file mode 100644 index 4c40131..0000000 --- a/src/vasprintf.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Like vsprintf but provides a pointer to malloc'd storage, which must - be freed by the caller. - Copyright (C) 1994, 2002 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty 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. - -Libiberty 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 libiberty; see the file COPYING.LIB. 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 - - -#ifndef va_copy /* According to POSIX, va_copy is a macro. */ -#if defined (__GNUC__) && defined (__PPC__) \ - && (defined (_CALL_SYSV) || defined (_WIN32)) -#define va_copy(d, s) (*(d) = *(s)) -#elif defined (MUST_COPY_VA_BYVAL) -#define va_copy(d, s) ((d) = (s)) -#else -#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list)) -#endif -#endif - - -#ifdef TEST -int global_total_width; -#endif - -static int int_vasprintf (char **, const char *, va_list *); - -static int -int_vasprintf (result, format, args) - char **result; - const char *format; - va_list *args; -{ -#ifdef HAVE_W32CE_SYSTEM - /* No va_copy and the replacement above doesn't work. */ -#define MAX_STRLEN 256 - *result = malloc (MAX_STRLEN); - if (*result != NULL) - { - int res = _vsnprintf (*result, MAX_STRLEN, format, *args); - (*result)[MAX_STRLEN - 1] = '\0'; - return res; - } - else - return 0; -#else - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; - - va_copy (ap, *args); - - while (*p != '\0') - { - if (*p++ == '%') - { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char **) &p, 10); - if (*p == '.') - { - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char **) &p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s and floats. */ - total_width += 30; - switch (*p) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - /* Since an ieee double can have an exponent of 307, we'll - make the buffer wide enough to cover the gross case. */ - total_width += 307; - break; - case 's': - { - char *tmp = va_arg (ap, char *); - if (tmp) - total_width += strlen (tmp); - else /* in case the vsprintf does prints a text */ - total_width += 25; /* e.g. "(null pointer reference)" */ - } - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - p++; - } - } -#ifdef TEST - global_total_width = total_width; -#endif - *result = malloc (total_width); - if (*result != NULL) - return vsprintf (*result, format, *args); - else - return 0; -#endif -} - -int -vasprintf (result, format, args) - char **result; - const char *format; -#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__) - _BSD_VA_LIST_ args; -#else - va_list args; -#endif -{ - return int_vasprintf (result, format, &args); -} - - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (buf, fmt, ap); - va_end (ap); - return status; -} - - -#ifdef TEST -void -checkit (const char* format, ...) -{ - va_list args; - char *result; - - va_start (args, format); - vasprintf (&result, format, args); - if (strlen (result) < global_total_width) - printf ("PASS: "); - else - printf ("FAIL: "); - printf ("%d %s\n", global_total_width, result); -} - -int -main (void) -{ - checkit ("%d", 0x12345678); - checkit ("%200d", 5); - checkit ("%.300d", 6); - checkit ("%100.150d", 7); - checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ -777777777777777777333333333333366666666666622222222222777777777777733333"); - checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); -} -#endif /* TEST */ diff --git a/src/vfs-create.c b/src/vfs-create.c index a01d4da..a3bec19 100644 --- a/src/vfs-create.c +++ b/src/vfs-create.c @@ -138,7 +138,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[], return gpg_error (GPG_ERR_UNUSABLE_PUBKEY); } - if (asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0) + if (gpgrt_asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0) { err = gpg_error_from_syserror (); free (container_file_esc); @@ -147,7 +147,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[], err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL, op_err); - free (cmd); + gpgrt_free (cmd); if (err || *op_err) { free (container_file_esc); @@ -156,7 +156,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[], recp++; } - if (asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0) + if (gpgrt_asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0) { err = gpg_error_from_syserror (); free (container_file_esc); @@ -166,7 +166,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[], err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL, op_err); - free (cmd); + gpgrt_free (cmd); return err; } diff --git a/src/vfs-mount.c b/src/vfs-mount.c index 5d2f2a9..68a8efe 100644 --- a/src/vfs-mount.c +++ b/src/vfs-mount.c @@ -184,7 +184,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, if (err) return err; - if (asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0) + if (gpgrt_asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0) { err = gpg_error_from_syserror (); free (container_file_esc); @@ -194,7 +194,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL, op_err); - free (cmd); + gpgrt_free (cmd); if (err || *op_err) return err; @@ -206,7 +206,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, if (err) return err; - if (asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0) + if (gpgrt_asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0) { err = gpg_error_from_syserror (); free (mount_dir_esc); @@ -216,13 +216,13 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, } else { - if (asprintf (&cmd, "MOUNT") < 0) + if (gpgrt_asprintf (&cmd, "MOUNT") < 0) return gpg_error_from_syserror (); } err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL, _gpgme_vfs_mount_status_handler, ctx, op_err); - free (cmd); + gpgrt_free (cmd); return err; } diff --git a/src/w32-io.c b/src/w32-io.c index 6302ad9..eed8a00 100644 --- a/src/w32-io.c +++ b/src/w32-io.c @@ -1643,11 +1643,11 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags, "with your installation.\n" "Please report the problem to your " "distributor of GpgME.\n\n" - "Developers Note: The install dir can be " + "Developer's 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); + gpgrt_free (msg); gpg_err_set_errno (EIO); return TRACE_SYSRES (-1); } diff --git a/src/w32-util.c b/src/w32-util.c index ad36c9a..5b02c7e 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -577,9 +577,10 @@ _gpgme_get_gpgconf_path (void) "Install Directory"); if (tmp) { - if (gpgrt_asprintf (&dir, "%s\\bin", tmp) == -1) - return NULL; + dir = _gpgme_strconcat (tmp, "\\bin", NULL); free (tmp); + if (!dir) + return NULL; } } if (dir) commit 563420a88f8a4f561a2faea4d2b4a1c58b375fd8 Author: Werner Koch Date: Thu Feb 2 12:28:39 2017 +0100 core: Remove unused check for funopen/fopencookie. * configure.ac (funopen): Remove check. * src/funopen.c: Remove file. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 7109194..1cad7b5 100644 --- a/configure.ac +++ b/configure.ac @@ -698,21 +698,6 @@ fi # Other checks # -# Check for funopen -AC_CHECK_FUNCS(funopen) -if test $ac_cv_func_funopen != yes; then - # No funopen but we can implement that in terms of fopencookie. - AC_CHECK_FUNCS(fopencookie) - if test $ac_cv_func_fopencookie = yes; then - AC_REPLACE_FUNCS(funopen) - else - AC_MSG_WARN([ -*** -*** No implementation of fopencookie or funopen available -***]) - fi -fi - # Check for getgid etc AC_CHECK_FUNCS(getgid getegid) diff --git a/src/funopen.c b/src/funopen.c deleted file mode 100644 index b722020..0000000 --- a/src/funopen.c +++ /dev/null @@ -1,63 +0,0 @@ -/* funopen.c - Replacement for funopen. - Copyright (C) 2004 g10 Code 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 - - -/* Replacement for the *BSD function: - - FILE *funopen (void *cookie, - int (*readfn)(void *, char *, int), - int (*writefn)(void *, const char *, int), - fpos_t (*seekfn)(void *, fpos_t, int), - int (*closefn)(void *)); - - The functions to provide my either be NULL if not required or - similar to the unistd function with the exception of using the - cookie instead of the file descriptor. -*/ - - -#ifdef HAVE_FOPENCOOKIE -FILE * -_gpgme_funopen(void *cookie, - cookie_read_function_t *readfn, - cookie_write_function_t *writefn, - cookie_seek_function_t *seekfn, - cookie_close_function_t *closefn) -{ - cookie_io_functions_t io = { NULL }; - - io.read = readfn; - io.write = writefn; - io.seek = seekfn; - io.close = closefn; - - return fopencookie (cookie, - readfn ? ( writefn ? "rw" : "r" ) - : ( writefn ? "w" : ""), io); -} -#else -#error No known way to implement funopen. -#endif ----------------------------------------------------------------------- Summary of changes: configure.ac | 20 ----- src/debug.c | 14 ++-- src/engine-assuan.c | 16 ++-- src/engine-g13.c | 16 ++-- src/engine-gpg.c | 12 ++- src/engine-gpgsm.c | 33 ++++---- src/engine-uiserver.c | 58 +++++++------- src/funopen.c | 63 --------------- src/util.h | 11 +-- src/vasprintf.c | 206 -------------------------------------------------- src/vfs-create.c | 8 +- src/vfs-mount.c | 10 +-- src/w32-io.c | 4 +- src/w32-util.c | 5 +- 14 files changed, 97 insertions(+), 379 deletions(-) delete mode 100644 src/funopen.c delete mode 100644 src/vasprintf.c hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 13:31:24 2017 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 02 Feb 2017 13:31:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-52-ga08c781 Message-ID: This is an 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 a08c781739e7561093f32b732c4991f2bd817ec2 (commit) via 027b81b35fe36692005b8dba22d9eb2db05e8c80 (commit) via 74268180e5a3acc827f3a369f1fe5971f3bbe285 (commit) via 6f9d8a956b2ca0f5a0eb7acc656fc17af2f2de47 (commit) from 7440119e729d3fdedda8a9b44b70f8959beea8d7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a08c781739e7561093f32b732c4991f2bd817ec2 Author: Neal H. Walfield Date: Thu Feb 2 13:26:17 2017 +0100 gpg: If there is a TOFU conflict, elide the too few message warning. * g10/tofu.c (tofu_get_validity): If there was a conflict, don't also print out a warning about too few messages. Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index fc03c5a..41bdd5f 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -3694,6 +3694,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, int bindings = 0; int bindings_valid = 0; int need_warning = 0; + int had_conflict = 0; dbs = opendbs (ctrl); if (! dbs) @@ -3762,6 +3763,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, * key. */ log_assert (conflict_set); + had_conflict = 1; for (iter = conflict_set; iter; iter = iter->next) show_statistics (dbs, iter->d, email, TOFU_POLICY_ASK, NULL, 1, now); @@ -3794,7 +3796,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, xfree (email); } - if (need_warning) + if (need_warning && ! had_conflict) show_warning (fingerprint, user_id_list); die: commit 027b81b35fe36692005b8dba22d9eb2db05e8c80 Author: Neal H. Walfield Date: Thu Feb 2 13:24:57 2017 +0100 gpg: Only print out TOFU statistics for conflicts in interactive mode * g10/tofu.c (get_trust): Add arguments POLICYP and CONFLICT_SETP. If they are not NULL, return the policy and conflict set (if there is one), respectively. Update callers. If MAY_ASK is FALSE, don't print out the statistics. (tofu_register_encryption): If there is a conflict and we haven't yet printed the statistics about the conflicting bindings, do so now. (tofu_get_validity): Likewise. Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2914 diff --git a/g10/tofu.c b/g10/tofu.c index 9f5f406..fc03c5a 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2644,7 +2644,9 @@ get_policy (tofu_dbs_t dbs, PKT_public_key *pk, static enum tofu_policy get_trust (ctrl_t ctrl, PKT_public_key *pk, const char *fingerprint, const char *email, - const char *user_id, int may_ask, time_t now) + const char *user_id, int may_ask, + enum tofu_policy *policyp, strlist_t *conflict_setp, + time_t now) { tofu_dbs_t dbs = ctrl->tofu.dbs; int in_transaction = 0; @@ -2683,6 +2685,7 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, if (tdb_keyid_is_utk (kid)) { trust_level = TRUST_ULTIMATE; + policy = TOFU_POLICY_GOOD; goto out; } } @@ -2690,7 +2693,8 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, begin_transaction (ctrl, 0); in_transaction = 1; - policy = get_policy (dbs, pk, fingerprint, user_id, email, &conflict_set, now); + policy = get_policy (dbs, pk, fingerprint, user_id, email, + &conflict_set, now); if (policy == TOFU_POLICY_AUTO) { policy = opt.tofu_default_policy; @@ -2758,10 +2762,6 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, } else { - for (iter = conflict_set; iter; iter = iter->next) - show_statistics (dbs, iter->d, email, - TOFU_POLICY_ASK, NULL, 1, now); - trust_level = TRUST_UNDEFINED; } @@ -2807,7 +2807,13 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, if (in_transaction) end_transaction (ctrl, 0); - free_strlist (conflict_set); + if (policyp) + *policyp = policy; + + if (conflict_setp) + *conflict_setp = conflict_set; + else + free_strlist (conflict_set); return trust_level; } @@ -3326,7 +3332,8 @@ tofu_register_signature (ctrl_t ctrl, /* Make sure the binding exists and record any TOFU conflicts. */ - if (get_trust (ctrl, pk, fingerprint, email, user_id->d, 0, now) + if (get_trust (ctrl, pk, fingerprint, email, user_id->d, + 0, NULL, NULL, now) == _tofu_GET_TRUST_ERROR) { rc = gpg_error (GPG_ERR_GENERAL); @@ -3492,11 +3499,13 @@ tofu_register_encryption (ctrl_t ctrl, for (user_id = user_id_list; user_id; user_id = user_id->next) { char *email = email_from_user_id (user_id->d); + strlist_t conflict_set = NULL; + enum tofu_policy policy; /* Make sure the binding exists and that we recognize any conflicts. */ int tl = get_trust (ctrl, pk, fingerprint, email, user_id->d, - may_ask, now); + may_ask, &policy, &conflict_set, now); if (tl == _tofu_GET_TRUST_ERROR) { /* An error. */ @@ -3505,6 +3514,28 @@ tofu_register_encryption (ctrl_t ctrl, goto die; } + + /* If there is a conflict and MAY_ASK is true, we need to show + * the TOFU statistics for the current binding and the + * conflicting bindings. But, if we are not in batch mode, then + * they have already been printed (this is required to make sure + * the information is available to the caller before cpr_get is + * called). */ + if (policy == TOFU_POLICY_ASK && may_ask && opt.batch) + { + strlist_t iter; + + /* The conflict set should contain at least the current + * key. */ + log_assert (conflict_set); + + for (iter = conflict_set; iter; iter = iter->next) + show_statistics (dbs, iter->d, email, + TOFU_POLICY_ASK, NULL, 1, now); + } + + free_strlist (conflict_set); + rc = gpgsql_stepx (dbs->db, &dbs->s.register_encryption, NULL, NULL, &err, "insert into encryptions\n" @@ -3681,11 +3712,13 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, for (user_id = user_id_list; user_id; user_id = user_id->next, bindings ++) { char *email = email_from_user_id (user_id->d); + strlist_t conflict_set = NULL; + enum tofu_policy policy; /* Always call get_trust to make sure the binding is registered. */ int tl = get_trust (ctrl, pk, fingerprint, email, user_id->d, - may_ask, now); + may_ask, &policy, &conflict_set, now); if (tl == _tofu_GET_TRUST_ERROR) { /* An error. */ @@ -3708,13 +3741,35 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, if (may_ask && tl != TRUST_ULTIMATE && tl != TRUST_EXPIRED) { - enum tofu_policy policy = - get_policy (dbs, pk, fingerprint, user_id->d, email, NULL, now); + /* If policy is ask, then we already printed out the + * conflict information in ask_about_binding or will do so + * in a moment. */ + if (policy != TOFU_POLICY_ASK) + need_warning |= + show_statistics (dbs, fingerprint, email, policy, NULL, 0, now); + + /* If there is a conflict and MAY_ASK is true, we need to + * show the TOFU statistics for the current binding and the + * conflicting bindings. But, if we are not in batch mode, + * then they have already been printed (this is required to + * make sure the information is available to the caller + * before cpr_get is called). */ + if (policy == TOFU_POLICY_ASK && opt.batch) + { + strlist_t iter; - need_warning |= - show_statistics (dbs, fingerprint, email, policy, NULL, 0, now); + /* The conflict set should contain at least the current + * key. */ + log_assert (conflict_set); + + for (iter = conflict_set; iter; iter = iter->next) + show_statistics (dbs, iter->d, email, + TOFU_POLICY_ASK, NULL, 1, now); + } } + free_strlist (conflict_set); + if (tl == TRUST_NEVER) trust_level = TRUST_NEVER; else if (tl == TRUST_EXPIRED) commit 74268180e5a3acc827f3a369f1fe5971f3bbe285 Author: Neal H. Walfield Date: Thu Feb 2 11:00:51 2017 +0100 gpg: Add newline to output. * g10/tofu.c (ask_about_binding): Add newline to output. Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 149a185..9f5f406 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1969,7 +1969,7 @@ ask_about_binding (ctrl_t ctrl, else if (!response[0]) /* Default to unknown. Don't save it. */ { - tty_printf (_("Defaulting to unknown.")); + tty_printf (_("Defaulting to unknown.\n")); *policy = TOFU_POLICY_UNKNOWN; break; } commit 6f9d8a956b2ca0f5a0eb7acc656fc17af2f2de47 Author: Neal H. Walfield Date: Fri Jan 6 11:51:08 2017 +0100 gpg: Remove period at end of warning. * g10/tofu.c (tofu_register_encryption): Remove period at end of warning. Signed-off-by: Neal H. Walfield diff --git a/g10/tofu.c b/g10/tofu.c index 8d535fa..149a185 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -3480,7 +3480,7 @@ tofu_register_encryption (ctrl_t ctrl, if (! user_id_list) log_info (_("WARNING: Encrypting to %s, which has no " - "non-revoked user ids.\n"), + "non-revoked user ids\n"), keystr (pk->keyid)); } ----------------------------------------------------------------------- Summary of changes: g10/tofu.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 14:24:58 2017 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 02 Feb 2017 14:24:58 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-53-g769272b Message-ID: This is an 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 769272ba87f282a69e8d5f9bb27c86e6bec4496b (commit) from a08c781739e7561093f32b732c4991f2bd817ec2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 769272ba87f282a69e8d5f9bb27c86e6bec4496b Author: Neal H. Walfield Date: Thu Feb 2 14:24:38 2017 +0100 gpg: Ensure TOFU bindings associated with UTKs are registered as usual * g10/tofu.c (get_trust): Call get_policy before short-circuiting the policy lookup for ultimately trusted keys to make sure the binding is added to the bindings table, if necessary. Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2929 diff --git a/g10/tofu.c b/g10/tofu.c index 41bdd5f..85347bb 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2306,7 +2306,11 @@ build_conflict_set (tofu_dbs_t dbs, /* Return the effective policy for the binding * (email has already been normalized) and any conflict information in * *CONFLICT_SETP, if CONFLICT_SETP is not NULL. Returns - * _tofu_GET_POLICY_ERROR if an error occurs. */ + * _tofu_GET_POLICY_ERROR if an error occurs. + * + * This function registers the binding in the bindings table if it has + * not yet been registered. + */ static enum tofu_policy get_policy (tofu_dbs_t dbs, PKT_public_key *pk, const char *fingerprint, const char *user_id, const char *email, @@ -2677,6 +2681,14 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, && _tofu_GET_TRUST_ERROR != TRUST_FULLY && _tofu_GET_TRUST_ERROR != TRUST_ULTIMATE); + begin_transaction (ctrl, 0); + in_transaction = 1; + + /* We need to call get_policy even if the key is ultimately trusted + * to make sure the binding has been registered. */ + policy = get_policy (dbs, pk, fingerprint, user_id, email, + &conflict_set, now); + /* If the key is ultimately trusted, there is nothing to do. */ { u32 kid[2]; @@ -2690,11 +2702,6 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, } } - begin_transaction (ctrl, 0); - in_transaction = 1; - - policy = get_policy (dbs, pk, fingerprint, user_id, email, - &conflict_set, now); if (policy == TOFU_POLICY_AUTO) { policy = opt.tofu_default_policy; ----------------------------------------------------------------------- Summary of changes: g10/tofu.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 14:47:38 2017 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 02 Feb 2017 14:47:38 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-55-g64be8e1 Message-ID: This is an 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 64be8e1e8607944687f3ae45ec64aa30bf4fdf6f (commit) via e596b21f4b78dd27489e677699cc4ba648051b3f (commit) from 769272ba87f282a69e8d5f9bb27c86e6bec4496b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 64be8e1e8607944687f3ae45ec64aa30bf4fdf6f Author: Neal H. Walfield Date: Thu Feb 2 14:47:34 2017 +0100 tests: Improve description of test. * tests/openpgp/issue2929.scm: Improve description of test. Signed-off-by: Neal H. Walfield diff --git a/tests/openpgp/issue2929.scm b/tests/openpgp/issue2929.scm index 44521bb..121103b 100644 --- a/tests/openpgp/issue2929.scm +++ b/tests/openpgp/issue2929.scm @@ -26,7 +26,7 @@ ;; Redefine GPG without --always-trust and TOFU trust model. (define gpg `(,(tool 'gpg) --no-permission-warning --trust-model=tofu)) -(info "Checking key creation with TOFU trust model (issue2929).") +(info "Checking TOFU trust model with ultimately trusted keys (issue2929).") (call-check `(, at gpg --quick-generate-key frob at example.org)) (call-check `(, at gpg --sign gpg.conf)) (call-check `(, at gpg --verify gpg.conf.gpg)) commit e596b21f4b78dd27489e677699cc4ba648051b3f Author: Neal H. Walfield Date: Thu Feb 2 14:43:15 2017 +0100 Revert "Revert "tests: Add test demonstrating issue2929."" This reverts commit 59048b0f1aa77313573a1004cd3a9f02692a7521. diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index d1dd449..5cab3d5 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -96,7 +96,8 @@ XTESTS = \ issue2015.scm \ issue2346.scm \ issue2417.scm \ - issue2419.scm + issue2419.scm \ + issue2929.scm # XXX: Currently, one cannot override automake's 'check' target. As a # workaround, we avoid defining 'TESTS', thus automake will not emit diff --git a/tests/openpgp/issue2929.scm b/tests/openpgp/issue2929.scm new file mode 100644 index 0000000..44521bb --- /dev/null +++ b/tests/openpgp/issue2929.scm @@ -0,0 +1,32 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2017 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see . + +(load (with-path "defs.scm")) +(setup-environment) + +(catch (skip "Tofu not supported") + (call-check `(, at gpg --trust-model=tofu --list-config))) + +;; Redefine GPG without --always-trust and TOFU trust model. +(define gpg `(,(tool 'gpg) --no-permission-warning --trust-model=tofu)) + +(info "Checking key creation with TOFU trust model (issue2929).") +(call-check `(, at gpg --quick-generate-key frob at example.org)) +(call-check `(, at gpg --sign gpg.conf)) +(call-check `(, at gpg --verify gpg.conf.gpg)) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/Makefile.am | 3 ++- tests/openpgp/{issue2015.scm => issue2929.scm} | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) copy tests/openpgp/{issue2015.scm => issue2929.scm} (60%) mode change 100755 => 100644 hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 15:51:39 2017 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 02 Feb 2017 15:51:39 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-56-g407f5f9 Message-ID: This is an 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 407f5f9baea5591f148974240a87dfb43e5efef3 (commit) from 64be8e1e8607944687f3ae45ec64aa30bf4fdf6f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 407f5f9baea5591f148974240a87dfb43e5efef3 Author: Neal H. Walfield Date: Thu Feb 2 15:48:45 2017 +0100 gpg: Don't assume that strtoul interprets "" as 0. * g10/tofu.c (show_statistics): If there are not records, return 0 instead of NULL. -- Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2853 According to SUSv3: If the subject sequence is empty or does not have the expected form, no conversion is performed ... If no conversion could be performed, 0 is returned and errno may be set to [EINVAL]. http://pubs.opengroup.org/onlinepubs/007908799/xsh/strtol.html It appears that MacOS X sets errno to EINVAL, but glibc doesn't. Hence, we map NULL to 0 explicitly. diff --git a/g10/tofu.c b/g10/tofu.c index 85347bb..449e921 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2983,7 +2983,8 @@ show_statistics (tofu_dbs_t dbs, /* Get the signature stats. */ rc = gpgsql_exec_printf (dbs->db, strings_collect_cb, &strlist, &err, - "select count (*), min (signatures.time), max (signatures.time)\n" + "select count (*), coalesce (min (signatures.time), 0),\n" + " coalesce (max (signatures.time), 0)\n" " from signatures\n" " left join bindings on signatures.binding = bindings.oid\n" " where fingerprint = %Q and email = %Q;", @@ -3036,7 +3037,8 @@ show_statistics (tofu_dbs_t dbs, /* Get the encryption stats. */ rc = gpgsql_exec_printf (dbs->db, strings_collect_cb, &strlist, &err, - "select count (*), min (encryptions.time), max (encryptions.time)\n" + "select count (*), coalesce (min (encryptions.time), 0),\n" + " coalesce (max (encryptions.time), 0)\n" " from encryptions\n" " left join bindings on encryptions.binding = bindings.oid\n" " where fingerprint = %Q and email = %Q;", ----------------------------------------------------------------------- Summary of changes: g10/tofu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 2 17:17:22 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 02 Feb 2017 17:17:22 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-52-g43160a3 Message-ID: This is an 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 43160a39f27f6c3507447620666c85af00b3499c (commit) via 195c73589232160f45d00f4901c9bb2b0162f0e5 (commit) from 15050ce5fce4ed815503db7c029abb38d08970d6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 43160a39f27f6c3507447620666c85af00b3499c Author: Andre Heinecke Date: Thu Feb 2 17:16:27 2017 +0100 qt: Add test for tofu conflict * lang/qt/tests/t-tofuinfo.cpp (TofuInfoTest::testTofuConflict): New. diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index d88861c..e16b1fd 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -35,12 +35,16 @@ #include #include #include +#include + #include "protocol.h" #include "tofuinfo.h" #include "tofupolicyjob.h" #include "verifyopaquejob.h" #include "verificationresult.h" #include "signingresult.h" +#include "importjob.h" +#include "importresult.h" #include "keylistjob.h" #include "keylistresult.h" #include "qgpgmesignjob.h" @@ -61,10 +65,57 @@ static const char testMsg1[] = "=Crq6\n" "-----END PGP MESSAGE-----\n"; +static const char conflictKey1[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +"\n" +"mDMEWG+w/hYJKwYBBAHaRw8BAQdAiq1oStvDYg8ZfFs5DgisYJo8dJxD+C/AA21O\n" +"K/aif0O0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBHoJBLaV\n" +"DamYAgoa1L5BwMOl/x88BQJYb7D+AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n" +"Ah4BAheAAAoJEL5BwMOl/x88GvwA/0SxkbLyAcshGm2PRrPsFQsSVAfwaSYFVmS2\n" +"cMVIw1PfAQDclRH1Z4MpufK07ju4qI33o4s0UFpVRBuSxt7A4P2ZD7g4BFhvsP4S\n" +"CisGAQQBl1UBBQEBB0AmVrgaDNJ7K2BSalsRo2EkRJjHGqnp5bBB0tapnF81CQMB\n" +"CAeIeAQYFggAIBYhBHoJBLaVDamYAgoa1L5BwMOl/x88BQJYb7D+AhsMAAoJEL5B\n" +"wMOl/x88OR0BAMq4/vmJUORRTmzjHcv/DDrQB030DSq666rlckGIKTShAPoDXM9N\n" +"0gZK+YzvrinSKZXHmn0aSwmC1/hyPybJPEljBw==\n" +"=p2Oj\n" +"-----END PGP PUBLIC KEY BLOCK-----\n"; + +static const char conflictKey2[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +"\n" +"mDMEWG+xShYJKwYBBAHaRw8BAQdA567gPEPJRpqKnZjlFJMRNUqruRviYMyygfF6\n" +"6Ok+ygu0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBJ5kRh7E\n" +"I98w8kgUcmkAfYFvqqHsBQJYb7FKAhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n" +"Ah4BAheAAAoJEGkAfYFvqqHsYR0BAOz8JjYB4VvGkt6noLS3F5TLfsedGwQkBCw5\n" +"znw/vGZsAQD9DSX+ekwdrN56mNO8ISt5uVS7B1ZQtouNBF+nzcwbDbg4BFhvsUoS\n" +"CisGAQQBl1UBBQEBB0BFupW8+Xc1ikab8TJqANjQhvFVh6uLsgcK4g9lZgbGXAMB\n" +"CAeIeAQYFggAIBYhBJ5kRh7EI98w8kgUcmkAfYFvqqHsBQJYb7FKAhsMAAoJEGkA\n" +"fYFvqqHs15ABALdN3uiV/07cJ3RkNb3WPcijGsto+lECDS11dKEwTMFeAQDx+V36\n" +"ocbYC/xEuwi3w45oNqGieazzcD/GBbt8OBk3BA==\n" +"=45IR\n" +"-----END PGP PUBLIC KEY BLOCK-----\n"; + +static const char conflictMsg1[] = "-----BEGIN PGP MESSAGE-----\n" +"\n" +"owGbwMvMwCG2z/HA4aX/5W0YT3MlMUTkb2xPSizi6ihlYRDjYJAVU2Sp4mTZNpV3\n" +"5QwmLqkrMLWsTCCFDFycAjCR1vcMf4U0Qrs6qzqfHJ9puGOFduLN2nVmhsumxjBE\n" +"mdw4lr1ehIWR4QdLuNBpe86PGx1PtNXfVAzm/hu+vfjCp5BVNjPTM9L0eAA=\n" +"=MfBD\n" +"-----END PGP MESSAGE-----\n"; + +static const char conflictMsg2[] = "-----BEGIN PGP MESSAGE-----\n" +"\n" +"owGbwMvMwCGWyVDbmL9q4RvG01xJDBH5GyvS8vO5OkpZGMQ4GGTFFFnmpbjJHVG+\n" +"b/DJQ6QIppaVCaSQgYtTACaySZHhr/SOPrdFJ89KrcwKY5i1XnflXYf2PK76SafK\n" +"tkxXuXzvJAvDX4kCybuqFk3HXCexz2+IrnZ+5X5EqOnuo3ens2cte+uzlhMA\n" +"=BIAi\n" +"-----END PGP MESSAGE-----\n"; + class TofuInfoTest: public QGpgMETest { Q_OBJECT +Q_SIGNALS: + void asyncDone(); +private: bool testSupported() { return !(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.16"); @@ -349,6 +400,88 @@ private Q_SLOTS: delete job; } + void testTofuConflict() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.19") { + return; + } + + // Import key 1 + auto importjob = openpgp()->importJob(); + connect(importjob, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + QVERIFY(!result.error()); + QVERIFY(!result.imports().empty()); + QVERIFY(result.numImported()); + Q_EMIT asyncDone(); + }); + importjob->start(QByteArray(conflictKey1)); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait()); + + // Verify Message 1 + const QByteArray signedData(conflictMsg1); + auto verifyJob = openpgp()->verifyOpaqueJob(true); + QByteArray verified; + auto result = verifyJob->exec(signedData, verified); + delete verifyJob; + + QVERIFY(!result.isNull()); + QVERIFY(!result.error()); + + QVERIFY(result.numSignatures() == 1); + auto sig = result.signatures()[0]; + QVERIFY(sig.validity() == Signature::Marginal); + + auto stats = sig.key().userID(0).tofuInfo(); + QVERIFY(!stats.isNull()); + QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint())); + QVERIFY(stats.signFirst() == stats.signLast()); + QVERIFY(stats.signCount() == 1); + QVERIFY(stats.policy() == TofuInfo::PolicyAuto); + QVERIFY(stats.validity() == TofuInfo::LittleHistory); + + // Import key 2 + importjob = openpgp()->importJob(); + connect(importjob, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + QVERIFY(!result.error()); + QVERIFY(!result.imports().empty()); + QVERIFY(result.numImported()); + Q_EMIT asyncDone(); + }); + importjob->start(QByteArray(conflictKey2)); + QSignalSpy spy2 (this, SIGNAL(asyncDone())); + QVERIFY(spy2.wait()); + + // Verify Message 2 + const QByteArray signedData2(conflictMsg2); + QByteArray verified2; + verifyJob = openpgp()->verifyOpaqueJob(true); + result = verifyJob->exec(signedData2, verified2); + delete verifyJob; + + QVERIFY(!result.isNull()); + QVERIFY(!result.error()); + + QVERIFY(result.numSignatures() == 1); + sig = result.signatures()[0]; + QVERIFY(sig.validity() == Signature::Unknown); + // TODO activate when implemented + // QVERIFY(sig.summary() == Signature::TofuConflict); + + stats = sig.key().userID(0).tofuInfo(); + QVERIFY(!stats.isNull()); + QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint())); + QVERIFY(stats.signFirst() == stats.signLast()); + QVERIFY(stats.signCount() == 1); + QVERIFY(stats.policy() == TofuInfo::PolicyAsk); + QVERIFY(stats.validity() == TofuInfo::Conflict); + } + + void initTestCase() { QGpgMETest::initTestCase(); commit 195c73589232160f45d00f4901c9bb2b0162f0e5 Author: Andre Heinecke Date: Thu Feb 2 14:02:31 2017 +0100 core: Handle multiple TOFU_USER lines in verify * src/verify.c (op_data_t): Add conflict_user_seen. (parse_tofu_user): Return ERR_DUP_VALUE for mutltiple TOFU_USERS. (_gpgme_verify_status_handler): Handle ERR_DUP_VALUE from parse_tofu_user to ignore the next TOFU_STATS. -- This fixes TOFU Conflict verification with GnuPG-2.1.17 and 2.1.18 GnuPG-Bug-Id: 2914 diff --git a/src/verify.c b/src/verify.c index faa8deb..398cec5 100644 --- a/src/verify.c +++ b/src/verify.c @@ -46,6 +46,7 @@ typedef struct int did_prepare_new_sig; int only_newsig_seen; int plaintext_seen; + int conflict_user_seen; } *op_data_t; @@ -680,6 +681,14 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol) goto leave; } + if (sig->key && sig->key->fpr && strcmp (sig->key->fpr, fpr)) + { + /* GnuPG since 2.1.17 emits multiple TOFU_USER lines with + different fingerprints in case of conflicts for a signature. */ + err = GPG_ERR_DUP_VALUE; + goto leave; + } + args = tail; tail = strchr (args, ' '); if (tail == args) @@ -708,12 +717,6 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol) 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; - } err = _gpgme_key_append_name (sig->key, address, 0); if (err) @@ -930,6 +933,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) calc_sig_summary (sig); err = prepare_new_sig (opd); opd->only_newsig_seen = 1; + opd->conflict_user_seen = 0; return err; case GPGME_STATUS_GOODSIG: @@ -995,16 +999,35 @@ _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, ctx->protocol) - /* */ : trace_gpg_error (GPG_ERR_INV_ENGINE); + if (!sig) + return trace_gpg_error (GPG_ERR_INV_ENGINE); + err = parse_tofu_user (sig, args, ctx->protocol); + /* gpg emits TOFU User lines for each conflicting key. + GPGME does not expose this to have a clean API and + a GPGME user can do a keylisting with the address + normalisation. + So when a duplicated TOFU_USER line is encountered + we ignore the conflicting tofu stats emited afterwards. + */ + if (err == GPG_ERR_DUP_VALUE) + { + opd->conflict_user_seen = 1; + break; + } + opd->conflict_user_seen = 0; + return trace_gpg_error (err); case GPGME_STATUS_TOFU_STATS: opd->only_newsig_seen = 0; + if (opd->conflict_user_seen) + break; return sig ? parse_tofu_stats (sig, args) /* */ : trace_gpg_error (GPG_ERR_INV_ENGINE); case GPGME_STATUS_TOFU_STATS_LONG: opd->only_newsig_seen = 0; + if (opd->conflict_user_seen) + break; return sig ? parse_tofu_stats_long (sig, args, ctx->raw_description) /* */ : trace_gpg_error (GPG_ERR_INV_ENGINE); ----------------------------------------------------------------------- Summary of changes: lang/qt/tests/t-tofuinfo.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++ src/verify.c | 39 ++++++++++--- 2 files changed, 164 insertions(+), 8 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 12:00:03 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 12:00:03 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.0.0-10-gce745a2 Message-ID: This is an 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 ce745a292192b01203ba5f557205a6f000bff953 (commit) via cd45d74d07512f8ec8d2b3306a1804457dd12964 (commit) via b0e0bdeac5d40ca645afc9017778b39a26303523 (commit) from 8e3aa3204e74e8d7a7538e0d0f04e555f140131b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ce745a292192b01203ba5f557205a6f000bff953 Author: Werner Koch Date: Fri Feb 3 11:53:25 2017 +0100 curses: Do not return OK on error. * pinentry/pinentry.c (cmd_confirm): Take care not to return OK if the RESULT is negative. * pinentry/pinentry-curses.c (dialog_create): Amend error reporting by setting specific_err_loc. (dialog_run): Use new var confirm_mode for clearness. In confirm mode return Cancel instead of error. This is how the gtk Pinentry does it. -- A common error case is that a tty is not available and thus the fopen fails. In this case it is plainly wrong to return OK, we would better return CANCEL. Even better the specicic_err thing is now used to return a proper error code. For example: $ pinentry-curses --ttyname=/dev/no/such/tty OK Pleased to meet you getinfo ttyinfo D /dev/no/such/tty - - OK confirm S ERROR curses.open_tty_for_read 83918929 ERR 83918929 No such file or directory The curses pinentry is also used as fallback from gtk. Thus in this case we now also get a error message back: $ pinentry-gtk-2 --display=/dev/null --ttyname=/dev/no/such/tty OK Pleased to meet you getinfo flavor D gtk2:curses OK getinfo ttyinfo D /dev/no/such/tty - /dev/null OK confirm S ERROR gtk2.open_tty_for_read 83918929 ERR 83918929 No such file or directory Returning an error instead of OK also fixes this bug: A background task is asking to insert a certain smartcard and asks via pinentry for it. Now w/o a valid tty the old code return OK and gpg-agent started new pinentries (which don't show up) over and over until the correct card was inserted. Signed-off-by: Werner Koch diff --git a/pinentry/pinentry-curses.c b/pinentry/pinentry-curses.c index a6dbb69..6fa4c72 100644 --- a/pinentry/pinentry-curses.c +++ b/pinentry/pinentry-curses.c @@ -254,6 +254,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) { \ err = 1; \ pinentry->specific_err = gpg_error (GPG_ERR_LOCALE_PROBLEM); \ + pinentry->specific_err_loc = "dialog_create_copy"; \ goto out; \ } \ } \ @@ -286,6 +287,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) { \ err = 1; \ pinentry->specific_err = gpg_error_from_syserror (); \ + pinentry->specific_err_loc = "dialog_create_mk_button"; \ goto out; \ } \ \ @@ -311,6 +313,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) { \ err = 1; \ pinentry->specific_err = gpg_error (GPG_ERR_LOCALE_PROBLEM); \ + pinentry->specific_err_loc = "dialog_create_utf8conv"; \ goto out; \ } \ } \ @@ -378,6 +381,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) err = 1; pinentry->specific_err = gpg_error (size_y < 0? GPG_ERR_MISSING_ENVVAR /* */ : GPG_ERR_WINDOW_TOO_SMALL); + pinentry->specific_err_loc = "dialog_create"; goto out; } @@ -434,6 +438,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) err = 1; pinentry->specific_err = gpg_error (size_x < 0? GPG_ERR_MISSING_ENVVAR /* */ : GPG_ERR_WINDOW_TOO_SMALL); + pinentry->specific_err_loc = "dialog_create"; goto out; } @@ -814,6 +819,7 @@ dialog_input (dialog_t diag, int alt, int chr) static int dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) { + int confirm_mode = !pinentry->pin; struct dialog diag; FILE *ttyfi = NULL; FILE *ttyfo = NULL; @@ -824,6 +830,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) #ifndef HAVE_DOSISH_SYSTEM int no_input = 1; #endif + #ifdef HAVE_NCURSESW char *old_ctype = NULL; @@ -843,7 +850,8 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) if (!ttyfi) { pinentry->specific_err = gpg_error_from_syserror (); - return -1; + pinentry->specific_err_loc = "open_tty_for_read"; + return confirm_mode? 0 : -1; } ttyfo = fopen (tty_name, "w"); if (!ttyfo) @@ -852,7 +860,8 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) fclose (ttyfi); errno = err; pinentry->specific_err = gpg_error_from_syserror (); - return -1; + pinentry->specific_err_loc = "open_tty_for_write"; + return confirm_mode? 0 : -1; } screen = newterm (tty_type, ttyfo, ttyfi); set_term (screen); @@ -865,7 +874,8 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) { errno = ENOTTY; pinentry->specific_err = gpg_error_from_syserror (); - return -1; + pinentry->specific_err_loc = "isatty"; + return confirm_mode? 0 : -1; } init_screen = 1; initscr (); @@ -925,8 +935,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) fclose (ttyfo); return -2; } - dialog_switch_pos (&diag, - diag.pinentry->pin ? DIALOG_POS_PIN : DIALOG_POS_OK); + dialog_switch_pos (&diag, confirm_mode? DIALOG_POS_OK : DIALOG_POS_PIN); #ifndef HAVE_DOSISH_SYSTEM wtimeout (stdscr, 70); @@ -966,7 +975,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) switch (diag.pos) { case DIALOG_POS_OK: - if (diag.pinentry->pin) + if (!confirm_mode) dialog_switch_pos (&diag, DIALOG_POS_PIN); break; case DIALOG_POS_NOTOK: @@ -1020,10 +1029,10 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_CANCEL: - if (diag.pinentry->pin) - dialog_switch_pos (&diag, DIALOG_POS_PIN); - else + if (confirm_mode) dialog_switch_pos (&diag, DIALOG_POS_OK); + else + dialog_switch_pos (&diag, DIALOG_POS_PIN); break; default: break; @@ -1064,10 +1073,12 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) } while (!done); - if (diag.pinentry->pin) - /* NUL terminate the passphrase. dialog_run makes sure there is - enough space for the terminating NUL byte. */ - diag.pinentry->pin[diag.pin_len] = 0; + if (!confirm_mode) + { + /* NUL terminate the passphrase. dialog_run makes sure there is + enough space for the terminating NUL byte. */ + diag.pinentry->pin[diag.pin_len] = 0; + } set_cursor_state (1); endwin (); @@ -1092,7 +1103,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) if (diag.notok) free (diag.notok); - if (pinentry->pin) + if (!confirm_mode) { pinentry->locale_err = 1; pin_utf8 = pinentry_local_to_utf8 (pinentry->lc_ctype, pinentry->pin, 1); @@ -1109,10 +1120,11 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) if (done == -2) pinentry->canceled = 1; - if (diag.pinentry->pin) - return done < 0 ? -1 : diag.pin_len; - else + /* In confirm mode return cancel instead of error. */ + if (confirm_mode) return done < 0 ? 0 : 1; + + return done < 0 ? -1 : diag.pin_len; } diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index b38110d..afda9ef 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -1450,8 +1450,8 @@ cmd_confirm (assuan_context_t ctx, char *line) if (pinentry.close_button) assuan_write_status (ctx, "BUTTON_INFO", "close"); - if (result) - return 0; + if (result > 0) + return 0; /* OK */ if (pinentry.specific_err) { @@ -1463,7 +1463,7 @@ cmd_confirm (assuan_context_t ctx, char *line) return gpg_error (GPG_ERR_LOCALE_PROBLEM); if (pinentry.one_button) - return 0; + return 0; /* OK */ if (pinentry.canceled) return gpg_error (GPG_ERR_CANCELED); commit cd45d74d07512f8ec8d2b3306a1804457dd12964 Author: Werner Koch Date: Fri Feb 3 11:39:13 2017 +0100 core: New command getinfo/ttyinfo * pinentry/pinentry.c (remember_display): New var. (pinentry_have_display): Peek at --display. (pinentry_parse_opts): Set pinentry.display. (cmd_getinfo): Add sub-command "ttyinfo". Signed-off-by: Werner Koch diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index a198fb3..b38110d 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -70,6 +70,14 @@ struct pinentry pinentry; static const char *flavor_flag; +/* Because gtk_init removes the --display arg from the command lines + * and our command line parser is called after gtk_init (so that it + * does not see gtk specific options) we don't have a way to get hold + * of the --display option. Our solution is to remember --disable in + * the call to pinentry_have_display and set it then in our + * parser. */ +static char *remember_display; + static void pinentry_reset (int use_defaults) @@ -570,17 +578,54 @@ pinentry_init (const char *pgmname) int pinentry_have_display (int argc, char **argv) { + int found = 0; + + for (; argc; argc--, argv++) + { + if (!strcmp (*argv, "--display")) + { + if (argv[1] && !remember_display) + { + remember_display = strdup (argv[1]); + if (!remember_display) + { #ifndef HAVE_W32CE_SYSTEM - const char *s; + fprintf (stderr, "%s: %s\n", this_pgmname, strerror (errno)); +#endif + exit (EXIT_FAILURE); + } + } + found = 1; + break; + } + else if (!strncmp (*argv, "--display=", 10)) + { + if (!remember_display) + { + remember_display = strdup (*argv+10); + if (!remember_display) + { +#ifndef HAVE_W32CE_SYSTEM + fprintf (stderr, "%s: %s\n", this_pgmname, strerror (errno)); +#endif + exit (EXIT_FAILURE); + } + } + found = 1; + break; + } + } - s = getenv ("DISPLAY"); - if (s && *s) - return 1; +#ifndef HAVE_W32CE_SYSTEM + { + const char *s; + s = getenv ("DISPLAY"); + if (s && *s) + found = 1; + } #endif - for (; argc; argc--, argv++) - if (!strcmp (*argv, "--display") || !strncmp (*argv, "--display=", 10)) - return 1; - return 0; + + return found; } @@ -795,6 +840,12 @@ pinentry_parse_opts (int argc, char *argv[]) break; } } + + if (!pinentry.display && remember_display) + { + pinentry.display = remember_display; + remember_display = NULL; + } } @@ -1436,6 +1487,7 @@ cmd_message (assuan_context_t ctx, char *line) version - Return the version of the program. pid - Return the process id of the server. flavor - Return information about the used pinentry flavor + ttyinfo - Return DISPLAY and ttyinfo. */ static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) @@ -1470,6 +1522,15 @@ cmd_getinfo (assuan_context_t ctx, char *line) buffer[sizeof buffer -1] = 0; rc = assuan_send_data (ctx, buffer, strlen (buffer)); } + else if (!strcmp (line, "ttyinfo")) + { + snprintf (buffer, sizeof buffer, "%s %s %s", + pinentry.ttyname? pinentry.ttyname : "-", + pinentry.ttytype? pinentry.ttytype : "-", + pinentry.display? pinentry.display : "-" ); + buffer[sizeof buffer -1] = 0; + rc = assuan_send_data (ctx, buffer, strlen (buffer)); + } else rc = gpg_error (GPG_ERR_ASS_PARAMETER); return rc; commit b0e0bdeac5d40ca645afc9017778b39a26303523 Author: Werner Koch Date: Wed Jan 11 18:40:17 2017 +0100 gtk2: Fix a problem with fvwm * gtk+-2/pinentry-gtk-2.c (grab_pointer): Take care of GDK_GRAB_ALREADY_GRABBED. -- Debian-bug-id: 850708 Co-authored-by: Vincent Lefevre Signed-off-by: Werner Koch diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 473c4aa..e37601f 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -203,7 +203,12 @@ grab_pointer (GtkWidget *win, GdkEvent *event, gpointer data) (void)data; /* Change the cursor for the duration of the grab to indicate that - something is going on. */ + * something is going on. The fvwm window manager grabs the pointer + * for a short time and thus we may end up with the already grabbed + * error code. Actually this error code should be used to detect a + * malicious grabbing application but with fvwm this renders + * Pinentry only unusable. Thus we try again several times also for + * that error code. See Debian bug 850708 for details. */ /* 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), @@ -215,7 +220,8 @@ grab_pointer (GtkWidget *win, GdkEvent *event, gpointer data) NULL /* confine to */, cursor, gdk_event_get_time (event)); - while (tries++ < max_tries && err == GDK_GRAB_NOT_VIEWABLE); + while (tries++ < max_tries && (err == GDK_GRAB_NOT_VIEWABLE + || err == GDK_GRAB_ALREADY_GRABBED)); if (err) { ----------------------------------------------------------------------- Summary of changes: gtk+-2/pinentry-gtk-2.c | 10 ++++-- pinentry/pinentry-curses.c | 46 +++++++++++++++---------- pinentry/pinentry.c | 83 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 109 insertions(+), 30 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 12:08:55 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 12:08:55 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-57-g7052a0d Message-ID: This is an 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 7052a0d77cf8f3a445b252a809d29be445788625 (commit) from 407f5f9baea5591f148974240a87dfb43e5efef3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7052a0d77cf8f3a445b252a809d29be445788625 Author: Werner Koch Date: Fri Feb 3 12:04:52 2017 +0100 gpg: More diagnostics for a launched pinentry. * agent/call-pinentry.c (start_pinentry): Call getinfo/ttyinfo. * g10/server.c (gpg_proxy_pinentry_notify): Simplify the output so that we do not change the code when adding new fields to PINENTRY_LAUNCHED. -- This patch changes the --verbose output of gpg to show for example gpg: pinentry launched (5228 gtk2 1.0.1-beta10 \ /dev/pts/4 xterm localhost:10.0) the used tty, its type, and the value of DISPLAY in addiion to the pid, flavor, and version. Signed-off-by: Werner Koch diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index fa00bf9..2bebee2 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -541,7 +541,7 @@ start_pinentry (ctrl_t ctrl) } - /* Ask the pinentry for its version and flavor and streo that as a + /* Ask the pinentry for its version and flavor and store that as a * string in MB. This information is useful for helping users to * figure out Pinentry problems. */ { @@ -555,6 +555,10 @@ start_pinentry (ctrl_t ctrl) if (assuan_transact (entry_ctx, "GETINFO version", put_membuf_cb, &mb, NULL, NULL, NULL, NULL)) put_membuf_str (&mb, "unknown"); + put_membuf_str (&mb, " "); + if (assuan_transact (entry_ctx, "GETINFO ttyinfo", + put_membuf_cb, &mb, NULL, NULL, NULL, NULL)) + put_membuf_str (&mb, "? ? ?"); put_membuf (&mb, "", 1); flavor_version = get_membuf (&mb, NULL); } diff --git a/g10/server.c b/g10/server.c index b89f0be..e3a3bad 100644 --- a/g10/server.c +++ b/g10/server.c @@ -770,18 +770,15 @@ gpg_server (ctrl_t ctrl) gpg_error_t gpg_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line) { - if (opt.verbose) - { - char *linecopy = xtrystrdup (line); - char *fields[4]; - - if (linecopy - && split_fields (linecopy, fields, DIM (fields)) >= 4 - && !strcmp (fields[0], "PINENTRY_LAUNCHED")) - log_info (_("pinentry launched (pid %s, flavor %s, version %s)\n"), - fields[1], fields[2], fields[3]); + const char *s; - xfree (linecopy); + if (opt.verbose + && !strncmp (line, "PINENTRY_LAUNCHED", 17) + && (line[17]==' '||!line[17])) + { + for (s = line + 17; *s && spacep (s); s++) + ; + log_info (_("pinentry launched (%s)\n"), s); } if (!ctrl || !ctrl->server_local ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 6 +++++- g10/server.c | 19 ++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 13:15:40 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 13:15:40 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-54-g93a5907 Message-ID: This is an 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 93a59070c699d569d1eac7ba22355fe3f5d10882 (commit) via afc308598d1ddaf20d54b4eab30b959066a4e5e6 (commit) from 43160a39f27f6c3507447620666c85af00b3499c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 93a59070c699d569d1eac7ba22355fe3f5d10882 Author: Werner Koch Date: Fri Feb 3 13:13:22 2017 +0100 core: Fix possible deadlock due to get_max_fds. * src/posix-io.c (get_max_fds): Do not use the Linux optimization. -- Signed-off-by: Werner Koch diff --git a/src/posix-io.c b/src/posix-io.c index 5296f5f..cabb3e5 100644 --- a/src/posix-io.c +++ b/src/posix-io.c @@ -287,37 +287,43 @@ get_max_fds (void) int rc; /* Under Linux we can figure out the highest used file descriptor by - * reading /proc/self/fd. This is in the common cases much fast than - * for example doing 4096 close calls where almost all of them will - * fail. */ -#ifdef __linux__ - { - DIR *dir = NULL; - struct dirent *dir_entry; - const char *s; - int x; - - dir = opendir ("/proc/self/fd"); - if (dir) - { - while ((dir_entry = readdir (dir))) - { - s = dir_entry->d_name; - if ( *s < '0' || *s > '9') - continue; - x = atoi (s); - if (x > fds) - fds = x; - } - closedir (dir); - } - if (fds != -1) - { - fds++; - source = "/proc"; - } - } -#endif /* __linux__ */ + * reading /proc/self/fd. This is in the common cases much faster + * than for example doing 4096 close calls where almost all of them + * will fail. + * + * Unfortunately we can't call opendir between fork and exec in a + * multi-threaded process because opendir uses malloc and thus a + * mutex which may deadlock with a malloc in another thread. Thus + * the code is not used until we can have a opendir variant which + * does not use malloc. */ +/* #ifdef __linux__ */ +/* { */ +/* DIR *dir = NULL; */ +/* struct dirent *dir_entry; */ +/* const char *s; */ +/* int x; */ + +/* dir = opendir ("/proc/self/fd"); */ +/* if (dir) */ +/* { */ +/* while ((dir_entry = readdir (dir))) */ +/* { */ +/* s = dir_entry->d_name; */ +/* if ( *s < '0' || *s > '9') */ +/* continue; */ +/* x = atoi (s); */ +/* if (x > fds) */ +/* fds = x; */ +/* } */ +/* closedir (dir); */ +/* } */ +/* if (fds != -1) */ +/* { */ +/* fds++; */ +/* source = "/proc"; */ +/* } */ +/* } */ +/* #endif /\* __linux__ *\/ */ #ifdef RLIMIT_NOFILE if (fds == -1) commit afc308598d1ddaf20d54b4eab30b959066a4e5e6 Author: Werner Koch Date: Fri Feb 3 13:08:39 2017 +0100 core: Minor cleanup of commit 195c735 * src/verify.c (parse_tofu_user): For cleanness use gpg_error ... (_gpgme_verify_status_handler): ... and gpg_err_code. Signed-off-by: Werner Koch diff --git a/src/verify.c b/src/verify.c index 398cec5..900f925 100644 --- a/src/verify.c +++ b/src/verify.c @@ -685,7 +685,7 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol) { /* GnuPG since 2.1.17 emits multiple TOFU_USER lines with different fingerprints in case of conflicts for a signature. */ - err = GPG_ERR_DUP_VALUE; + err = gpg_error (GPG_ERR_DUP_VALUE); goto leave; } @@ -1003,13 +1003,13 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) return trace_gpg_error (GPG_ERR_INV_ENGINE); err = parse_tofu_user (sig, args, ctx->protocol); /* gpg emits TOFU User lines for each conflicting key. - GPGME does not expose this to have a clean API and - a GPGME user can do a keylisting with the address - normalisation. - So when a duplicated TOFU_USER line is encountered - we ignore the conflicting tofu stats emited afterwards. - */ - if (err == GPG_ERR_DUP_VALUE) + * GPGME does not expose this to have a clean API and + * a GPGME user can do a keylisting with the address + * normalisation. + * So when a duplicated TOFU_USER line is encountered + * we ignore the conflicting tofu stats emited afterwards. + */ + if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) { opd->conflict_user_seen = 1; break; ----------------------------------------------------------------------- Summary of changes: src/posix-io.c | 68 ++++++++++++++++++++++++++++++++-------------------------- src/verify.c | 16 +++++++------- 2 files changed, 45 insertions(+), 39 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 13:59:01 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 13:59:01 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-55-g51bd69f Message-ID: This is an 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 51bd69f216a9e2930eeba4b5f6c20e952a381720 (commit) from 93a59070c699d569d1eac7ba22355fe3f5d10882 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 51bd69f216a9e2930eeba4b5f6c20e952a381720 Author: Werner Koch Date: Fri Feb 3 13:56:23 2017 +0100 core: Optimize fork/exec for *BSD and Solaris. * configure.ac (closefrom): Add to ac_check_funcs. * src/posix-io.c (_gpgme_io_spawn): Use closefrom. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 9903751..f28480b 100644 --- a/configure.ac +++ b/configure.ac @@ -694,7 +694,7 @@ fi # # Check for getgid etc -AC_CHECK_FUNCS(getgid getegid) +AC_CHECK_FUNCS(getgid getegid closefrom) # Replacement functions. diff --git a/src/posix-io.c b/src/posix-io.c index cabb3e5..a351806 100644 --- a/src/posix-io.c +++ b/src/posix-io.c @@ -459,10 +459,9 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags, /* Intermediate child to prevent zombie processes. */ if ((pid = fork ()) == 0) { - int max_fds = get_max_fds (); - int fd; - /* Child. */ + int max_fds = -1; + int fd; int seen_stdin = 0; int seen_stdout = 0; int seen_stderr = 0; @@ -470,15 +469,40 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags, if (atfork) atfork (atforkvalue, 0); - /* First close all fds which will not be inherited. */ - for (fd = 0; fd < max_fds; fd++) - { - for (i = 0; fd_list[i].fd != -1; i++) - if (fd_list[i].fd == fd) - break; - if (fd_list[i].fd == -1) - close (fd); - } + /* First close all fds which will not be inherited. If we + * have closefrom(2) we first figure out the highest fd we + * do not want to close, then call closefrom, and on success + * use the regular code to close all fds up to the start + * point of closefrom. Note that Solaris' closefrom does + * not return errors. */ +#ifdef HAVE_CLOSEFROM + { + fd = -1; + for (i = 0; fd_list[i].fd != -1; i++) + if (fd_list[i].fd > fd) + fd = fd_list[i].fd; + fd++; +#ifdef __sun + closefrom (fd); + max_fds = fd; +#else /*!__sun */ + while ((i = closefrom (fd)) && errno == EINTR) + ; + if (!i || errno == EBADF) + max_fds = fd; +#endif /*!__sun*/ + } +#endif /*HAVE_CLOSEFROM*/ + if (max_fds == -1) + max_fds = get_max_fds (); + for (fd = 0; fd < max_fds; fd++) + { + for (i = 0; fd_list[i].fd != -1; i++) + if (fd_list[i].fd == fd) + break; + if (fd_list[i].fd == -1) + close (fd); + } /* And now dup and close those to be duplicated. */ for (i = 0; fd_list[i].fd != -1; i++) ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 +- src/posix-io.c | 48 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 13 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 17:15:52 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 17:15:52 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-58-g309f464 Message-ID: This is an 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 309f464a5952c7d7504b875bf4853914b1242346 (commit) from 7052a0d77cf8f3a445b252a809d29be445788625 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 309f464a5952c7d7504b875bf4853914b1242346 Author: Werner Koch Date: Fri Feb 3 17:13:08 2017 +0100 agent: Tell the Pinentry the client's pid. * configure.ac: Check for SO_PEERCRED et al. * agent/agent.h (server_control_s): Add field 'client_pid'. * agent/command.c (start_command_handler): Set CLIENT_PID. * agent/command-ssh.c (get_client_pid): New. (start_command_handler_ssh): Set CLIENT_PID. * agent/call-pinentry.c (start_pinentry): Tell Pinentry the client-pid. Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 2db5a5c..2178384 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -218,6 +218,7 @@ struct server_control_s session_env_t session_env; char *lc_ctype; char *lc_messages; + unsigned long client_pid; /* The current pinentry mode. */ pinentry_mode_t pinentry_mode; diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 2bebee2..384b23a 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -540,6 +540,20 @@ start_pinentry (ctrl_t ctrl) } } + /* Tell Pinentry about our client. */ + if (ctrl->client_pid) + { + char *optstr; + if ((optstr = xtryasprintf ("OPTION owner=%lu", ctrl->client_pid))) + { + assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + /* We ignore errors because this is just a fancy thing and + older pinentries do not support this feature. */ + xfree (optstr); + } + } + /* Ask the pinentry for its version and flavor and store that as a * string in MB. This information is useful for helping users to diff --git a/agent/command-ssh.c b/agent/command-ssh.c index f57bac3..1d4453c 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -3491,6 +3491,44 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) } +/* Return the peer's pid. Stripped down code from libassuan. */ +static unsigned long +get_client_pid (int fd) +{ + pid_t client_pid = (pid_t)(-1); + +#ifdef HAVE_SO_PEERCRED + { + struct ucred cr; + socklen_t cl = sizeof cr; + + if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)) + client_pid = cr.pid; + } +#elif defined (HAVE_GETPEERUCRED) + { + ucred_t *ucred = NULL; + + if (getpeerucred (fd, &ucred) != -1) + { + client_pid= ucred_getpid (ucred); + ucred_free (ucred); + } + } +#elif defined (HAVE_LOCAL_PEEREID) + { + struct unpcbid unp; + socklen_t unpl = sizeof unp; + + if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1) + client_pid = unp.unp_pid; + } +#endif + + return client_pid == (pid_t)(-1)? 0 : (unsigned long)client_pid; +} + + /* Start serving client on SOCK_CLIENT. */ void start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) @@ -3503,6 +3541,8 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) if (err) goto out; + ctrl->client_pid = get_client_pid (FD2INT(sock_client)); + /* Create stream from socket. */ stream_sock = es_fdopen (FD2INT(sock_client), "r+"); if (!stream_sock) diff --git a/agent/command.c b/agent/command.c index a2d4931..c8b34e9 100644 --- a/agent/command.c +++ b/agent/command.c @@ -3288,6 +3288,8 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd) for (;;) { + pid_t client_pid; + rc = assuan_accept (ctx); if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1) { @@ -3299,7 +3301,12 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd) break; } - ctrl->server_local->connect_from_self = (assuan_get_pid (ctx)==getpid ()); + client_pid = assuan_get_pid (ctx); + ctrl->server_local->connect_from_self = (client_pid == getpid ()); + if (client_pid != ASSUAN_INVALID_PID) + ctrl->client_pid = (unsigned long)client_pid; + else + ctrl->client_pid = 0; rc = assuan_process (ctx); if (rc) diff --git a/configure.ac b/configure.ac index 75bed06..ce02d03 100644 --- a/configure.ac +++ b/configure.ac @@ -1375,6 +1375,53 @@ if test $ac_cv_func_mmap != yes -a $mmap_needed = yes; then AC_MSG_ERROR([[Sorry, the current implemenation requires mmap.]]) fi + +# +# Check for the getsockopt SO_PEERCRED +# (This has been copied from libassuan) +# +AC_MSG_CHECKING(for SO_PEERCRED) +AC_CACHE_VAL(gnupg_cv_sys_so_peercred, + [AC_TRY_COMPILE([#include ], + [struct ucred cr; + int cl = sizeof cr; + getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);], + gnupg_cv_sys_so_peercred=yes, + gnupg_cv_sys_so_peercred=no) + ]) +AC_MSG_RESULT($gnupg_cv_sys_so_peercred) + +if test $gnupg_cv_sys_so_peercred = yes; then + AC_DEFINE(HAVE_SO_PEERCRED, 1, + [Defined if SO_PEERCRED is supported (Linux specific)]) +else + # Check for the getsockopt LOCAL_PEEREID (NetBSD) + AC_MSG_CHECKING(for LOCAL_PEEREID) + AC_CACHE_VAL(gnupg_cv_sys_so_local_peereid, + [AC_TRY_COMPILE([#include + #include ], + [struct unpcbid unp; + int unpl = sizeof unp; + getsockopt (1, SOL_SOCKET, LOCAL_PEEREID, &unp, &unpl);], + gnupg_cv_sys_so_local_peereid=yes, + gnupg_cv_sys_so_local_peereid=no) + ]) + AC_MSG_RESULT($gnupg_cv_sys_so_local_peereid) + + if test $gnupg_cv_sys_so_local_peereid = yes; then + AC_DEFINE(HAVE_LOCAL_PEEREID, 1, + [Defined if LOCAL_PEEREID is supported (NetBSD specific)]) + else + # (Open)Solaris + AC_CHECK_FUNCS([getpeerucred], AC_CHECK_HEADERS([ucred.h])) + if test $ac_cv_func_getpeerucred != yes; then + # FreeBSD + AC_CHECK_FUNCS([getpeereid]) + fi + fi +fi + + # # W32 specific test # ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 1 + agent/call-pinentry.c | 14 ++++++++++++++ agent/command-ssh.c | 40 ++++++++++++++++++++++++++++++++++++++++ agent/command.c | 9 ++++++++- configure.ac | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 17:19:05 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 17:19:05 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.0.0-12-gc0d60e1 Message-ID: This is an 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 c0d60e130b9bbd21801c8e71e80ab7c36f4ad6bd (commit) via 61cde37b3e6a41bd24476d3c285288c12da0ed60 (commit) from ce745a292192b01203ba5f557205a6f000bff953 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c0d60e130b9bbd21801c8e71e80ab7c36f4ad6bd Author: Werner Koch Date: Fri Feb 3 17:16:43 2017 +0100 gtk: Unless SETTITLE is used show the pid in the titlebar. * gtk+-2/pinentry-gtk-2.c (create_window): Display the pid as title. -- This information could also be used to lookup the command line of the process and show that in the titlebar. Signed-off-by: Werner Koch diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index e37601f..79cecda 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -631,6 +631,17 @@ create_window (pinentry_t ctx) msg = pinentry_utf8_validate (pinentry->title); gtk_window_set_title (GTK_WINDOW(win), msg); } + else if (pinentry->owner_pid) + { + char buf[100]; + snprintf (buf, sizeof buf, "%s [%lu]", + pinentry->owner_host? pinentry->owner_host:"", + pinentry->owner_pid); + buf[sizeof buf - 1] = 0; + gtk_window_set_title (GTK_WINDOW(win), buf); + } + + if (pinentry->description) { msg = pinentry_utf8_validate (pinentry->description); commit 61cde37b3e6a41bd24476d3c285288c12da0ed60 Author: Werner Koch Date: Fri Feb 3 17:15:24 2017 +0100 core: New Assuan option "owner". * pinentry/pinentry.h (struct pinentry): Add fields 'owner_pid' and 'owner_host'. * pinentry/pinentry.c (pinentry_reset): Take care of these fields. (option_handler): New option "owner". Signed-off-by: Werner Koch diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index afda9ef..d33ebe9 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -98,6 +98,8 @@ pinentry_reset (int use_defaults) char *default_tt_visi = pinentry.default_tt_visi; char *default_tt_hide = pinentry.default_tt_hide; char *touch_file = pinentry.touch_file; + unsigned long owner_pid = pinentry.owner_pid; + char *owner_host = pinentry.owner_host; /* These options are set from the command line. Don't reset them. */ @@ -131,6 +133,7 @@ pinentry_reset (int use_defaults) free (pinentry.default_tt_visi); free (pinentry.default_tt_hide); free (pinentry.touch_file); + free (pinentry.owner_host); free (pinentry.display); } @@ -171,8 +174,7 @@ pinentry_reset (int use_defaults) pinentry.color_so = PINENTRY_COLOR_DEFAULT; pinentry.color_so_bright = 0; } - else - /* Restore the options. */ + else /* Restore the options. */ { pinentry.grab = grab; pinentry.ttyname = ttyname; @@ -188,6 +190,8 @@ pinentry_reset (int use_defaults) pinentry.default_tt_visi = default_tt_visi; pinentry.default_tt_hide = default_tt_hide; pinentry.touch_file = touch_file; + pinentry.owner_pid = owner_pid; + pinentry.owner_host = owner_host; pinentry.debug = debug; pinentry.display = display; @@ -917,6 +921,35 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) if (!pinentry.lc_messages) return gpg_error_from_syserror (); } + else if (!strcmp (key, "owner")) + { + long along; + char *endp; + + free (pinentry.owner_host); + pinentry.owner_host = NULL; + + errno = 0; + along = strtol (value, &endp, 10); + if (along < 0 || errno) + pinentry.owner_pid = 0; + else + { + pinentry.owner_pid = (unsigned long)along; + while (endp && *endp == ' ') + endp++; + if (*endp) + { + pinentry.owner_host = strdup (endp); + if (pinentry.owner_host) + { + for (endp=pinentry.owner_host; *endp && *endp != ' '; endp++) + ; + *endp = 0; + } + } + } + } else if (!strcmp (key, "parent-wid")) { pinentry.parent_wid = atoi (value); diff --git a/pinentry/pinentry.h b/pinentry/pinentry.h index 45d35ad..1e891b7 100644 --- a/pinentry/pinentry.h +++ b/pinentry/pinentry.h @@ -91,6 +91,14 @@ struct pinentry /* True if caller should grab the keyboard. (Assuan: "OPTION grab" or "OPTION no-grab".) */ int grab; + + /* The PID of the owner or 0 if not known. The owner is the process + * which actually triggered the the pinentry. For example gpg. */ + unsigned long owner_pid; + + /* The malloced hostname of the owener or NULL. */ + char *owner_host; + /* The window ID of the parent window over which the pinentry window should be displayed. (Assuan: "OPTION parent-wid WID".) */ int parent_wid; ----------------------------------------------------------------------- Summary of changes: gtk+-2/pinentry-gtk-2.c | 11 +++++++++++ pinentry/pinentry.c | 37 +++++++++++++++++++++++++++++++++++-- pinentry/pinentry.h | 8 ++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 21:03:13 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 21:03:13 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.0.0-13-g36d32fb Message-ID: This is an 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 36d32fbdedb07b285d01871b3ee66400c81681d3 (commit) from c0d60e130b9bbd21801c8e71e80ab7c36f4ad6bd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 36d32fbdedb07b285d01871b3ee66400c81681d3 Author: Werner Koch Date: Fri Feb 3 21:00:52 2017 +0100 Use a shared function to construct the title. * pinentry/pinentry.c (pinentry_get_title): New. * qt/main.cpp (qt_cmd_handler): Use that function for the title. * tty/pinentry-tty.c (confirm, password): Ditto. * gnome3/pinentry-gnome3.c (create_prompt): Ditto. * gtk+-2/pinentry-gtk-2.c (create_window): Ditto. * pinentry/pinentry-emacs.c (set_labels): Ditto. Signed-off-by: Werner Koch diff --git a/gnome3/pinentry-gnome3.c b/gnome3/pinentry-gnome3.c index c148fd9..27d2132 100644 --- a/gnome3/pinentry-gnome3.c +++ b/gnome3/pinentry-gnome3.c @@ -121,7 +121,7 @@ create_prompt (pinentry_t pe, int confirm) { GcrPrompt *prompt; GError *error = NULL; - char *msg; + char *msg, *p; char window_id[32]; /* Create the prompt. */ @@ -149,9 +149,17 @@ create_prompt (pinentry_t pe, int confirm) } /* Set the messages for the various buttons, etc. */ - msg = pinentry_utf8_validate (pe->title ? pe->title : PGMNAME); - gcr_prompt_set_title (prompt, msg); - g_free (msg); + p = pinentry_get_title (pe); + if (p) + { + msg = pinentry_utf8_validate (p); + if (msg) + { + gcr_prompt_set_title (prompt, msg); + g_free (msg); + } + free (p); + } if (pe->description) { diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 79cecda..dee0360 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -563,6 +563,7 @@ create_window (pinentry_t ctx) GtkWidget *wvbox, *chbox, *bbox; GtkAccelGroup *acc; gchar *msg; + char *p; repeat_entry = NULL; @@ -626,22 +627,16 @@ create_window (pinentry_t ctx) box = gtk_vbox_new (FALSE, HIG_SMALL); gtk_box_pack_start (GTK_BOX (chbox), box, TRUE, TRUE, 0); - if (pinentry->title) + p = pinentry_get_title (pinentry); + if (p) { - msg = pinentry_utf8_validate (pinentry->title); - gtk_window_set_title (GTK_WINDOW(win), msg); - } - else if (pinentry->owner_pid) - { - char buf[100]; - snprintf (buf, sizeof buf, "%s [%lu]", - pinentry->owner_host? pinentry->owner_host:"", - pinentry->owner_pid); - buf[sizeof buf - 1] = 0; - gtk_window_set_title (GTK_WINDOW(win), buf); + msg = pinentry_utf8_validate (p); + if (msg) + gtk_window_set_title (GTK_WINDOW(win), msg); + g_free (msg); + free (p); } - if (pinentry->description) { msg = pinentry_utf8_validate (pinentry->description); diff --git a/pinentry/pinentry-emacs.c b/pinentry/pinentry-emacs.c index 50ba406..2f7693b 100644 --- a/pinentry/pinentry-emacs.c +++ b/pinentry/pinentry-emacs.c @@ -467,8 +467,14 @@ set_label (pinentry_t pe, const char *name, const char *value) static void set_labels (pinentry_t pe) { - if (pe->title) - set_label (pe, "SETTITLE", pe->title); + char *p; + + p = pinentry_get_title (pe); + if (p) + { + set_label (pe, "SETTITLE", p); + free (p); + } if (pe->description) set_label (pe, "SETDESC", pe->description); if (pe->error) diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index d33ebe9..7251899 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -390,6 +390,33 @@ copy_and_escape (char *buffer, const void *text, size_t textlen) } +/* Return a malloced string with the title. The caller mus free the + * string. If no title is available or the title string has an error + * NULL is returned. */ +char * +pinentry_get_title (pinentry_t pe) +{ + char *title; + + if (pe->title) + title = strdup (pe->title); + else if (pe->owner_pid) + { + char buf[100]; + if (pe->owner_host) + snprintf (buf, sizeof buf, "[%lu]@%s", pe->owner_pid, pe->owner_host); + else + snprintf (buf, sizeof buf, "[%lu]", + pe->owner_pid); + buf[sizeof buf - 1] = 0; + title = strdup (buf); + } + else + title = strdup (this_pgmname); + + return title; +} + /* Run a quality inquiry for PASSPHRASE of LENGTH. (We need LENGTH because not all backends might be able to return a proper diff --git a/pinentry/pinentry.h b/pinentry/pinentry.h index 1e891b7..868b4d8 100644 --- a/pinentry/pinentry.h +++ b/pinentry/pinentry.h @@ -256,6 +256,7 @@ char *pinentry_utf8_to_local (const char *lc_ctype, const char *text); Return NULL on error. */ char *pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure); +char *pinentry_get_title (pinentry_t pe); /* Run a quality inquiry for PASSPHRASE of LENGTH. */ int pinentry_inq_quality (pinentry_t pin, diff --git a/qt/main.cpp b/qt/main.cpp index 225c06b..e2af686 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -145,6 +145,7 @@ static int qt_cmd_handler(pinentry_t pe) { QWidget *parent = 0; + char *str; /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) { @@ -161,9 +162,13 @@ qt_cmd_handler(pinentry_t pe) pe->cancel ? escape_accel(from_utf8(pe->cancel)) : pe->default_cancel ? escape_accel(from_utf8(pe->default_cancel)) : /* else */ QLatin1String("&Cancel") ; + + str = pinentry_get_title (pe); const QString title = - pe->title ? from_utf8(pe->title) : + str ? from_utf8(str) : /* else */ QLatin1String("pinentry-qt") ; + free (str); + const QString repeatError = pe->repeat_error_string ? from_utf8(pe->repeat_error_string) : QLatin1String("Passphrases do not match"); @@ -179,6 +184,8 @@ qt_cmd_handler(pinentry_t pe) if (want_pass) { + char *str; + PinEntryDialog pinentry(parent, 0, pe->timeout, true, !!pe->quality_bar, repeatString, visibilityTT, hideTT); @@ -186,8 +193,11 @@ qt_cmd_handler(pinentry_t pe) pinentry.setPrompt(escape_accel(from_utf8(pe->prompt))); pinentry.setDescription(from_utf8(pe->description)); pinentry.setRepeatErrorText(repeatError); - if (pe->title) { - pinentry.setWindowTitle(from_utf8(pe->title)); + + str = pinentry_get_title (pe); + if (str) { + pinentry.setWindowTitle(from_utf8(str)); + free (str); } /* If we reuse the same dialog window. */ diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c index a509d79..8b37340 100644 --- a/tty/pinentry-tty.c +++ b/tty/pinentry-tty.c @@ -173,6 +173,7 @@ static int confirm (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo) { char *msg; + char *msgbuffer = NULL; char ok = 0; char notok = 0; @@ -184,8 +185,10 @@ confirm (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo) msg = pinentry->description; if (! msg) - /* If there is no description, fallback to the title. */ - msg = pinentry->title; + { + /* If there is no description, fallback to the title. */ + msg = msgbuffer = pinentry_get_title (pinentry); + } if (! msg) msg = "Confirm:"; @@ -194,6 +197,7 @@ confirm (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo) fputs (msg, ttyfo); fputc ('\n', ttyfo); } + free (msgbuffer); fflush (ttyfo); @@ -377,17 +381,19 @@ static int password (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo) { char *msg; + char *msgbuffer = NULL; int done = 0; msg = pinentry->description; if (! msg) - msg = pinentry->title; + msg = msgbuffer = pinentry_get_title (pinentry); if (! msg) msg = "Enter your passphrase."; dump_error_text (ttyfo, pinentry->error); fprintf (ttyfo, "%s\n", msg); + free (msgbuffer); while (! done) { ----------------------------------------------------------------------- Summary of changes: gnome3/pinentry-gnome3.c | 16 ++++++++++++---- gtk+-2/pinentry-gtk-2.c | 21 ++++++++------------- pinentry/pinentry-emacs.c | 10 ++++++++-- pinentry/pinentry.c | 27 +++++++++++++++++++++++++++ pinentry/pinentry.h | 1 + qt/main.cpp | 16 +++++++++++++--- tty/pinentry-tty.c | 12 +++++++++--- 7 files changed, 78 insertions(+), 25 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 21:19:32 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 21:19:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-59-g042fe71 Message-ID: This is an 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 042fe711c76f6377cedb8f83a73ba386cee34bb7 (commit) from 309f464a5952c7d7504b875bf4853914b1242346 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 042fe711c76f6377cedb8f83a73ba386cee34bb7 Author: Werner Koch Date: Fri Feb 3 21:16:26 2017 +0100 agent: Tell pinentry the hostname the agent is running on. * agent/call-pinentry.c [!W32]: Incluse utsname.h (start_pinentry): Pass nodename to OPTION/owner. Signed-off-by: Werner Koch diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 384b23a..9931665 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -31,6 +31,7 @@ # include # include # include +# include #endif #include @@ -544,7 +545,16 @@ start_pinentry (ctrl_t ctrl) if (ctrl->client_pid) { char *optstr; - if ((optstr = xtryasprintf ("OPTION owner=%lu", ctrl->client_pid))) + const char *nodename = ""; + +#ifndef HAVE_W32_SYSTEM + struct utsname utsbuf; + if (!uname (&utsbuf)) + nodename = utsbuf.nodename; +#endif /*!HAVE_W32_SYSTEM*/ + + if ((optstr = xtryasprintf ("OPTION owner=%lu %s", + ctrl->client_pid, nodename))) { assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 3 21:43:31 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 03 Feb 2017 21:43:31 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.0.0-14-ge467a00 Message-ID: This is an 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 e467a000f87e87582f5838964b6f1e0a960d4445 (commit) from 36d32fbdedb07b285d01871b3ee66400c81681d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e467a000f87e87582f5838964b6f1e0a960d4445 Author: Werner Koch Date: Fri Feb 3 21:41:05 2017 +0100 core: Show the command line in the titlebar. * pinentry/pinentry.c (get_cmdline): New. (pinentry_get_title): Add the cmdline to the title. -- This works only on Linux assuming that /proc/PID/cmdline is available. Signed-off-by: Werner Koch diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index 7251899..517a033 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -390,6 +390,39 @@ copy_and_escape (char *buffer, const void *text, size_t textlen) } +static char * +get_cmdline (unsigned long pid) +{ + char buffer[200]; + FILE *fp; + size_t i, n; + + snprintf (buffer, sizeof buffer, "/proc/%lu/cmdline", pid); + buffer[sizeof buffer - 1] = 0; + + fp = fopen (buffer, "rb"); + if (!fp) + return NULL; + n = fread (buffer, 1, sizeof buffer - 1, fp); + if (n < sizeof buffer -1 && ferror (fp)) + { + /* Some error occurred. */ + fclose (fp); + return NULL; + } + /* Arguments are delimites by Nuls. We should do proper quoting but + * that can be a bit complicated, thus we simply replace the Nuls by + * spaces. */ + for (i=0; i < n; i++) + if (!buffer[i]) + buffer[i] = ' '; + buffer[i] = 0; /* Make sure the last byte is the string terminator. */ + fclose (fp); + + return strdup (buffer); +} + + /* Return a malloced string with the title. The caller mus free the * string. If no title is available or the title string has an error * NULL is returned. */ @@ -402,13 +435,23 @@ pinentry_get_title (pinentry_t pe) title = strdup (pe->title); else if (pe->owner_pid) { - char buf[100]; - if (pe->owner_host) - snprintf (buf, sizeof buf, "[%lu]@%s", pe->owner_pid, pe->owner_host); + char buf[200]; + char *cmdline = get_cmdline (pe->owner_pid); + + if (pe->owner_host && cmdline) + snprintf (buf, sizeof buf, "[%lu]@%s (%s)", + pe->owner_pid, pe->owner_host, cmdline); + else if (cmdline) + snprintf (buf, sizeof buf, "[%lu] (%s)", + pe->owner_pid, cmdline); + else if (pe->owner_host) + snprintf (buf, sizeof buf, "[%lu]@%s", + pe->owner_pid, pe->owner_host); else snprintf (buf, sizeof buf, "[%lu]", pe->owner_pid); buf[sizeof buf - 1] = 0; + free (cmdline); title = strdup (buf); } else ----------------------------------------------------------------------- Summary of changes: pinentry/pinentry.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 4 07:31:52 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Sat, 04 Feb 2017 07:31:52 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-60-gf2b276d Message-ID: This is an 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 f2b276dffbe2435b17abf2b3c51684d3636f3f11 (commit) from 042fe711c76f6377cedb8f83a73ba386cee34bb7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f2b276dffbe2435b17abf2b3c51684d3636f3f11 Author: Daniel Kahn Gillmor Date: Sat Feb 4 01:28:08 2017 -0500 doc: Clarify abbreviation of --help. * doc/gpg.texi: clarify abbreviation of --help. Debian-bug-id: 852979 Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpg.texi b/doc/gpg.texi index 8e1a5e6..b79b783 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -141,7 +141,8 @@ cannot abbreviate this command. @itemx -h @opindex help Print a usage message summarizing the most useful command-line options. -Note that you cannot abbreviate this command. +Note that you cannot arbitrarily abbreviate this command +(though you can use its short form @option{-h}). @item --warranty @opindex warranty ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 4 11:54:46 2017 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 04 Feb 2017 11:54:46 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.7.3-71-gc67c728 Message-ID: This is an 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 c67c728478e8f47b6e8296b643fd35d66d4a1052 (commit) via 4b7451d3e8e7b87d8e407fbbd924ad5b13bd0f00 (commit) via 37b537600f33fcf8e1c8dc2c658a142fbba44199 (commit) via 1407317a6112a23d4fec5827a9d74faef4196f66 (commit) via efa9042f82ffed3d076b8e26ac62d29e00bb756a (commit) from e7b941c3de9c9b6319298c02f844cc0cadbf8562 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c67c728478e8f47b6e8296b643fd35d66d4a1052 Author: Jussi Kivilinna Date: Sat Feb 4 12:48:57 2017 +0200 rndhw: add missing "memory" clobbers * random/rndhw.c: (poll_padlock, rdrand_long): Add "memory" to asm clobbers. -- Signed-off-by: Jussi Kivilinna diff --git a/random/rndhw.c b/random/rndhw.c index 063c25a..e3a7861 100644 --- a/random/rndhw.c +++ b/random/rndhw.c @@ -76,7 +76,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */ : "=a" (status) : "g" (p) - : "%rdx", "%rdi", "cc" + : "%rdx", "%rdi", "cc", "memory" ); #else asm volatile @@ -85,7 +85,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */ : "=a" (status) : "g" (p) - : "%edx", "%edi", "cc" + : "%edx", "%edi", "cc", "memory" ); #endif if ((status & (1<<6)) /* RNG still enabled. */ @@ -139,7 +139,7 @@ rdrand_long (volatile unsigned long *v) "2:" : "=r" (ok), "=a" (*v) : "0" (RDRAND_RETRY_LOOPS) - : "cc"); + : "cc", "memory"); return ok; } commit 4b7451d3e8e7b87d8e407fbbd924ad5b13bd0f00 Author: Jussi Kivilinna Date: Sat Jan 28 11:00:35 2017 +0200 Add UNLIKELY and LIKELY macros * src/g10lib.h (LIKELY, UNLIKELY): New. (gcry_assert): Use LIKELY for assert check. (fast_wipememory2_unaligned_head): Use UNLIKELY for unaligned branching. * cipher/bufhelp.h (buf_cpy, buf_xor, buf_xor_1, buf_xor_2dst) (buf_xor_n_copy_2): Ditto. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index 3110a1d..b854bc0 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -1,5 +1,5 @@ /* bufhelp.h - Some buffer manipulation helpers - * Copyright (C) 2012 Jussi Kivilinna + * Copyright (C) 2012-2017 Jussi Kivilinna * * This file is part of Libgcrypt. * @@ -20,6 +20,7 @@ #define GCRYPT_BUFHELP_H +#include "g10lib.h" #include "bithelp.h" @@ -88,7 +89,7 @@ buf_cpy(void *_dst, const void *_src, size_t len) const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)dst | (uintptr_t)src) & longmask) + if (UNLIKELY(((uintptr_t)dst | (uintptr_t)src) & longmask)) goto do_bytes; #endif @@ -124,7 +125,7 @@ buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len) const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask) + if (UNLIKELY(((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask)) goto do_bytes; #endif @@ -160,7 +161,7 @@ buf_xor_1(void *_dst, const void *_src, size_t len) const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)dst | (uintptr_t)src) & longmask) + if (UNLIKELY(((uintptr_t)dst | (uintptr_t)src) & longmask)) goto do_bytes; #endif @@ -196,7 +197,7 @@ buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len) const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask) + if (UNLIKELY(((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask)) goto do_bytes; #endif @@ -238,8 +239,8 @@ buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy, const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor | - (uintptr_t)srcdst_cpy) & longmask) + if (UNLIKELY(((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor | + (uintptr_t)srcdst_cpy) & longmask)) goto do_bytes; #endif diff --git a/src/g10lib.h b/src/g10lib.h index 8ce84b8..0309a83 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -75,6 +75,14 @@ #define GCC_ATTR_UNUSED #endif +#if __GNUC__ >= 3 +#define LIKELY( expr ) __builtin_expect( !!(expr), 1 ) +#define UNLIKELY( expr ) __builtin_expect( !!(expr), 0 ) +#else +#define LIKELY( expr ) (!!(expr)) +#define UNLIKELY( expr ) (!!(expr)) +#endif + /* Gettext macros. */ #define _(a) _gcry_gettext(a) @@ -165,15 +173,15 @@ int _gcry_log_verbosity( int level ); #ifdef JNLIB_GCC_M_FUNCTION #define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ ) -#define gcry_assert(expr) ((expr)? (void)0 \ +#define gcry_assert(expr) (LIKELY(expr)? (void)0 \ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__)) #elif __STDC_VERSION__ >= 199901L #define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ ) -#define gcry_assert(expr) ((expr)? (void)0 \ +#define gcry_assert(expr) (LIKELY(expr)? (void)0 \ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__)) #else #define BUG() _gcry_bug( __FILE__ , __LINE__ ) -#define gcry_assert(expr) ((expr)? (void)0 \ +#define gcry_assert(expr) (LIKELY(expr)? (void)0 \ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__)) #endif @@ -346,7 +354,7 @@ typedef struct fast_wipememory_s } __attribute__((packed, aligned(1), may_alias)) fast_wipememory_t; #else #define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \ - while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \ + while(UNLIKELY((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1)) && _vlen) \ { *_vptr=(_vset); _vptr++; _vlen--; } \ } while(0) typedef struct fast_wipememory_s commit 37b537600f33fcf8e1c8dc2c658a142fbba44199 Author: Jussi Kivilinna Date: Sat Jan 28 15:00:28 2017 +0200 rndhw: avoid type-punching * random/rndhw.c (rdrand_long, rdrand_nlong): Add 'volatile' for pointer. (poll_drng): Convert buffer to 'unsigned long[]' and make use of DIM macro. -- Signed-off-by: Jussi Kivilinna diff --git a/random/rndhw.c b/random/rndhw.c index 8e50751..063c25a 100644 --- a/random/rndhw.c +++ b/random/rndhw.c @@ -129,7 +129,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), # define RDRAND_LONG RDRAND_INT # endif static inline int -rdrand_long (unsigned long *v) +rdrand_long (volatile unsigned long *v) { int ok; asm volatile ("1: " RDRAND_LONG "\n\t" @@ -145,7 +145,7 @@ rdrand_long (unsigned long *v) static inline int -rdrand_nlong (unsigned long *v, int count) +rdrand_nlong (volatile unsigned long *v, int count) { while (count--) if (!rdrand_long(v++)) @@ -157,12 +157,12 @@ rdrand_nlong (unsigned long *v, int count) static size_t poll_drng (add_fn_t add, enum random_origins origin, int fast) { - volatile char buffer[64] __attribute__ ((aligned (8))); + volatile unsigned long buffer[8] __attribute__ ((aligned (8))); unsigned int nbytes = sizeof (buffer); (void)fast; - if (!rdrand_nlong ((unsigned long *)buffer, sizeof(buffer)/sizeof(long))) + if (!rdrand_nlong (buffer, DIM(buffer))) return 0; (*add)((void *)buffer, nbytes, origin); return nbytes; commit 1407317a6112a23d4fec5827a9d74faef4196f66 Author: Jussi Kivilinna Date: Sat Jan 28 14:59:56 2017 +0200 hwf-x86: avoid type-punching * src/hwf-x86.c (detect_x86_gnuc): Use union for vendor_id. -- Signed-off-by: Jussi Kivilinna diff --git a/src/hwf-x86.c b/src/hwf-x86.c index a746ab2..53e00d9 100644 --- a/src/hwf-x86.c +++ b/src/hwf-x86.c @@ -170,7 +170,11 @@ get_xgetbv(void) static unsigned int detect_x86_gnuc (void) { - char vendor_id[12+1]; + union + { + char c[12+1]; + unsigned int ui[3]; + } vendor_id; unsigned int features; unsigned int os_supports_avx_avx2_registers = 0; unsigned int max_cpuid_level; @@ -183,16 +187,14 @@ detect_x86_gnuc (void) if (!is_cpuid_available()) return 0; - get_cpuid(0, &max_cpuid_level, - (unsigned int *)&vendor_id[0], - (unsigned int *)&vendor_id[8], - (unsigned int *)&vendor_id[4]); - vendor_id[12] = 0; + get_cpuid(0, &max_cpuid_level, &vendor_id.ui[0], &vendor_id.ui[2], + &vendor_id.ui[1]); + vendor_id.c[12] = 0; if (0) ; /* Just to make "else if" and ifdef macros look pretty. */ #ifdef ENABLE_PADLOCK_SUPPORT - else if (!strcmp (vendor_id, "CentaurHauls")) + else if (!strcmp (vendor_id.c, "CentaurHauls")) { /* This is a VIA CPU. Check what PadLock features we have. */ @@ -225,12 +227,12 @@ detect_x86_gnuc (void) } } #endif /*ENABLE_PADLOCK_SUPPORT*/ - else if (!strcmp (vendor_id, "GenuineIntel")) + else if (!strcmp (vendor_id.c, "GenuineIntel")) { /* This is an Intel CPU. */ result |= HWF_INTEL_CPU; } - else if (!strcmp (vendor_id, "AuthenticAMD")) + else if (!strcmp (vendor_id.c, "AuthenticAMD")) { /* This is an AMD CPU. */ } commit efa9042f82ffed3d076b8e26ac62d29e00bb756a Author: Jussi Kivilinna Date: Sat Jan 28 10:26:09 2017 +0200 cipher: add explicit blocksize checks to allow better optimization * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt) (_gcry_cipher_cbc_decrypt): Add explicit check for cipher blocksize of 64-bit or 128-bit. * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt) (_gcry_cipher_cfb_decrypt): Ditto. * cipher/cipher-cmac.c (cmac_write, cmac_generate_subkeys) (cmac_final): Ditto. * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto. * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt): Ditto. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/cipher-cbc.c b/cipher/cipher-cbc.c index 67814b7..95c49b2 100644 --- a/cipher/cipher-cbc.c +++ b/cipher/cipher-cbc.c @@ -44,6 +44,11 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c, size_t nblocks = inbuflen / blocksize; unsigned int burn, nburn; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return GPG_ERR_INV_LENGTH; + if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen)) return GPG_ERR_BUFFER_TOO_SHORT; @@ -133,6 +138,11 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, size_t nblocks = inbuflen / blocksize; unsigned int burn, nburn; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return GPG_ERR_INV_LENGTH; + if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c index f289ed3..21c81ca 100644 --- a/cipher/cipher-cfb.c +++ b/cipher/cipher-cfb.c @@ -41,6 +41,11 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, size_t blocksize_x_2 = blocksize + blocksize; unsigned int burn, nburn; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return GPG_ERR_INV_LENGTH; + if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; @@ -138,6 +143,11 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, size_t blocksize_x_2 = blocksize + blocksize; unsigned int burn, nburn; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return GPG_ERR_INV_LENGTH; + if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c index eca1c1a..da3ef75 100644 --- a/cipher/cipher-cmac.c +++ b/cipher/cipher-cmac.c @@ -42,6 +42,11 @@ cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen) unsigned int burn = 0; unsigned int nblocks; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return; + if (!inlen || !inbuf) return; @@ -109,6 +114,11 @@ cmac_generate_subkeys (gcry_cipher_hd_t c) byte buf[MAX_BLOCKSIZE]; } u; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return; + if (MAX_BLOCKSIZE < blocksize) BUG (); @@ -149,6 +159,11 @@ cmac_final (gcry_cipher_hd_t c) unsigned int burn; byte *subkey; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return; + if (count == blocksize) subkey = c->u_mode.cmac.subkeys[0]; /* K1 */ else diff --git a/cipher/cipher-ctr.c b/cipher/cipher-ctr.c index 4bbfaae..f9cb6b5 100644 --- a/cipher/cipher-ctr.c +++ b/cipher/cipher-ctr.c @@ -42,6 +42,11 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, size_t nblocks; unsigned int burn, nburn; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return GPG_ERR_INV_LENGTH; + if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; diff --git a/cipher/cipher-ofb.c b/cipher/cipher-ofb.c index 7db7658..f821d1b 100644 --- a/cipher/cipher-ofb.c +++ b/cipher/cipher-ofb.c @@ -40,6 +40,11 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, size_t blocksize = c->spec->blocksize; unsigned int burn, nburn; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block + * length, to allow better optimization of this function. */ + if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) + return GPG_ERR_INV_LENGTH; + if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; ----------------------------------------------------------------------- Summary of changes: cipher/bufhelp.h | 15 ++++++++------- cipher/cipher-cbc.c | 10 ++++++++++ cipher/cipher-cfb.c | 10 ++++++++++ cipher/cipher-cmac.c | 15 +++++++++++++++ cipher/cipher-ctr.c | 5 +++++ cipher/cipher-ofb.c | 5 +++++ random/rndhw.c | 14 +++++++------- src/g10lib.h | 16 ++++++++++++---- src/hwf-x86.c | 20 +++++++++++--------- 9 files changed, 83 insertions(+), 27 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 4 12:37:55 2017 From: cvs at cvs.gnupg.org (by Mathias L. Baumann) Date: Sat, 04 Feb 2017 12:37:55 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.7.3-73-gd1ee9a6 Message-ID: This is an 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 d1ee9a660571ce4a998c9ab2299d4f2419f99127 (commit) via 80bd6195c794a7900791a88b943f371dc480cf07 (commit) from c67c728478e8f47b6e8296b643fd35d66d4a1052 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d1ee9a660571ce4a998c9ab2299d4f2419f99127 Author: Mathias L. Baumann Date: Sat Feb 4 13:30:41 2017 +0200 Implement CFB with 8-bit mode * cipher/cipher-cfb.c (_gcry_cipher_cfb8_encrypt) (_gcry_cipher_cfg8_decrypt): Add 8-bit variants of decrypt/encrypt functions. * cipher/cipher-internal.h (_gcry_cipher_cfb8_encrypt) (_gcry_cipher_cfg8_decrypt): Ditto. * cipher/cipher.c: Adjust code flow to work with GCRY_CIPHER_MODE_CFB8. * tests/basic.c: Add tests for cfb8 with AES and 3DES. -- Signed-off-by: Mathias L. Baumann [JK: edit changelog, fix email malformed patch] Signed-off-by: Jussi Kivilinna diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c index 21c81ca..cca5c1f 100644 --- a/cipher/cipher-cfb.c +++ b/cipher/cipher-cfb.c @@ -233,3 +233,89 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, return 0; } + + +gcry_err_code_t +_gcry_cipher_cfb8_encrypt (gcry_cipher_hd_t c, + unsigned char *outbuf, size_t outbuflen, + const unsigned char *inbuf, size_t inbuflen) +{ + gcry_cipher_encrypt_t enc_fn = c->spec->encrypt; + size_t blocksize = c->spec->blocksize; + unsigned int burn, nburn; + + if (outbuflen < inbuflen) + return GPG_ERR_BUFFER_TOO_SHORT; + + burn = 0; + + while ( inbuflen > 0) + { + /* Encrypt the IV. */ + nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + + outbuf[0] = c->lastiv[0] ^ inbuf[0]; + + /* Bitshift iv by 8 bit to the left */ + for (int i = 0; i < blocksize-1; i++) + c->u_iv.iv[i] = c->u_iv.iv[i+1]; + + /* append cipher text to iv */ + c->u_iv.iv[blocksize-1] = outbuf[0]; + + outbuf += 1; + inbuf += 1; + inbuflen -= 1; + } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + + return 0; +} + + +gcry_err_code_t +_gcry_cipher_cfb8_decrypt (gcry_cipher_hd_t c, + unsigned char *outbuf, size_t outbuflen, + const unsigned char *inbuf, size_t inbuflen) +{ + gcry_cipher_encrypt_t enc_fn = c->spec->encrypt; + size_t blocksize = c->spec->blocksize; + unsigned int burn, nburn; + unsigned char appendee; + + if (outbuflen < inbuflen) + return GPG_ERR_BUFFER_TOO_SHORT; + + burn = 0; + + while (inbuflen > 0) + { + /* Encrypt the IV. */ + nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + + /* inbuf might == outbuf, make sure we keep the value + so we can append it later */ + appendee = inbuf[0]; + + outbuf[0] = inbuf[0] ^ c->lastiv[0]; + + /* Bitshift iv by 8 bit to the left */ + for (int i = 0; i < blocksize-1; i++) + c->u_iv.iv[i] = c->u_iv.iv[i+1]; + + c->u_iv.iv[blocksize-1] = appendee; + + outbuf += 1; + inbuf += 1; + inbuflen -= 1; + } + + if (burn > 0) + _gcry_burn_stack (burn + 4 * sizeof(void *)); + + return 0; +} diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index 33d0629..ea9c33d 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -348,6 +348,14 @@ gcry_err_code_t _gcry_cipher_cfb_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); +gcry_err_code_t _gcry_cipher_cfb8_encrypt +/* */ (gcry_cipher_hd_t c, + unsigned char *outbuf, size_t outbuflen, + const unsigned char *inbuf, size_t inbuflen); +gcry_err_code_t _gcry_cipher_cfb8_decrypt +/* */ (gcry_cipher_hd_t c, + unsigned char *outbuf, size_t outbuflen, + const unsigned char *inbuf, size_t inbuflen); /*-- cipher-ofb.c --*/ diff --git a/cipher/cipher.c b/cipher/cipher.c index 06ce1da..124700e 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -415,6 +415,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle, case GCRY_CIPHER_MODE_ECB: case GCRY_CIPHER_MODE_CBC: case GCRY_CIPHER_MODE_CFB: + case GCRY_CIPHER_MODE_CFB8: case GCRY_CIPHER_MODE_OFB: case GCRY_CIPHER_MODE_CTR: case GCRY_CIPHER_MODE_AESWRAP: @@ -902,6 +903,10 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, rc = _gcry_cipher_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; + case GCRY_CIPHER_MODE_CFB8: + rc = _gcry_cipher_cfb8_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); + break; + case GCRY_CIPHER_MODE_OFB: rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; @@ -1029,6 +1034,10 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, rc = _gcry_cipher_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; + case GCRY_CIPHER_MODE_CFB8: + rc = _gcry_cipher_cfb8_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); + break; + case GCRY_CIPHER_MODE_OFB: rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; diff --git a/tests/basic.c b/tests/basic.c index 6d086b5..1b61122 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -893,7 +893,104 @@ check_cfb_cipher (void) 16, "\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71" } } - } + }, + { GCRY_CIPHER_AES, 1, + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b", + 1, + "\x3b"}, + { "\xc1", + 1, + "\x79"}, + { "\xbe", + 1, + "\x42"}, + { "\xe2", + 1, + "\x4c"}, + } + }, + { GCRY_CIPHER_AES192, 1, + "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" + "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b", + 1, + "\xcd"}, + { "\xc1", + 1, + "\xa2"}, + { "\xbe", + 1, + "\x52"}, + { "\xe2", + 1, + "\x1e"}, + } + }, + { GCRY_CIPHER_AES256, 1, + "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b", + 1, + "\xdc"}, + { "\xc1", + 1, + "\x1f"}, + { "\xbe", + 1, + "\x1a"}, + { "\xe2", + 1, + "\x85"}, + } + }, + { GCRY_CIPHER_AES, 1, + "\x3a\x6f\x91\x59\x26\x3f\xa6\xce\xf2\xa0\x75\xca\xfa\xce\x58\x17", + "\x0f\xc2\x36\x62\xb7\xdb\xf7\x38\x27\xf0\xc7\xde\x32\x1c\xa3\x6e", + { { "\x87\xef\xeb\x8d\x55\x9e\xd3\x36\x77\x28", + 10, + "\x8e\x9c\x50\x42\x56\x14\xd5\x40\xce\x11"}, + } + }, + { GCRY_CIPHER_AES192, 1, + "\x53\x7e\x7b\xf6\x61\xfd\x40\x24\xa0\x24\x61\x3f\x15\xb1\x36\x90" + "\xf7\xd0\xc8\x47\xc1\xe1\x89\x65", + "\x3a\x81\xf9\xd9\xd3\xc1\x55\xb0\xca\xad\x5d\x73\x34\x94\x76\xfc", + { { "\xd3\xd8\xb9\xb9\x84\xad\xc2\x42\x37\xee", + 10, + "\x38\x79\xfe\xa7\x2a\xc9\x99\x29\xe5\x3a"}, + } + }, + { GCRY_CIPHER_AES256, 1, + "\xeb\xbb\x45\x66\xb5\xe1\x82\xe0\xf0\x72\x46\x6b\x0b\x31\x1d\xf3" + "\x8f\x91\x75\xbc\x02\x13\xa5\x53\x0b\xce\x2e\xc4\xd7\x4f\x40\x0d", + "\x09\x56\xa4\x8e\x01\x00\x2c\x9e\x16\x37\x6d\x6e\x30\x8d\xba\xd1", + { { "\xb0\xfe\x25\xac\x8d\x3d\x28\xa2\xf4\x71", + 10, + "\x63\x8c\x68\x23\xe7\x25\x6f\xb5\x62\x6e"}, + } + }, + { GCRY_CIPHER_3DES, 1, + "\xe3\x34\x7a\x6b\x0b\xc1\x15\x2c\x64\x2a\x25\xcb\xd3\xbc\x31\xab" + "\xfb\xa1\x62\xa8\x1f\x19\x7c\x15", + "\xb7\x40\xcc\x21\xe9\x25\xe3\xc8", + { { "\xdb\xe9\x15\xfc\xb3\x3b\xca\x18\xef\x14", + 10, + "\xf4\x80\x1a\x8d\x03\x9d\xb4\xca\x8f\xf6"}, + } + }, + { GCRY_CIPHER_3DES, 1, + "\x7c\xa2\x89\x38\xba\x6b\xec\x1f\xfe\xc7\x8f\x7c\xd6\x97\x61\x94" + "\x7c\xa2\x89\x38\xba\x6b\xec\x1f", + "\x95\x38\x96\x58\x6e\x49\xd3\x8f", + { { "\x2e\xa9\x56\xd4\xa2\x11\xdb\x68\x59\xb7", + 10, + "\xf2\x0e\x53\x66\x74\xa6\x6f\xa7\x38\x05"}, + } + }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; @@ -6179,6 +6276,7 @@ check_ciphers (void) check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB8, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); commit 80bd6195c794a7900791a88b943f371dc480cf07 Author: Jussi Kivilinna Date: Sat Feb 4 13:29:50 2017 +0200 Register DCO for Mathias L. Baumann -- Signed-off-by: Jussi Kivilinna diff --git a/AUTHORS b/AUTHORS index 25de16c..b80d43e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -168,6 +168,9 @@ Jussi Kivilinna Markus Teich 2014-10-08:20141008180509.GA2770 at trolle: +Mathias L. Baumann +2017-01-30:07c06d79-0828-b564-d604-fd16c7c86ebe at sociomantic.com: + Milan Broz 2014-01-13:52D44CC6.4050707 at gmail.com: ----------------------------------------------------------------------- Summary of changes: AUTHORS | 3 ++ cipher/cipher-cfb.c | 86 ++++++++++++++++++++++++++++++++++++++++ cipher/cipher-internal.h | 8 ++++ cipher/cipher.c | 9 +++++ tests/basic.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 205 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 5 18:07:36 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Sun, 05 Feb 2017 18:07:36 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-61-gf31120a Message-ID: This is an 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 f31120a5aa40b6e4e89d41d1d5d34e0f7da173b4 (commit) from f2b276dffbe2435b17abf2b3c51684d3636f3f11 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f31120a5aa40b6e4e89d41d1d5d34e0f7da173b4 Author: Daniel Kahn Gillmor Date: Sat Feb 4 01:23:32 2017 -0500 gpg: Fix aliases --list-key, --list-sig, and --check-sig. * g10/gpg.c (opts): Define commands with ARGPARSE_c instead of ARGPARSE_s_n. -- These three entries are commands, but they're being treated as a string-based option for some reason. However, if you try to use them concurrently with another command like --clearsign, you'll get "gpg: conflicting commands". Furthermore, because they're marked as options, their flags differ from the commands that they alias, they cause ambiguity in abbreviation (e.g. try "gpg --list-ke") which should have been fixed by 7249ab0f95d1f6cb8ee61eefedc79801bb56398f. Marking them explicitly as commands for argparse should be more accurate and should resolve the abbreviation ambiguity issue. Signed-off-by: Daniel Kahn Gillmor gpg: fix aliases --list-key, --list-sig, and --check-sig. * g10/gpg.c: ARGPARSE_OPTS opts[]: define commands with ARGPARSE_c instead of ARGPARSE_s_n. -- These three entries are commands, but they're being treated as a string-based option for some reason. However, if you try to use them concurrently with another command like --clearsign, you'll get "gpg: conflicting commands". Furthermore, because they're marked as options, their flags differ from the commands that they alias, they cause ambiguity in abbreviation (e.g. try "gpg --list-ke") which should have been fixed by 7249ab0f95d1f6cb8ee61eefedc79801bb56398f. Marking them explicitly as commands for argparse should be more accurate and should resolve the abbreviation ambiguity issue. Signed-off-by: Daniel Kahn Gillmor diff --git a/g10/gpg.c b/g10/gpg.c index f9039ae..e280c22 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -728,9 +728,9 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"), ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"), ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"), - ARGPARSE_s_n (aListKeys, "list-key", "@"), /* alias */ - ARGPARSE_s_n (aListSigs, "list-sig", "@"), /* alias */ - ARGPARSE_s_n (aCheckKeys, "check-sig", "@"), /* alias */ + ARGPARSE_c (aListKeys, "list-key", "@"), /* alias */ + ARGPARSE_c (aListSigs, "list-sig", "@"), /* alias */ + ARGPARSE_c (aCheckKeys, "check-sig", "@"), /* alias */ ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"), ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"), ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"), ----------------------------------------------------------------------- Summary of changes: g10/gpg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 6 05:40:05 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Mon, 06 Feb 2017 05:40:05 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-56-gad22bee Message-ID: This is an 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 ad22bee5387b1e9a40e8c822a081db3228bb9def (commit) from 51bd69f216a9e2930eeba4b5f6c20e952a381720 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ad22bee5387b1e9a40e8c822a081db3228bb9def Author: Daniel Kahn Gillmor Date: Thu Jan 26 18:36:39 2017 -0500 doc: Document that gpgme_op_genkey() parms parameter is not XML. * doc/gpgme.texi (GnupgKeyParms): document that input format is not true XML. -- Please see discussion at https://lists.gnupg.org/pipermail/gnupg-devel/2017-January/032507.html Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 99627c4..e058fba 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3874,11 +3874,18 @@ and return a certificate request in @var{public}, which then needs to be signed by the certification authority and imported before it can be used. GpgSM does not make the fingerprint available. -The argument @var{parms} specifies parameters for the key in an XML -string. The details about the format of @var{parms} are specific to -the crypto engine used by @var{ctx}. Here is an example for GnuPG as -the crypto engine (all parameters of OpenPGP key generation are -documented in the GPG manual): +The argument @var{parms} specifies parameters for the key in an string +that looks something like XML. The details about the format of + at var{parms} are specific to the crypto engine used by @var{ctx}. The +first line of the parameters must be @code{} and the last line must be + at code{}. Every line in between the first and last +lines is treated as a Header: Value pair. In particular, no XML +escaping is necessary if you need to include the characters @code{<}, + at code{>}, or @code{&}. + +Here is an example for GnuPG as the crypto engine (all parameters of +OpenPGP key generation are documented in the GPG manual): @example @@ -3914,9 +3921,10 @@ retrieved with @code{gpgme_op_genkey_result}. The function returns the error code @code{GPG_ERR_NO_ERROR} if the operation could be started successfully, @code{GPG_ERR_INV_VALUE} if - at var{parms} is not a valid XML string, @code{GPG_ERR_NOT_SUPPORTED} if - at var{public} or @var{secret} is not valid, and @code{GPG_ERR_GENERAL} -if no key was created by the backend. + at var{parms} is not a well-formed string (e.g. does not have the +expected tag-like headers and footers), @code{GPG_ERR_NOT_SUPPORTED} +if @var{public} or @var{secret} is not valid, and + at code{GPG_ERR_GENERAL} if no key was created by the backend. @end deftypefun @deftypefun gpgme_error_t gpgme_op_genkey_start (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{parms}}, @w{gpgme_data_t @var{public}}, @w{gpgme_data_t @var{secret}}) ----------------------------------------------------------------------- Summary of changes: doc/gpgme.texi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 7 10:07:08 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 07 Feb 2017 10:07:08 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-57-g903bf16 Message-ID: This is an 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 903bf16a416b1bf608b1e647937c9b06864b0141 (commit) from ad22bee5387b1e9a40e8c822a081db3228bb9def (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 903bf16a416b1bf608b1e647937c9b06864b0141 Author: Andre Heinecke Date: Tue Feb 7 10:01:58 2017 +0100 qt: Don't rely on implicit include in t-verify * lang/qt/tests/t-various.cpp: Include QTemporaryDir -- This fixes build with some Qt Versions diff --git a/lang/qt/tests/t-various.cpp b/lang/qt/tests/t-various.cpp index aa45b62..b4ba9f2 100644 --- a/lang/qt/tests/t-various.cpp +++ b/lang/qt/tests/t-various.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include "keylistjob.h" #include "protocol.h" #include "keylistresult.h" ----------------------------------------------------------------------- Summary of changes: lang/qt/tests/t-various.cpp | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 7 10:30:24 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 07 Feb 2017 10:30:24 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.7.3-74-g75d91ff Message-ID: This is an 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 75d91ffeaf83098ade325bb3b6b2c8a76eb1f6a6 (commit) from d1ee9a660571ce4a998c9ab2299d4f2419f99127 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 75d91ffeaf83098ade325bb3b6b2c8a76eb1f6a6 Author: Justus Winter Date: Tue Feb 7 10:20:58 2017 +0100 Fix building with a pre C99 compiler. * cipher/cipher-cfb.c (_gcry_cipher_cfb8_encrypt): Move the declaration of 'i' out of the loop. (_gcry_cipher_cfb8_decrypt): Likewise. -- Fixes build on OpenBSD. Fixes-commit: d1ee9a660571ce4a998c9ab2299d4f2419f99127 Signed-off-by: Justus Winter diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c index cca5c1f..c888e70 100644 --- a/cipher/cipher-cfb.c +++ b/cipher/cipher-cfb.c @@ -251,6 +251,8 @@ _gcry_cipher_cfb8_encrypt (gcry_cipher_hd_t c, while ( inbuflen > 0) { + int i; + /* Encrypt the IV. */ nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv ); burn = nburn > burn ? nburn : burn; @@ -258,7 +260,7 @@ _gcry_cipher_cfb8_encrypt (gcry_cipher_hd_t c, outbuf[0] = c->lastiv[0] ^ inbuf[0]; /* Bitshift iv by 8 bit to the left */ - for (int i = 0; i < blocksize-1; i++) + for (i = 0; i < blocksize-1; i++) c->u_iv.iv[i] = c->u_iv.iv[i+1]; /* append cipher text to iv */ @@ -293,6 +295,8 @@ _gcry_cipher_cfb8_decrypt (gcry_cipher_hd_t c, while (inbuflen > 0) { + int i; + /* Encrypt the IV. */ nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv ); burn = nburn > burn ? nburn : burn; @@ -304,7 +308,7 @@ _gcry_cipher_cfb8_decrypt (gcry_cipher_hd_t c, outbuf[0] = inbuf[0] ^ c->lastiv[0]; /* Bitshift iv by 8 bit to the left */ - for (int i = 0; i < blocksize-1; i++) + for (i = 0; i < blocksize-1; i++) c->u_iv.iv[i] = c->u_iv.iv[i+1]; c->u_iv.iv[blocksize-1] = appendee; ----------------------------------------------------------------------- Summary of changes: cipher/cipher-cfb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 7 11:54:31 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 07 Feb 2017 11:54:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-64-gb30ac66 Message-ID: This is an 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 b30ac663cec82c89ca9a3e87e65b36d2552f1533 (commit) from aa3f08794bfc809821e2fc30a09a5ae23925c645 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b30ac663cec82c89ca9a3e87e65b36d2552f1533 Author: Werner Koch Date: Tue Feb 7 11:48:58 2017 +0100 wks: Add WKS-Phase headers to the server messages. * tools/gpg-wks-server.c (send_confirmation_request): Add custom header. (send_congratulation_message): Ditto. Signed-off-by: Werner Koch diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index 1a91858..ca89fc3 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -915,6 +915,13 @@ send_confirmation_request (server_ctx_t ctx, err = mime_maker_add_header (mime, "Subject", "Confirm your key publication"); if (err) goto leave; + + /* Help Enigmail to identify messages. Note that this is on no way + * secured. */ + err = mime_maker_add_header (mime, "WKS-Phase", "confirm"); + if (err) + goto leave; + for (sl = opt.extra_headers; sl; sl = sl->next) { err = mime_maker_add_header (mime, sl->d, NULL); @@ -1206,6 +1213,9 @@ send_congratulation_message (const char *mbox, const char *keyfile) err = mime_maker_add_header (mime, "Subject", "Your key has been published"); if (err) goto leave; + err = mime_maker_add_header (mime, "WKS-Phase", "done"); + if (err) + goto leave; for (sl = opt.extra_headers; sl; sl = sl->next) { err = mime_maker_add_header (mime, sl->d, NULL); ----------------------------------------------------------------------- Summary of changes: tools/gpg-wks-server.c | 10 ++++++++++ 1 file changed, 10 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 7 15:41:43 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 07 Feb 2017 15:41:43 +0100 Subject: [git] GpgEX - branch, master, updated. gpgex-1.0.4-5-gcb5f44e Message-ID: This is an 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 cb5f44e8c5d947aa85a345fa9446cd4920b626f7 (commit) from 3dddfb2546b839e104286767f504e456ae91df45 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cb5f44e8c5d947aa85a345fa9446cd4920b626f7 Author: Werner Koch Date: Tue Feb 7 15:38:58 2017 +0100 Assign maintainer -- Signed-off-by: Werner Koch diff --git a/AUTHORS b/AUTHORS index fe7a90d..0e83566 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,8 @@ Package: gpgex Contact: info-gpgex at g10code.com -Bugs: http://bugs.gnupg.org +Bugs: https://bugs.gnupg.org +Security related bug reports: +Maintainer: Andre Heinecke License: LGPLv2.1 g10 Code GmbH ----------------------------------------------------------------------- Summary of changes: AUTHORS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- GnupG extension for the Windows Explorer http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 7 15:45:27 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 07 Feb 2017 15:45:27 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-1.4.0-257-g866ba99 Message-ID: This is an 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 866ba9958d862f906cdd22aacd11a39a6413a3f4 (commit) from afb10a7a8b17f0e0028b43ae4d9c613bbecc4c18 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 866ba9958d862f906cdd22aacd11a39a6413a3f4 Author: Werner Koch Date: Tue Feb 7 15:41:16 2017 +0100 Assign maintainer -- Signed-off-by: Werner Koch diff --git a/AUTHORS b/AUTHORS index 288efac..eafab81 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,7 @@ Package: gpgol -Contact: info-gpgol at g10code.com -Bugs: http://bugs.gnupg.org +Bugs: https://bugs.gnupg.org +Security related bug reports: +Maintainer: Andre Heinecke License: LGPLv2.1+ ----------------------------------------------------------------------- Summary of changes: AUTHORS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 7 18:09:26 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 07 Feb 2017 18:09:26 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-65-g56aa85f Message-ID: This is an 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 56aa85f88f6b35fb03a2dc1a95882d49a74290e3 (commit) from b30ac663cec82c89ca9a3e87e65b36d2552f1533 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 56aa85f88f6b35fb03a2dc1a95882d49a74290e3 Author: Justus Winter Date: Tue Feb 7 18:01:44 2017 +0100 tests: Skip key types not supported by OpenSSH. * tests/openpgp/ssh-import.scm (path): New variable. (ssh,ssh-keygen,ssh-version,ssh-supports?): Likewise. -- Skip algorithms not supported by the OpenSSH in the ssh import test. This notably fixes the test on macOS when the stock ssh version is used. GnuPG-bug-id: 2847 GnuPG-bug-id: 2947 Signed-off-by: Justus Winter diff --git a/tests/openpgp/ssh-import.scm b/tests/openpgp/ssh-import.scm index ad5acc5..7a4364c 100755 --- a/tests/openpgp/ssh-import.scm +++ b/tests/openpgp/ssh-import.scm @@ -24,10 +24,35 @@ (call-check `(,(tool 'gpgconf) --null --list-dirs agent-ssh-socket)) #t) -(define SSH-ADD #f) +(define path (string-split (getenv "PATH") *pathsep*)) +(define ssh #f) +(catch (skip "ssh not found") (set! ssh (path-expand "ssh" path))) + +(define ssh-add #f) (catch (skip "ssh-add not found") - (set! SSH-ADD - (path-expand "ssh-add" (string-split (getenv "PATH") *pathsep*)))) + (set! ssh-add (path-expand "ssh-add" path))) + +(define ssh-keygen #f) +(catch (skip "ssh-keygen not found") + (set! ssh-keygen (path-expand "ssh-keygen" path))) + +(define ssh-version + (let ((tmp (:stderr (call-with-io `(,ssh "-V") ""))) + (prefix "OpenSSH_")) + (unless (string-prefix? tmp prefix) + (skip "This doesn't look like OpenSSH:" tmp)) + (string->number (substring tmp (string-length prefix) + (+ 3 (string-length prefix)))))) + +(define (ssh-supports? algorithm) + (cond + ((equal? algorithm "ed25519") + (>= ssh-version 6.5)) + (else + (not (string-contains? (:stderr (call-with-io `(,ssh-keygen + -t ,algorithm + -b "1009") "")) + "unknown key type"))))) (define keys '(("dsa" "9a:e1:f1:5f:46:ea:a5:06:e1:e2:f8:38:8e:06:54:58") @@ -48,7 +73,7 @@ (pipe:spawn `(,SSH-ADD -))) (unless (string-contains? (call-popen `(,SSH-ADD -l "-E" md5) "") hash) (fail "key not added")))) - car keys) + car (filter (lambda (x) (ssh-supports? (car x))) keys)) (info "Checking for issue2316...") (unlink (path-join GNUPGHOME "sshcontrol")) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/ssh-import.scm | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 8 10:08:04 2017 From: cvs at cvs.gnupg.org (by Anatoly madRat L. Berenblit) Date: Wed, 08 Feb 2017 10:08:04 +0100 Subject: [git] Pinentry - branch, justus/fltk, created. pinentry-1.0.0-15-g183fea8 Message-ID: This is an 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, justus/fltk has been created at 183fea8ae35b693757deb719920414a334a3a936 (commit) - Log ----------------------------------------------------------------- commit 183fea8ae35b693757deb719920414a334a3a936 Author: Anatoly madRat L. Berenblit Date: Tue Feb 7 17:18:41 2017 +0100 fltk: Add a FLTK-based pinentry. * Makefile.am: Add new subdirectory. * configure.ac: Add configuration for FLTK. * fltk/Makefile.am: New file. * fltk/encrypt.xpm: Likewise. * fltk/icon.xpm: Likewise. * fltk/main.cxx: Likewise. * fltk/passwindow.cxx: Likewise. * fltk/passwindow.h: Likewise. * fltk/pinwindow.cxx: Likewise. * fltk/pinwindow.h: Likewise. * fltk/qualitypasswindow.cxx: Likewise. * fltk/qualitypasswindow.h: Likewise. Signed-off-by: Justus Winter diff --git a/Makefile.am b/Makefile.am index ef80f6c..1f62939 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,9 +70,15 @@ else pinentry_w32 = endif +if BUILD_PINENTRY_FLTK +pinentry_fltk = fltk +else +pinentry_fltk = +endif + SUBDIRS = m4 secmem pinentry ${pinentry_curses} ${pinentry_tty} \ ${pinentry_emacs} ${pinentry_gtk_2} ${pinentry_gnome_3} \ - ${pinentry_qt} ${pinentry_w32} doc + ${pinentry_qt} ${pinentry_w32} ${pinentry_fltk} doc install-exec-local: diff --git a/configure.ac b/configure.ac index 5119e4a..8b38149 100644 --- a/configure.ac +++ b/configure.ac @@ -588,6 +588,42 @@ pinentry_w32=no test $have_w32_system = yes && pinentry_w32=yes AM_CONDITIONAL(BUILD_PINENTRY_W32, test "$pinentry_w32" = "yes") +dnl +dnl Check for FLTK pinentry program. +dnl +AC_ARG_ENABLE(pinentry-fltk, + AC_HELP_STRING([--enable-pinentry-fltk], [build FLTK 1.3 pinentry]), + pinentry_fltk=$enableval, pinentry_fltk=maybe) + +dnl check for fltk-config +if test "$pinentry_fltk" != "no"; then + AC_PATH_PROG(FLTK_CONFIG, fltk-config, no) + if test x"${FLTK_CONFIG}" = xno ; then + AC_MSG_WARN([fltk-config is not found]) + pinentry_fltk=no + fi +fi + +dnl check for FLTK libraries and set flags +if test "$pinentry_fltk" != "no"; then + AC_MSG_CHECKING([for FLTK 1.3]) + FLTK_VERSION=`${FLTK_CONFIG} --api-version` + if test ${FLTK_VERSION} != "1.3" ; then + AC_MSG_RESULT([no]) + AC_MSG_WARN([FLTK 1.3 not found (available $FLTK_VERSION)]) + pinentry_fltk=no + else + AC_MSG_RESULT([yes]) + FLTKCFLAGS=`${FLTK_CONFIG} --cflags` + FLTKCXXFLAGS=`${FLTK_CONFIG} --cxxflags` + FLTKLIBS=`${FLTK_CONFIG} --ldflags` + AC_SUBST(FLTKCFLAGS) + AC_SUBST(FLTKCXXFLAGS) + AC_SUBST(FLTKLIBS) + pinentry_fltk=yes + fi +fi +AM_CONDITIONAL(BUILD_PINENTRY_FLTK, test "$pinentry_fltk" = "yes") # Figure out the default pinentry. We are very conservative here. # Please change the order only after verifying that the preferred @@ -611,7 +647,11 @@ else if test "$pinentry_w32" = "yes"; then PINENTRY_DEFAULT=pinentry-w32 else - AC_MSG_ERROR([[No pinentry enabled.]]) + if test "$pinentry_fltk" = "yes"; then + PINENTRY_DEFAULT=pinentry-fltk + else + AC_MSG_ERROR([[No pinentry enabled.]]) + fi fi fi fi @@ -690,6 +730,7 @@ gtk+-2/Makefile gnome3/Makefile qt/Makefile w32/Makefile +fltk/Makefile doc/Makefile Makefile ]) @@ -710,6 +751,7 @@ AC_MSG_NOTICE([ GNOME 3 Pinentry .: $pinentry_gnome_3 Qt Pinentry ......: $pinentry_qt $pinentry_qt_lib_version W32 Pinentry .....: $pinentry_w32 + FLTK Pinentry ....: $pinentry_fltk Fallback to Curses: $fallback_curses Emacs integration : $inside_emacs diff --git a/fltk/Makefile.am b/fltk/Makefile.am new file mode 100644 index 0000000..2c9338f --- /dev/null +++ b/fltk/Makefile.am @@ -0,0 +1,16 @@ +# Makefile.am - PIN entry FLTK frontend. + +bin_PROGRAMS = pinentry-fltk + +if FALLBACK_CURSES +ncurses_include = $(NCURSES_INCLUDE) +libcurses = ../pinentry/libpinentry-curses.a $(LIBCURSES) $(LIBICONV) +else +ncurses_include = +libcurses = +endif + +AM_CPPFLAGS = $(COMMON_CFLAGS) $(FLTKCXXFLAGS) $(ncurses_include) -I$(top_srcdir)/secmem -I$(top_srcdir)/pinentry +LDADD = ../pinentry/libpinentry.a ../secmem/libsecmem.a $(COMMON_LIBS) $(LIBCAP) $(FLTKLIBS) $(libcurses) + +pinentry_fltk_SOURCES = main.cxx pinwindow.cxx passwindow.cxx qualitypasswindow.cxx diff --git a/fltk/encrypt.xpm b/fltk/encrypt.xpm new file mode 100644 index 0000000..80402e3 --- /dev/null +++ b/fltk/encrypt.xpm @@ -0,0 +1,83 @@ +/* XPM */ +static const char * const encrypt_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 45 32 1 ", +" c #9B7738", +". c #B08830", +"X c #CA9703", +"o c #C99607", +"O c #CD9A02", +"+ c #D19D03", +"@ c #D4A002", +"# c #D7A305", +"$ c #D8A501", +"% c #DFAB01", +"& c #DCA803", +"* c #E3B103", +"= c #E7B702", +"- c #C39A31", +"; c #D4AC2F", +": c #E6BE26", +"> c #EFC002", +", c #F5CD06", +"< c #FEE21D", +"1 c #FCE01F", +"2 c #F6D424", +"3 c #B49A55", +"4 c #CAAC5F", +"5 c #FCE854", +"6 c #888887", +"7 c #9A9A9A", +"8 c #A7A7A7", +"9 c #B8B8B7", +"0 c #F3F08F", +"q c #C3C3C3", +"w c gray85", +"e c None", +/* pixels */ +"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", +"eeeeeeeeeee889qqqq987eeeeeeeeeee", +"eeeeeeeee89qwwwqqwwww88eeeeeeeee", +"eeeeeeee99qq877777669wq8eeeeeeee", +"eeeeeee99q888888888876ww9eeeeeee", +"eeeeee99q888888887778869q9eeeeee", +"eeeee89q8888eeeeeeee7786wq8eeeee", +"eeeee999888eeeeeeeeee7777wqeeeee", +"eeee899778eeeeeeeeeeee776wq8eeee", +"eeee8q977eeeeeeeeeeeeee779q9eeee", +"eeee8q977eeeeeeeeeeeeee777w9eeee", +"eeee8q867eeeeeeeeeeeeee776wqeeee", +"eeee8q768eeeeeeeeeeeeee766wqeeee", +"eeee8q768eeeeeeeeeeeeee766wqeeee", +"eeee8q778eeeeeeeeeeeeee776wqeeee", +"eeee8q778eeeeeeeeeeeeee776wqeeee", +"eeee8q888eeeeeeeeeeeeee786wqeeee", +"eeee8q888eeeeeeeeeeeeee786wqeeee", +"eeee8q898eeeeeeeeeeeeee796wqeeee", +"eeee8q898eeeeeeeeeeeeee896wqeeee", +"e45444443333 3333444003e", +"e4552::;;--... ...--;;:25003e", +"e4552,>>=&@OXXooXO+@$&*=>,15003e", +"e4552,>>*&#+ooooo++##&*=>,15003e", +"e4552,>>*&#+XXXXXO+@#&*=>,<5003e", +"e4552,>>=%$+OXXOO++##&*=>,15003e", +"e4552,>>=%$OooXXO+@@#&%=,,<5003e", +"e4552,>>=%$@OXXO+@@#&&*=>,15003e", +"e4552,>>*&$+XXXXOO++@#%=>,<5003e", +"e4552,>>=&$+OXXO++@@$&*=,,<5003e", +"e4552,>>=%$+XXXXOO+@#&*=>,<5003e", +"e4552,>>*&#+ooXO++@##&*>,,<5003e", +"e4552,>>=%$@OXXO++@$$%*>,,<5003e", +"e4552,>>=%$+OXXO++@#$&*=,,<5003e", +"e4552,>>=%$@OOOO++@$&%*=>,<5003e", +"e4552,>>=%$+OXXOO+@#&%=>,,<5003e", +"e4552,>>=%$+OXXOO+@##%*=>,<5003e", +"e4552,>>*&#+oooO++@#&&*>,,<5003e", +"e4552,>>=%$@OOOO+@$&%%*>,,<5003e", +"e4552,>>=%$@OOXO+@$&%%*>,,<5003e", +"e4552,>>=%$+OXXO+@$&&%*>,,<5003e", +"e4552,>>=%$@OOO+@@$&%%=>,,<5003e", +"e4552,>>=%$@OOO+@@$&%%=>,,<5003e", +"e4552,>>=%$@OOO+@@$&%%=>,,<5003e", +"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" +}; diff --git a/fltk/icon.xpm b/fltk/icon.xpm new file mode 100644 index 0000000..eed3cd6 --- /dev/null +++ b/fltk/icon.xpm @@ -0,0 +1,37 @@ +/* XPM */ +static const char *const icon_xpm[] = { +"31 29 3 1 ", +" c black", +". c yellow", +"X c None", + +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +" XXXXXXXXXXXXXXXXXX", +" ........... XXXXXXXXXXXXXXXXXX", +" ........... XXXXXXXXXXXXXXXXXX", +" ... ... XXXXXXXXXXXXXXXXXX", +" ... XXX ... ", +" ... XXX ... ................. ", +" ... XXX ... ................. ", +" ... XXX ... ... ... ", +" ... ... XXXXXXX ... X ... ", +" ........... XXXXXXX ... X ... ", +" ........... XXXXXXX X ... ", +" XXXXXXXXXXXXX ", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; diff --git a/fltk/main.cxx b/fltk/main.cxx new file mode 100644 index 0000000..7526656 --- /dev/null +++ b/fltk/main.cxx @@ -0,0 +1,391 @@ +/* + main.cpp - A Fltk based dialog for PIN entry. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define PGMNAME (PACKAGE_NAME"-fltk") + +#include +#include +#include +#include +#include +#include + +#include "memory.h" +#include + +#include +#ifdef FALLBACK_CURSES +#include +#endif + +#include +#include +#include + + +#include +#include +#include + +#include "pinwindow.h" +#include "passwindow.h" +#include "qualitypasswindow.h" + +#define CONFIRM_STRING "Confirm" +#define REPEAT_ERROR_STRING "Texts do not match" +#define OK_STRING "OK" +#define CANCEL_STRING "Cancel" + +char *application = NULL; + +static std::string escape_accel_utf8(const char *s) +{ + std::string result; + if (NULL != s) + { + result.reserve(strlen(s)); + for (const char *p = s; *p; ++p) + { + if ('&' == *p) + result.push_back(*p); + result.push_back(*p); + } + } + return result; +} + +class cancel_exception +{ + +}; + +static int get_quality(const char *passwd, void *ptr) +{ + if (NULL == passwd || 0 == *passwd) + return 0; + + pinentry_t* pe = reinterpret_cast(ptr); + return pinentry_inq_quality(*pe, passwd, strlen(passwd)); +} + +bool is_short(const char *str) +{ + return fl_utf_nb_char(reinterpret_cast(str), strlen(str)) < 16; +} + +bool is_empty(const char *str) +{ + return (NULL == str) || (0 == *str); +} + +static int fltk_cmd_handler(pinentry_t pe) +{ + int ret = -1; + + try + { + // TODO: Add parent window to pinentry-fltk window + //if (pe->parent_wid){} + std::string title = !is_empty(pe->title)?pe->title:PGMNAME; + std::string ok = escape_accel_utf8(pe->ok?pe->ok:(pe->default_ok?pe->default_ok:OK_STRING)); + std::string cancel = escape_accel_utf8(pe->cancel?pe->cancel:(pe->default_cancel?pe->default_cancel:CANCEL_STRING)); + + if (!!pe->pin) // password (or confirmation) + { + std::auto_ptr window; + + bool isSimple = (NULL == pe->quality_bar) && // pinenty.h: If this is not NULL ... + is_empty(pe->error) && is_empty(pe->description) && + is_short(pe->prompt); + if (isSimple) + { + assert(NULL == pe->description); + window.reset(PinWindow::create()); + window->prompt(pe->prompt); + } + else + { + PassWindow *pass = NULL; + + if (pe->quality_bar) // pinenty.h: If this is not NULL ... + { + QualityPassWindow *p = QualityPassWindow::create(get_quality, &pe); + window.reset(p); + pass = p; + p->quality(pe->quality_bar); + } + else + { + pass = PassWindow::create(); + window.reset(pass); + } + + if (NULL == pe->description) + { + pass->description(pe->prompt); + pass->prompt(" "); + } + else + { + pass->description(pe->description); + pass->prompt(escape_accel_utf8(pe->prompt).c_str()); + } + pass->description(pe->description); + pass->prompt(escape_accel_utf8(pe->prompt).c_str()); + + + if (NULL != pe->error) + pass->error(pe->error); + } + + window->ok(ok.c_str()); + window->cancel(cancel.c_str()); + window->title(title.c_str()); + window->showModal((NULL != application)?1:0, &application); + + if (NULL == window->passwd()) + throw cancel_exception(); + + const std::string password = window->passwd(); + window.reset(); + + if (pe->repeat_passphrase) + { + const char *dont_match = NULL; + do + { + if (NULL == dont_match && is_short(pe->repeat_passphrase)) + { + window.reset(PinWindow::create()); + window->prompt(escape_accel_utf8(pe->repeat_passphrase).c_str()); + } + else + { + PassWindow *pass = PassWindow::create(); + window.reset(pass); + pass->description(pe->repeat_passphrase); + pass->prompt(" "); + pass->error(dont_match); + } + + window->ok(ok.c_str()); + window->cancel(cancel.c_str()); + window->title(title.c_str()); + window->showModal(); + + if (NULL == window->passwd()) + throw cancel_exception(); + + if (password == window->passwd()) + { + pe->repeat_okay = 1; + ret = 1; + break; + } + else + { + dont_match = (NULL!=pe->repeat_error_string)? pe->repeat_error_string:REPEAT_ERROR_STRING; + } + } while (true); + } + else + ret = 1; + + pinentry_setbufferlen(pe, password.size()+1); + if (pe->pin) + { + memcpy(pe->pin, password.c_str(), password.size()+1); + pe->result = password.size(); + ret = password.size(); + } + } + else + { + // Confirmation or Message Dialog title, desc + Fl_Window dummy(0,0, 1,1); + + dummy.border(0); + dummy.show((NULL != application)?1:0, &application); + dummy.hide(); + + fl_message_title(title.c_str()); + + int result = -1; + + const char *message = (NULL != pe->description)?pe->description:CONFIRM_STRING; + + if (pe->one_button) + { + fl_ok = ok.c_str(); + fl_message(message); + result = 1; // OK + } + else if (pe->notok) + { + switch (fl_choice(message, ok.c_str(), cancel.c_str(), pe->notok)) + { + case 0: result = 1; break; + case 2: result = 0; break; + default: + case 1: result = -1;break; + } + } + else + { + switch (fl_choice(message, ok.c_str(), cancel.c_str(), NULL)) + { + case 0: result = 1; break; + default: + case 1: result = -1;break; + } + } + + // cancel -> pe->canceled = true, 0 + // ok/y -> 1 + // no -> 0 + if (-1 == result) + pe->canceled = true; + ret = (1 == result); + } + Fl::check(); + } + catch (const cancel_exception&) + { + ret = -1; + } + catch (...) + { + ret = -1; + } + // do_touch_file(pe); only for NCURSES? + return ret; + } + +pinentry_cmd_handler_t pinentry_cmd_handler = fltk_cmd_handler; + +int main(int argc, char *argv[]) +{ + application = *argv; + pinentry_init(PGMNAME); + +#ifdef FALLBACK_CURSES + if (!pinentry_have_display(argc, argv)) + pinentry_cmd_handler = curses_cmd_handler; + else +#endif + { + //FLTK understood only -D (--display) + // and should be converted into -di[splay] + const static struct option long_options[] = + { + {"display", required_argument, 0, 'D' }, + {NULL, no_argument, 0, 0 } + }; + + for (int i = 0; i < argc-1; ++i) + { + switch (getopt_long(argc-i, argv+i, "D:", long_options, NULL)) + { + case 'D': + { + char* emul[] = {application, (char*)"-display", optarg}; + Fl::args(3, emul); + i = argc; + break; + } + default: + break; + } + } + } + + pinentry_parse_opts(argc, argv); + return pinentry_loop() ?EXIT_FAILURE:EXIT_SUCCESS; +} + +/* +int get_quality(const char *pass) +{ + size_t len = strlen(pass); + return len>4?(80+len):-len*10; +} + +int main(int argc, char *argv[]) +{ + std::auto_ptr window; + window.reset(QualityPassWindow::create(get_quality)); + +// window->message("Lorem ipsum dolor sit amet"); +// window->message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor. Phasellus tempor orci vel metus eleifend ultrices. Curabitur tempor euismod lorem"); + window->prompt("Lorem ipsum:"); + window->ok("YES!"); + window->cancel("OTMEHA"); +// window->error("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla"); +// window->error("Some error ellus adipiscing elit portt text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor a porttitor!"); + window->timeout(100); + window->title(PGMNAME); + window->showModal(argc, argv); + return 0; +} +// */ + +/* +int main(int argc, char *argv[]) +{ + Fl::args(argc, argv); + std::auto_ptr window; + window.reset(PinWindow::create()); +// window->message("PIN:"); +// window->message("Phasellus adipiscing elit porttitor nisi a fringilla porttitor:"); + window->ok("YES!"); + window->cancel("OTMEHA"); + window->timeout(100); + window->title(PGMNAME); + window->showModal(argc, argv); + return 0; +} +// */ + +/* +int main(int argc, char *argv[]) +{ + Fl::args(argc, argv); + std::auto_ptr window; + window.reset(PassWindow::create()); +// window->message("Descr&iption"); +// window->message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor:"); +// window->prompt("Prompt sit amet:"); + window->ok("YES!"); + window->cancel("OTMEHA"); +// window->error("Password is empty."); +// window->error("Some error text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor!"); +// window->error("Some error ellus adipiscing elit portt text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor!"); + window->timeout(100); + window->title(PGMNAME); + window->showModal(argc, argv); + return 0; +} +// */ diff --git a/fltk/passwindow.cxx b/fltk/passwindow.cxx new file mode 100644 index 0000000..78b3b2c --- /dev/null +++ b/fltk/passwindow.cxx @@ -0,0 +1,85 @@ +/* + passwindow.cxx - PassWindow is a more complex fltk dialog with more longer + desc field and possibility to show some error text. + if needed qualitybar - should be used QualityPassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "passwindow.h" + +#include +#include +#include + +const char *PassWindow::DESCRIPTION = "Please enter the passphrase:"; + +PassWindow::PassWindow() : error_(NULL) +{ +} + +void PassWindow::prompt(const char *name) +{ + set_label(input_, name, PROMPT); +} + +void PassWindow::description(const char *name) +{ + set_label(message_, name, DESCRIPTION); +} + +void PassWindow::error(const char *name) +{ + set_label(error_, name, ""); +} + +int PassWindow::init(const int cx, const int cy) +{ + int y = PinWindow::init(cx, cy); + + assert(window_ == Fl_Group::current()); // make_window should all add current + + y = icon_->y(); // move back to icon's + + const int mx = icon_->x()+icon_->w(); + message_->resize(mx, icon_->y(), cx-mx-10, icon_->h()); + message_->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); + description(NULL); + y += icon_->h(); + + input_->resize(130, y+5, cx-150, 25); + input_->labeltype(FL_NORMAL_LABEL); + prompt(NULL); + y = input_->y()+input_->h(); + + error_ = new Fl_Box(20, y+5, cx-30, 30); + error_->labelcolor(FL_RED); + error_->align(Fl_Align(FL_ALIGN_CENTER | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); // if not fit - user can read + y = error_->y()+error_->h(); + return y; +} + +PassWindow* PassWindow::create() +{ + PassWindow* p = new PassWindow; + p->init(460, 185); + p->window_->end(); + p->input_->take_focus(); + return p; +} diff --git a/fltk/passwindow.h b/fltk/passwindow.h new file mode 100644 index 0000000..43813cd --- /dev/null +++ b/fltk/passwindow.h @@ -0,0 +1,50 @@ +/* + passwindow.h - PassWindow is a more complex fltk dialog with more longer + desc field and possibility to show some error text. + if needed qualitybar - should be used QualityPassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __PASSWINDOW_H__ +#define __PASSWINDOW_H__ + +#include "pinwindow.h" + +class PassWindow : public PinWindow +{ +protected: + static const char *DESCRIPTION; + +protected: + Fl_Box *error_; + PassWindow(); + +public: + virtual void prompt(const char *message); + virtual void description(const char *desc); + virtual void error(const char *err); + + static PassWindow* create(); + +protected: + virtual int init(const int cx, const int cy); +}; + +#endif //#ifndef __PASSWINDOW_H__ diff --git a/fltk/pinwindow.cxx b/fltk/pinwindow.cxx new file mode 100644 index 0000000..ad11e91 --- /dev/null +++ b/fltk/pinwindow.cxx @@ -0,0 +1,250 @@ +/* + pinwindow.cxx - PinWindow is a simple fltk dialog for entring password + with timeout. if needed description (long text), error message, qualitybar + and etc should used PassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "memory.h" + +#include "encrypt.xpm" +#include "icon.xpm" + +#include "pinwindow.h" + +const char *PinWindow::TITLE = "Password"; +const char *PinWindow::BUTTON_OK = "OK"; +const char *PinWindow::BUTTON_CANCEL = "Cancel"; +const char *PinWindow::PROMPT = "Passphrase:"; + +static const char *timeout_format = "%s(%d)"; + +static Fl_Pixmap encrypt(encrypt_xpm); +static Fl_Pixmap icon(icon_xpm); + +PinWindow::PinWindow() : window_(NULL) + ,message_(NULL) ,input_(NULL) ,ok_(NULL) ,cancel_(NULL) + ,cancel_name_(BUTTON_CANCEL) + ,passwd_(NULL) ,timeout_(0) +{ +} + +PinWindow::~PinWindow() +{ + wipe(); + release(); + delete window_; +} + +void PinWindow::release() +{ + if (NULL != passwd_) + { + memset(passwd_, 0, strlen(passwd_)); + secmem_free(passwd_); + } + passwd_ = NULL; +} + +void PinWindow::title(const char *name) +{ + set_label(window_, name, TITLE); +} + +void PinWindow::ok(const char* name) +{ + set_label(ok_, name, BUTTON_OK); +} + +void PinWindow::cancel(const char* label) +{ + if (NULL != label && 0 != *label) + cancel_name_ = label; + else + cancel_name_ = BUTTON_CANCEL; + + update_cancel_label(); +} + +void PinWindow::prompt(const char *name) +{ + set_label(message_, name, PROMPT); +} + +void PinWindow::timeout(unsigned int time) +{ + if (timeout_ == time) + return; + + // A xor B ~ A != B + if ( (time>0) != (timeout_>0)) + { + //enable or disable + if (time>0) + Fl::add_timeout(1.0, timeout_cb, this); + else + Fl::remove_timeout(timeout_cb, this); + } + + timeout_=time; + update_cancel_label(); + --timeout_; +} + +void PinWindow::showModal() +{ + if (NULL != window_) + { + window_->show(); + Fl::run(); + } + Fl::check(); +} + +void PinWindow::showModal(const int argc, char* argv[]) +{ + if (NULL != window_) + { + window_->show(argc, argv); + Fl::run(); + } + Fl::check(); +} + +int PinWindow::init(const int cx, const int cy) +{ + assert(NULL == window_); + window_ = new Fl_Window(cx, cy, TITLE); + + Fl_RGB_Image app(&icon); + window_->icon(&app); + + icon_ = new Fl_Box(10, 10, 64, 64); + icon_->image(encrypt); + + message_ = new Fl_Box(79, 5, cx-99, 44, PROMPT); + message_->align(Fl_Align(FL_ALIGN_LEFT_TOP | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); // left + + input_ = new Fl_Secret_Input(79, 59, cx-99, 25); + input_->labeltype(FL_NO_LABEL); + + + const int button_y = cy-40; + ok_ = new Fl_Return_Button(cx-300, button_y, 120, 25, BUTTON_OK); + ok_->callback(ok_cb, this); + + cancel_ = new Fl_Button(cx-160, button_y, 120, 25); + update_cancel_label(); + cancel_->callback(cancel_cb, this); + + window_->hotspot(input_); + window_->set_modal(); + + return 84; +}; + +void PinWindow::update_cancel_label() +{ + if (timeout_ == 0) + { + cancel_->label(cancel_name_.c_str()); + } + else + { + const size_t len = cancel_name_.size()+strlen(timeout_format)+10+1; + char *buf = new char[len]; + snprintf(buf, len, timeout_format, cancel_name_.c_str(), timeout_); + cancel_->copy_label(buf); + delete[] buf; // no way to attach label + } +} + +void PinWindow::timeout_cb(void* val) +{ + PinWindow *self = reinterpret_cast(val); + if (self->timeout_ == 0) + { + cancel_cb(self->cancel_, self); + } + else + { + self->update_cancel_label(); + --self->timeout_; + Fl::repeat_timeout(1.0, timeout_cb, val); + } +} + +void PinWindow::cancel_cb(Fl_Widget *button, void *val) +{ + PinWindow *self = reinterpret_cast(val); + + self->wipe(); + self->release(); + self->window_->hide(); +} + +void PinWindow::ok_cb(Fl_Widget *button, void *val) +{ + PinWindow *self = reinterpret_cast(val); + + self->release(); + + const char *passwd = self->input_->value(); + size_t len = strlen(passwd)+1; + self->passwd_ = reinterpret_cast(secmem_malloc(len)); + if (NULL != self->passwd_) + memcpy(self->passwd_, passwd, len); + + self->wipe(); + self->window_->hide(); +} + +void PinWindow::wipe() +{ + int len = input_->size(); + char* emul = new char[len+1]; + for (int i=0; ireplace(0, len, emul, len); + delete[] emul; + + input_->value(TITLE); // hide size too +} + +PinWindow* PinWindow::create() +{ + PinWindow* p = new PinWindow; + p->init(410, 140); + p->window_->end(); + p->input_->take_focus(); + return p; +} diff --git a/fltk/pinwindow.h b/fltk/pinwindow.h new file mode 100644 index 0000000..e1d009e --- /dev/null +++ b/fltk/pinwindow.h @@ -0,0 +1,108 @@ +/* + pinwindow.h - PinWindow is a simple fltk dialog for entring password + with timeout. if needed description (long text), error message, qualitybar + and etc should used PassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __PINWINDOW_H__ +#define __PINWINDOW_H__ + +#include "config.h" + +class Fl_Window; +class Fl_Box; +class Fl_Input; +class Fl_Button; +class Fl_Widget; + +#include +#include + +class PinWindow +{ +protected: + static const char *TITLE; + static const char *BUTTON_OK; + static const char *BUTTON_CANCEL; + static const char *PROMPT; + +protected: + PinWindow(const PinWindow&); + PinWindow& operator=(const PinWindow&); + + Fl_Window *window_; + Fl_Box *icon_; + + Fl_Box *message_; + Fl_Input *input_; + + Fl_Button *ok_, *cancel_; + + std::string cancel_name_; + char *passwd_; // SECURE_MEMORY + unsigned int timeout_; // click cancel if timeout + +public: + virtual ~PinWindow(); + + static PinWindow* create(); + + inline const char* passwd() const { return passwd_; } + + virtual void timeout(unsigned int time); // 0 - infinity, seconds + virtual void title(const char *title); + virtual void ok(const char* ok); + virtual void cancel(const char* cancel); + virtual void prompt(const char *message); + + virtual void showModal(); + virtual void showModal(const int argc, char* argv[]); + +protected: + PinWindow(); + + void wipe(); // clear UI memory + void release(); // clear secure memory + void update_cancel_label(); + + virtual int init(const int cx, const int cy); + + //callbacks + static void cancel_cb(Fl_Widget *button, void *val); + static void ok_cb(Fl_Widget *button, void *val); + static void timeout_cb(void*); + + // ISSUE: Fl_Window component in tinycore works only as Fl_Window::label(...); not Fl_Widget + template void set_label(TWidget* widget, const char *label, const char *def) + { + assert(NULL != widget); // widget must be created + + if (NULL != widget) + { + if (NULL != label && 0 != *label) + widget->copy_label(label); + else + widget->label(def); + } + }; +}; + +#endif //#ifndef __PINWINDOW_H__ diff --git a/fltk/qualitypasswindow.cxx b/fltk/qualitypasswindow.cxx new file mode 100644 index 0000000..6d7f7cc --- /dev/null +++ b/fltk/qualitypasswindow.cxx @@ -0,0 +1,92 @@ +/* + qualitypasswindow.cxx - QualityPassWindow pin entry + with Password QualityBar and etc + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include "qualitypasswindow.h" + +const char *QualityPassWindow::QUALITY = "Quality"; + +QualityPassWindow::QualityPassWindow(QualityPassWindow::GetQualityFn qualify, void* ptr) + : get_quality_(qualify) + ,get_quality_user_(ptr) + ,quality_(NULL) +{ + assert(NULL != qualify); +} + +void QualityPassWindow::input_changed(Fl_Widget *input, void *val) +{ + QualityPassWindow *self = reinterpret_cast(val); + + assert(NULL != self->get_quality_); // function should be assigned in ctor + assert(NULL != self->quality_); // quality progress bar must be created in init + + if (NULL != self->quality_ && NULL != self->get_quality_) + { + int result = self->get_quality_(self->input_->value(), self->get_quality_user_); + bool isErr = (result <= 0); + if (isErr) + result = -result; + self->quality_->selection_color(isErr?FL_RED:FL_GREEN); + self->quality_->value(std::min(result, 100)); + } +} + +QualityPassWindow* QualityPassWindow::create(QualityPassWindow::GetQualityFn qualify, void *user) +{ + QualityPassWindow *p = new QualityPassWindow(qualify, user); + p->init(460, 215); + p->window_->end(); + p->input_->take_focus(); + return p; +} + +void QualityPassWindow::quality(const char *name) +{ + set_label(quality_, name, QUALITY); +} + +int QualityPassWindow::init(const int cx, const int cy) +{ + int y = PassWindow::init(cx, cy); + assert(window_ == Fl_Group::current()); // make_window should all add current + + input_->when(FL_WHEN_CHANGED); + input_->callback(input_changed, this); + + y = input_->y() + input_->h(); + + quality_ = new Fl_Progress(input_->x(), y+5, input_->w(), 25, QUALITY); + quality_->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP | FL_ALIGN_WRAP)); + quality_->maximum(100.1); + quality_->minimum(0.0); + y = quality_->y() + quality_->h(); + + error_->position(error_->x(), y+5); + + return error_->y() + error_->h(); +} diff --git a/fltk/qualitypasswindow.h b/fltk/qualitypasswindow.h new file mode 100644 index 0000000..164c10d --- /dev/null +++ b/fltk/qualitypasswindow.h @@ -0,0 +1,54 @@ +/* + qualitypasswindow.h - QualityPassWindow pin entry with Password QualityBar + and etc + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __QUALITYPASSWINDOW_H__ +#define __QUALITYPASSWINDOW_H__ + +#include "passwindow.h" +class Fl_Progress; + +class QualityPassWindow : public PassWindow +{ +protected: + static const char *QUALITY; + +public: + typedef int (*GetQualityFn)(const char *passwd, void *ptr); + + static QualityPassWindow* create(GetQualityFn qualify, void* user); + + void quality(const char *name); + +protected: + QualityPassWindow(GetQualityFn qualify, void*); + + const GetQualityFn get_quality_; + void* const get_quality_user_; + + Fl_Progress *quality_; + virtual int init(const int cx, const int cy); + + static void input_changed(Fl_Widget *input, void *val); +}; + +#endif //#ifndef __QUALITYPASSWINDOW_H__ ----------------------------------------------------------------------- hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 8 14:36:05 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 08 Feb 2017 14:36:05 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-66-g6823ed4 Message-ID: This is an 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 6823ed46584e753de3aba48a00ab738ab009a860 (commit) from 56aa85f88f6b35fb03a2dc1a95882d49a74290e3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6823ed46584e753de3aba48a00ab738ab009a860 Author: Justus Winter Date: Wed Feb 8 13:49:41 2017 +0100 gpg,common: Make sure that all fd given are valid. * common/sysutils.c (gnupg_fd_valid): New function. * common/sysutils.h (gnupg_fd_valid): New declaration. * common/logging.c (log_set_file): Use the new function. * g10/cpr.c (set_status_fd): Likewise. * g10/gpg.c (main): Likewise. * g10/keylist.c (read_sessionkey_from_fd): Likewise. * g10/passphrase.c (set_attrib_fd): Likewise. * tests/openpgp/Makefile.am (XTESTS): Add the new test. * tests/openpgp/issue2941.scm: New file. -- Consider a situation where the user passes "--status-fd 3" but file descriptor 3 is not open. During the course of executing the rest of the commands, it's possible that gpg itself will open some files, and file descriptor 3 will get allocated. In this situation, the status information will be appended directly to whatever file happens to have landed on fd 3 (the trustdb? the keyring?). This is a potential data destruction issue for all writable file descriptor options: --status-fd --attribute-fd --logger-fd It's also a potential issue for readable file descriptor options, but the risk is merely weird behavior, and not data corruption: --override-session-key-fd --passphrase-fd --command-fd Fixes this by checking whether the fd is valid early on before using it. GnuPG-bug-id: 2941 Signed-off-by: Justus Winter diff --git a/common/logging.c b/common/logging.c index 8c70742..ac13053 100644 --- a/common/logging.c +++ b/common/logging.c @@ -570,6 +570,9 @@ log_set_file (const char *name) void log_set_fd (int fd) { + if (! gnupg_fd_valid (fd)) + log_fatal ("logger-fd is invalid: %s\n", strerror (errno)); + set_file_fd (NULL, fd); } diff --git a/common/sysutils.c b/common/sysutils.c index e67420f..a796677 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1281,3 +1281,14 @@ gnupg_get_socket_name (int fd) return name; } #endif /*!HAVE_W32_SYSTEM*/ + +/* Check whether FD is valid. */ +int +gnupg_fd_valid (int fd) +{ + int d = dup (fd); + if (d < 0) + return 0; + close (d); + return 1; +} diff --git a/common/sysutils.h b/common/sysutils.h index a9316d7..ecd9f84 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -72,6 +72,7 @@ int gnupg_setenv (const char *name, const char *value, int overwrite); int gnupg_unsetenv (const char *name); char *gnupg_getcwd (void); char *gnupg_get_socket_name (int fd); +int gnupg_fd_valid (int fd); gpg_error_t gnupg_inotify_watch_socket (int *r_fd, const char *socket_name); int gnupg_inotify_has_name (int fd, const char *name); diff --git a/g10/cpr.c b/g10/cpr.c index 0133cad..4984e89 100644 --- a/g10/cpr.c +++ b/g10/cpr.c @@ -107,6 +107,9 @@ set_status_fd (int fd) if (fd == -1) return; + if (! gnupg_fd_valid (fd)) + log_fatal ("status-fd is invalid: %s\n", strerror (errno)); + if (fd == 1) statusfp = es_stdout; else if (fd == 2) diff --git a/g10/gpg.c b/g10/gpg.c index e280c22..66a2055 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3079,6 +3079,8 @@ main (int argc, char **argv) case oCommandFD: opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); + if (! gnupg_fd_valid (opt.command_fd)) + log_fatal ("command-fd is invalid: %s\n", strerror (errno)); break; case oCommandFile: opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1); @@ -5293,6 +5295,9 @@ read_sessionkey_from_fd (int fd) int i, len; char *line; + if (! gnupg_fd_valid (fd)) + log_fatal ("override-session-key-fd is invalid: %s\n", strerror (errno)); + for (line = NULL, i = len = 100; ; i++ ) { if (i >= len-1 ) diff --git a/g10/keylist.c b/g10/keylist.c index 4fe1e40..abdcb9f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1900,6 +1900,9 @@ set_attrib_fd (int fd) if (fd == -1) return; + if (! gnupg_fd_valid (fd)) + log_fatal ("attribute-fd is invalid: %s\n", strerror (errno)); + #ifdef HAVE_DOSISH_SYSTEM setmode (fd, O_BINARY); #endif diff --git a/g10/passphrase.c b/g10/passphrase.c index fb4ec4c..37abc0f 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -166,6 +166,9 @@ read_passphrase_from_fd( int fd ) int i, len; char *pw; + if (! gnupg_fd_valid (fd)) + log_fatal ("passphrase-fd is invalid: %s\n", strerror (errno)); + if ( !opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK) { /* Not used but we have to do a dummy read, so that it won't end up at the begin of the message if the quite usual trick to diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 5cab3d5..afac58f 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -97,7 +97,8 @@ XTESTS = \ issue2346.scm \ issue2417.scm \ issue2419.scm \ - issue2929.scm + issue2929.scm \ + issue2941.scm # XXX: Currently, one cannot override automake's 'check' target. As a # workaround, we avoid defining 'TESTS', thus automake will not emit diff --git a/tests/openpgp/issue2941.scm b/tests/openpgp/issue2941.scm new file mode 100755 index 0000000..d7220e0 --- /dev/null +++ b/tests/openpgp/issue2941.scm @@ -0,0 +1,34 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2017 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see . + +(load (with-path "defs.scm")) +(setup-legacy-environment) + +(define (check-failure options) + (let ((command `(, at gpg , at options))) + (catch '() + (call-check command) + (error "Expected an error, but got none when executing" command)))) + +(for-each-p + "Checking invocation with invalid file descriptors (issue2941)." + (lambda (option) + (check-failure `(,(string-append "--" option "=23") --sign gpg.conf))) + '("status-fd" "attribute-fd" "logger-fd" + "override-session-key-fd" "passphrase-fd" "command-fd")) ----------------------------------------------------------------------- Summary of changes: common/logging.c | 3 +++ common/sysutils.c | 11 +++++++++ common/sysutils.h | 1 + g10/cpr.c | 3 +++ g10/gpg.c | 5 ++++ g10/keylist.c | 3 +++ g10/passphrase.c | 3 +++ tests/openpgp/Makefile.am | 3 ++- .../{encrypt-multifile.scm => issue2941.scm} | 27 +++++++++------------- 9 files changed, 42 insertions(+), 17 deletions(-) copy tests/openpgp/{encrypt-multifile.scm => issue2941.scm} (61%) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 9 18:34:12 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Thu, 09 Feb 2017 18:34:12 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-67-g8810314 Message-ID: This is an 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 8810314e377a9cb6612150a57cf99260ed0bb9f6 (commit) from 6823ed46584e753de3aba48a00ab738ab009a860 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8810314e377a9cb6612150a57cf99260ed0bb9f6 Author: Daniel Kahn Gillmor Date: Wed Feb 8 12:05:08 2017 -0500 common: Avoid warning about implicit declaration of gnupg_fd_valid. * common/logging.c: Add #include "sysutils.h". -- Without this, we see: logging.c:573:9: warning: implicit declaration of function \ ?gnupg_fd_valid? [-Wimplicit-function-declaration] if (! gnupg_fd_valid (fd)) ^~~~~~~~~~~~~~ Signed-off-by: Daniel Kahn Gillmor diff --git a/common/logging.c b/common/logging.c index ac13053..670affb 100644 --- a/common/logging.c +++ b/common/logging.c @@ -61,6 +61,7 @@ #include "i18n.h" #include "common-defs.h" #include "logging.h" +#include "sysutils.h" #ifdef HAVE_W32_SYSTEM # define S_IRGRP S_IRUSR ----------------------------------------------------------------------- Summary of changes: common/logging.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 10 18:05:53 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 10 Feb 2017 18:05:53 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-68-g5996c7b Message-ID: This is an 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 5996c7bf99f3a681393fd9589276399ebc956cff (commit) from 8810314e377a9cb6612150a57cf99260ed0bb9f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5996c7bf99f3a681393fd9589276399ebc956cff Author: Werner Koch Date: Fri Feb 10 17:16:07 2017 +0100 gpg: Fix memory leak in the error case of signature creation. * g10/sign.c (write_signature_packets): Free SIG. Also replace xcalloc by xtrycalloc. -- If do_sign fails SIG was not released. Note that in the good case SIG is transferred to PKT and freed by free_packet. Reported-by: Stephan M?ller Signed-off-by: Werner Koch diff --git a/g10/sign.c b/g10/sign.c index acc894c..ff099b3 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -686,7 +686,10 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash, pk = sk_rover->pk; /* Build the signature packet. */ - sig = xmalloc_clear (sizeof *sig); + sig = xtrycalloc (1, sizeof *sig); + if (!sig) + return gpg_error_from_syserror (); + if (duration || opt.sig_policy_url || opt.sig_notations || opt.sig_keyserver_url) sig->version = 4; @@ -731,8 +734,12 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash, print_status_sig_created (pk, sig, status_letter); free_packet (&pkt); if (rc) - log_error ("build signature packet failed: %s\n", gpg_strerror (rc)); + log_error ("build signature packet failed: %s\n", + gpg_strerror (rc)); } + else + xfree (sig); + if (rc) return rc; } ----------------------------------------------------------------------- Summary of changes: g10/sign.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 03:24:51 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 13 Feb 2017 03:24:51 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-69-gda4c132 Message-ID: This is an 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 da4c132cca2c6df81243c9660b7348268a848f88 (commit) from 5996c7bf99f3a681393fd9589276399ebc956cff (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit da4c132cca2c6df81243c9660b7348268a848f88 Author: NIIBE Yutaka Date: Mon Feb 13 11:09:13 2017 +0900 scd: Fix use case of PC/SC. * scd/apdu.c (apdu_open_reader): Add an argument APP_EMPTY. When CCID driver fails to open, try PC/SC if APP is nothing. * scd/app.c (select_application): Supply arg if APP is nothing. -- After scanning available card readers by CCID driver, scdaemon should try PC/SC service if no APP is registered yet. Also, when the slot is allocated for PC/SC (ccid.handle==NULL), it should not call ccid_compare_BAI, otherwise scdaemon crashes. Debian-bug-id: 852702, 854005, 854595, 854616 Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.c b/scd/apdu.c index 6fc62aa..82d53b1 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -3127,7 +3127,7 @@ apdu_open_one_reader (const char *portstr) } int -apdu_open_reader (struct dev_list *dl) +apdu_open_reader (struct dev_list *dl, int app_empty) { int slot; @@ -3177,6 +3177,7 @@ apdu_open_reader (struct dev_list *dl) /* Check identity by BAI against already opened HANDLEs. */ for (slot = 0; slot < MAX_READER; slot++) if (reader_table[slot].used + && reader_table[slot].ccid.handle && ccid_compare_BAI (reader_table[slot].ccid.handle, bai)) break; @@ -3201,12 +3202,19 @@ apdu_open_reader (struct dev_list *dl) dl->idx++; } - slot = -1; + /* Not found. Try one for PC/SC, only when it's the initial scan. */ + if (app_empty && dl->idx == dl->idx_max) + { + dl->idx++; + slot = apdu_open_one_reader (dl->portstr); + } + else + slot = -1; } else #endif { /* PC/SC readers. */ - if (dl->idx == 0) + if (app_empty && dl->idx == 0) { dl->idx++; slot = apdu_open_one_reader (dl->portstr); diff --git a/scd/apdu.h b/scd/apdu.h index 473def5..6751e8c 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -91,7 +91,7 @@ gpg_error_t apdu_dev_list_start (const char *portstr, struct dev_list **l_p); void apdu_dev_list_finish (struct dev_list *l); /* Note, that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (struct dev_list *l); +int apdu_open_reader (struct dev_list *l, int app_empty); int apdu_open_remote_reader (const char *portstr, const unsigned char *cookie, size_t length, int (*readfnc) (void *opaque, diff --git a/scd/app.c b/scd/app.c index 5b8da1c..7e72870 100644 --- a/scd/app.c +++ b/scd/app.c @@ -343,7 +343,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app, int slot; int periodical_check_needed_this; - slot = apdu_open_reader (l); + slot = apdu_open_reader (l, !app_top); if (slot < 0) break; ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 14 +++++++++++--- scd/apdu.h | 2 +- scd/app.c | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 10:21:27 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 13 Feb 2017 10:21:27 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-70-gf8ce31a Message-ID: This is an 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 f8ce31a7bf1ee85e5010b628a66e6f69486e5213 (commit) from da4c132cca2c6df81243c9660b7348268a848f88 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f8ce31a7bf1ee85e5010b628a66e6f69486e5213 Author: Justus Winter Date: Mon Feb 13 10:18:45 2017 +0100 g13: Fix build on macOS. * g13/Makefile.am (t_common_ldadd): Add iconv. Signed-off-by: Justus Winter diff --git a/g13/Makefile.am b/g13/Makefile.am index c0e7a71..cc0e6a8 100644 --- a/g13/Makefile.am +++ b/g13/Makefile.am @@ -70,7 +70,7 @@ g13_syshelp_LDADD = $(libcommon) \ module_tests = t-g13tuple t_common_ldadd = $(libcommon) $(LIBGCRYPT_LIBS) \ - $(LIBASSUAN_LIBS) + $(LIBASSUAN_LIBS) $(LIBICONV) t_g13tuple_SOURCES = t-g13tuple.c g13tuple.c t_g13tuple_LDADD = $(t_common_ldadd) ----------------------------------------------------------------------- Summary of changes: g13/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 Feb 13 10:37:46 2017 From: cvs at cvs.gnupg.org (by Igor Gnatenko) Date: Mon, 13 Feb 2017 10:37:46 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-58-g60064c6 Message-ID: This is an 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 60064c665ec98a2a994fc6c8ad701e60b963ce7e (commit) from 903bf16a416b1bf608b1e647937c9b06864b0141 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 60064c665ec98a2a994fc6c8ad701e60b963ce7e Author: Igor Gnatenko Date: Sat Feb 11 08:36:24 2017 +0100 qt: Add missing #include * lang/qt/src/qgpgmenewcryptoconfig.cpp, lang/qt/src/threadedjobmixin.h: Include functional. -- With GCC 7.0, functional is not included transitively and we get: In file included from qgpgmedeletejob.h:39:0, from qgpgmedeletejob.cpp:38: threadedjobmixin.h:98:33: error: 'function' in namespace 'std' does not name a template type void setFunction(const std::function &function) ^~~~~~~~ std::{function,bind,placeholders,mem_fn} are defined in functional. References: https://bugzilla.redhat.com/show_bug.cgi?id=1417383 Signed-off-by: Igor Gnatenko GnuPG-Bug-Id: 2955 Commit Message amended by Andre Heinecke Signed-off-by: Andre Heinecke diff --git a/lang/qt/src/qgpgmenewcryptoconfig.cpp b/lang/qt/src/qgpgmenewcryptoconfig.cpp index 4738a03..6901eef 100644 --- a/lang/qt/src/qgpgmenewcryptoconfig.cpp +++ b/lang/qt/src/qgpgmenewcryptoconfig.cpp @@ -49,6 +49,7 @@ #include #include #include +#include using namespace QGpgME; using namespace GpgME; diff --git a/lang/qt/src/threadedjobmixin.h b/lang/qt/src/threadedjobmixin.h index 32b23db..5ad2737 100644 --- a/lang/qt/src/threadedjobmixin.h +++ b/lang/qt/src/threadedjobmixin.h @@ -51,6 +51,7 @@ #include "job.h" #include +#include namespace QGpgME { ----------------------------------------------------------------------- Summary of changes: lang/qt/src/qgpgmenewcryptoconfig.cpp | 1 + lang/qt/src/threadedjobmixin.h | 1 + 2 files changed, 2 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 12:01:59 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 13 Feb 2017 12:01:59 +0100 Subject: [git] gnupg-doc - branch, master, updated. d37ee56b510b20300bee5a7ffe70e3204e93c160 Message-ID: This is an 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 d37ee56b510b20300bee5a7ffe70e3204e93c160 (commit) from 706f736fdbc9ef00d6606a45e73bf5169e9ce4ea (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d37ee56b510b20300bee5a7ffe70e3204e93c160 Author: Justus Winter Date: Mon Feb 13 12:00:57 2017 +0100 jenkins: fix GPGMEs tests on OpenBSD diff --git a/misc/jenkins/bin/build.bash b/misc/jenkins/bin/build.bash index 88c8032..3dbc58b 100755 --- a/misc/jenkins/bin/build.bash +++ b/misc/jenkins/bin/build.bash @@ -104,14 +104,14 @@ case "$JOB_NAME" in # Disable NTBTLS for now until it is actually mature and used. CONFIGUREFLAGS="$CONFIGUREFLAGS --disable-ntbtls" - - # The libraries use rpath when linking the tests, so they - # locate their dependencies that way. GnuPG, however, does - # not. Therefore, we set LD_LIBRARY_PATH. - test_environment="LD_LIBRARY_PATH=$ORIGINAL_PREFIX/lib" ;; esac +# The libraries use rpath when linking the tests, so they locate their +# dependencies that way. GnuPG, however, does not. Therefore, we set +# LD_LIBRARY_PATH. +test_environment="LD_LIBRARY_PATH=$ORIGINAL_PREFIX/lib" + # See if we have a GPGME checkout for the tesets. xtest_gpgme_srcdir="$HOME/src/gpgme-for-gnupgs-tests" if [ -d "$xtest_gpgme_srcdir/obj" ]; then ----------------------------------------------------------------------- Summary of changes: misc/jenkins/bin/build.bash | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 12:35:21 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 13 Feb 2017 12:35:21 +0100 Subject: [git] gnupg-doc - branch, master, updated. 7a6a12e6aa916f4b09910d34df7ca16049edee86 Message-ID: This is an 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 7a6a12e6aa916f4b09910d34df7ca16049edee86 (commit) from d37ee56b510b20300bee5a7ffe70e3204e93c160 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7a6a12e6aa916f4b09910d34df7ca16049edee86 Author: Justus Winter Date: Mon Feb 13 12:34:53 2017 +0100 jenkins: use the same gnupg configuration for all unix targets diff --git a/misc/jenkins/bin/build.bash b/misc/jenkins/bin/build.bash index 3dbc58b..68e1ee7 100755 --- a/misc/jenkins/bin/build.bash +++ b/misc/jenkins/bin/build.bash @@ -89,12 +89,19 @@ case "$JOB_NAME" in fi ;; *gnupg*) - if [ "$XTARGET" = native ]; then - CONFIGUREFLAGS="--enable-wks-tools --enable-g13 --enable-symcryptrun --enable-gpg2-is-gpg" - fi + # Common configure options. + CONFIGUREFLAGS="--enable-wks-tools --enable-gpg2-is-gpg" + + # For Windows builds... if [ "$XTARGET" = w32 ]; then - CONFIGUREFLAGS="--enable-wks-tools --enable-gpg2-is-gpg --with-zlib=$ORIGINAL_PREFIX --with-bzip2=$ORIGINAL_PREFIX" + # ... we need to tweak it a little and we leave out some + # stuff... + CONFIGUREFLAGS="$CONFIGUREFLAGS --with-zlib=$ORIGINAL_PREFIX --with-bzip2=$ORIGINAL_PREFIX" + else + # ... that we enable for all other builds. + CONFIGUREFLAGS="$CONFIGUREFLAGS --enable-g13 --enable-symcryptrun" fi + if [ "$NODE_NAME" = zygalski ]; then CONFIGUREFLAGS="$CONFIGUREFLAGS --with-libiconv-prefix=$HOME/pkg" fi ----------------------------------------------------------------------- Summary of changes: misc/jenkins/bin/build.bash | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 15:12:27 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 13 Feb 2017 15:12:27 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-60-g60273e8 Message-ID: This is an 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 60273e8b2c11d42215a5707bc55e3e0d8f350e07 (commit) via f8db658f8b4c3c7941d0029273fb23fbe1ba74ad (commit) from 60064c665ec98a2a994fc6c8ad701e60b963ce7e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 60273e8b2c11d42215a5707bc55e3e0d8f350e07 Author: Justus Winter Date: Mon Feb 13 14:58:07 2017 +0100 build: Use macOS' compatibility macros to enable all features. * configure.ac: On macOS, use the compatibility macros to expose every feature of the libc. This is the equivalent of _GNU_SOURCE on GNU libc. -- Not defining this leads to compilation errors or superfluous warnings on macOS. GnuPG-bug-id: 2910 Signed-off-by: Justus Winter diff --git a/configure.ac b/configure.ac index a5ee77b..ba26901 100644 --- a/configure.ac +++ b/configure.ac @@ -167,6 +167,8 @@ case "${host}" in have_ld_version_script=yes ;; *-apple-darwin*) + AC_DEFINE(_DARWIN_C_SOURCE, 900000L, + Expose all libc features (__DARWIN_C_FULL).) AC_DEFINE(_XOPEN_SOURCE, 500, Activate POSIX interface on MacOS X) ;; esac commit f8db658f8b4c3c7941d0029273fb23fbe1ba74ad Author: Justus Winter Date: Mon Feb 13 14:01:32 2017 +0100 Revert "Disable fd-passing for Apple." The actual bug has been located, so this can be reverted. This reverts commit ef5b4ae37d13142e89a051908dc080cda3d24baa. diff --git a/configure.ac b/configure.ac index f28480b..a5ee77b 100644 --- a/configure.ac +++ b/configure.ac @@ -722,18 +722,7 @@ AC_CHECK_MEMBER(struct cmsghdr.cmsg_len, #include ]) - -dnl There seems to be a problem with Apple and decriptor passing. -dnl Until we found a solution we change the default to no. -dnl See bug 1483. -case "${host}" in - *-apple-darwin*) - use_descriptor_passing=no - ;; - *) - use_descriptor_passing=yes - ;; -esac +use_descriptor_passing=yes AC_ARG_ENABLE(fd-passing, AC_HELP_STRING([--disable-fd-passing], [do not use FD passing]), use_descriptor_passing=$enableval) ----------------------------------------------------------------------- Summary of changes: configure.ac | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 17:51:59 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 13 Feb 2017 17:51:59 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.0.0-15-gcd7b35e Message-ID: This is an 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 cd7b35e8ff106993b9ce98ea99a5210d637f3452 (commit) from e467a000f87e87582f5838964b6f1e0a960d4445 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cd7b35e8ff106993b9ce98ea99a5210d637f3452 Author: Andre Heinecke Date: Mon Feb 13 17:34:24 2017 +0100 qt: Fix pinentry-curses fallback for qt5 * qt/main.cpp (main): Initialize QApplication later. -- This fixes the curses fallback because with Qt5 the creation of the auto_ptr for the application already initialized the XCB subsystem and caused the abort of the application. Also removes the usage of the deprecated auto_ptr. diff --git a/qt/main.cpp b/qt/main.cpp index e2af686..40d0a5b 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -42,7 +42,6 @@ #include #include -#include #include #include @@ -313,7 +312,7 @@ main(int argc, char *argv[]) { pinentry_init("pinentry-qt"); - std::auto_ptr app; + QApplication *app = Q_NULLPTR; #ifdef FALLBACK_CURSES if (!pinentry_have_display(argc, argv)) { @@ -353,14 +352,14 @@ main(int argc, char *argv[]) p += strlen(argv[i]) + 1; } - /* We use a modal dialog window, so we don't need the application - window anymore. */ i = argc; - app.reset(new QApplication(i, new_argv)); + app = new QApplication(i, new_argv); app->setWindowIcon(QIcon(QLatin1String(":/document-encrypt.png"))); } pinentry_parse_opts(argc, argv); - return pinentry_loop() ? EXIT_FAILURE : EXIT_SUCCESS ; + int rc = pinentry_loop(); + delete app; + return rc ? EXIT_FAILURE : EXIT_SUCCESS ; } ----------------------------------------------------------------------- Summary of changes: qt/main.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 13 20:15:49 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 13 Feb 2017 20:15:49 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-73-gdee026d Message-ID: This is an 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 dee026d761ae3d7594c3dbc5b3fa842df53cc189 (commit) via 30dac0486b6357e84fbe79c612eea940b654e4d1 (commit) via 810adfd47801fc01e45fb71af9f05c91f7890cdb (commit) from f8ce31a7bf1ee85e5010b628a66e6f69486e5213 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dee026d761ae3d7594c3dbc5b3fa842df53cc189 Author: Werner Koch Date: Mon Feb 13 20:09:26 2017 +0100 dirmngr: Do a DNS lookup even if it is missing from nsswitch.conf. * dirmngr/dns-stuff.c (libdns_init): Do not print error message for a missing nsswitch.conf. Make sure that tehre is a DNS entry. -- GnuPG-bug-id: 2948 Signed-off-by: Werner Koch diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index f0de357..e57ddc7 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -498,12 +498,10 @@ libdns_init (void) (dns_nssconf_loadpath (ld.resolv_conf, fname)); if (err) { - log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err)); - /* not fatal, nsswitch.conf is not used on all systems; assume - * classic behavior instead. Our dns library states "bf" which tries - * DNS then Files, which is not classic; FreeBSD - * /usr/src/lib/libc/net/gethostnamadr.c defines default_src[] which - * is Files then DNS, which is. */ + /* This is not a fatal error: nsswitch.conf is not used on + * all systems; assume classic behavior instead. */ + if (gpg_err_code (err) != GPG_ERR_ENOENT) + log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err)); if (opt_debug) log_debug ("dns: fallback resolution order, files then DNS\n"); ld.resolv_conf->lookup[0] = 'f'; @@ -511,6 +509,23 @@ libdns_init (void) ld.resolv_conf->lookup[2] = '\0'; err = GPG_ERR_NO_ERROR; } + else if (!strchr (ld.resolv_conf->lookup, 'b')) + { + /* No DNS resulution type found in the list. This might be + * due to systemd based systems which allow for custom + * keywords which are not known to us and thus we do not + * know whether DNS is wanted or not. Becuase DNS is + * important for our infrastructure, we forcefully append + * DNS to the end of the list. */ + if (strlen (ld.resolv_conf->lookup)+2 < sizeof ld.resolv_conf->lookup) + { + if (opt_debug) + log_debug ("dns: appending DNS to resolution order\n"); + strcat (ld.resolv_conf->lookup, "b"); + } + else + log_error ("failed to append DNS to resolution order\n"); + } #endif /* Unix */ } commit 30dac0486b6357e84fbe79c612eea940b654e4d1 Author: Werner Koch Date: Mon Feb 13 19:38:53 2017 +0100 gpgconf: No ENOENT warning with --change-options et al. * tools/gpgconf-comp.c (retrieve_options_from_program): Check ERRNO before printing a warning. -- It is common that a conf files does not exist - thus we should not print a warning. GnuPG-bug-id: 2944 BTW: The error messages in gpgconf should be reworked to match those of the other components. Signed-off-by: Werner Koch diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 20e8411..d1144b2 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2164,8 +2164,11 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) config = es_fopen (config_filename, "r"); if (!config) - gc_error (0, errno, "warning: can not open config file %s", - config_filename); + { + if (errno != ENOENT) + gc_error (0, errno, "warning: can not open config file %s", + config_filename); + } else { while ((length = es_read_line (config, &line, &line_len, NULL)) > 0) commit 810adfd47801fc01e45fb71af9f05c91f7890cdb Author: Werner Koch Date: Mon Feb 13 13:09:51 2017 +0100 gpg: Print a warning if no command has been given. * g10/gpg.c (main): Print in the default case. -- GnuPG-bug-id: 2943 Signed-off-by: Werner Koch diff --git a/g10/gpg.c b/g10/gpg.c index 66a2055..0c5a167 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -4894,8 +4894,12 @@ main (int argc, char **argv) #endif /*USE_TOFU*/ break; - case aListPackets: default: + if (!opt.quiet) + log_info (_("WARNING: no command supplied." + " Trying to guess what you mean ...\n")); + /*FALLTHU*/ + case aListPackets: if( argc > 1 ) wrong_args("[filename]"); /* Issue some output for the unix newbie */ ----------------------------------------------------------------------- Summary of changes: dirmngr/dns-stuff.c | 27 +++++++++++++++++++++------ g10/gpg.c | 6 +++++- tools/gpgconf-comp.c | 7 +++++-- 3 files changed, 31 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 14 10:58:03 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 14 Feb 2017 10:58:03 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-74-gb456e5b Message-ID: This is an 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 b456e5be91dc064fc9509ea86edab113721ed299 (commit) from dee026d761ae3d7594c3dbc5b3fa842df53cc189 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b456e5be91dc064fc9509ea86edab113721ed299 Author: Werner Koch Date: Tue Feb 14 10:55:13 2017 +0100 gpg: Make --export-ssh-key work for the primary key. * g10/export.c (export_ssh_key): Also check the primary key. -- If no suitable subkey was found for export, we now check whether the primary key is suitable for export and export this one. Without this change it was only possible to export the primary key by using the '!' suffix in the key specification. Also added a sample key for testing this. GnuPG-bug-id: 2957 Signed-off-by: Werner Koch diff --git a/g10/export.c b/g10/export.c index f354ca0..8668126 100644 --- a/g10/export.c +++ b/g10/export.c @@ -2208,6 +2208,48 @@ export_ssh_key (ctrl_t ctrl, const char *userid) latest_key = node; } } + + /* If no subkey was suitable check the primary key. */ + if (!latest_key + && (node = keyblock) && node->pkt->pkttype == PKT_PUBLIC_KEY) + { + pk = node->pkt->pkt.public_key; + if (DBG_LOOKUP) + log_debug ("\tchecking primary key %08lX\n", + (ulong) keyid_from_pk (pk, NULL)); + if (!(pk->pubkey_usage & PUBKEY_USAGE_AUTH)) + { + if (DBG_LOOKUP) + log_debug ("\tprimary key not usable for authentication\n"); + } + else if (!pk->flags.valid) + { + if (DBG_LOOKUP) + log_debug ("\tprimary key not valid\n"); + } + else if (pk->flags.revoked) + { + if (DBG_LOOKUP) + log_debug ("\tprimary key has been revoked\n"); + } + else if (pk->has_expired) + { + if (DBG_LOOKUP) + log_debug ("\tprimary key has expired\n"); + } + else if (pk->timestamp > curtime && !opt.ignore_valid_from) + { + if (DBG_LOOKUP) + log_debug ("\tprimary key not yet valid\n"); + } + else + { + if (DBG_LOOKUP) + log_debug ("\tprimary key is fine\n"); + latest_date = pk->timestamp; + latest_key = node; + } + } } if (!latest_key) diff --git a/tests/openpgp/samplekeys/README b/tests/openpgp/samplekeys/README index 29524d5..6f2399f 100644 --- a/tests/openpgp/samplekeys/README +++ b/tests/openpgp/samplekeys/README @@ -17,3 +17,5 @@ E657FB607BB4F21C90BB6651BC067AF28BC90111.asc Key with subkeys (no protection) rsa-rsa-sample-1.asc RSA+RSA sample key (no passphrase) ed25519-cv25519-sample-1.asc Ed25519+CV25519 sample key (no passphrase) silent-running.asc Collection of sample secret keys (no passphrases) +rsa-primary-auth-only.pub.asc rsa2408 primary only, usage: cert,auth +rsa-primary-auth-only.sec.asc Ditto but the secret keyblock. diff --git a/tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc b/tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc new file mode 100644 index 0000000..f34999e --- /dev/null +++ b/tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc @@ -0,0 +1,23 @@ +pub rsa2048 2017-02-14 [CA] + F74B4029E6906D12EBDA8EE3BD7744900FDABC8D + Keygrip = AB1BB1843677AF7CC4D6C14444320C3FF4147E98 +uid [ unknown] ssh://host.example.net + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBFiizWgBCACi28riS0AaC7UvXaZfoafEvcXq/MAq6akiowPf3eY4zz5DkBPf +Ep3kGuDMAFqULvchIt9vpg719Zar/Xldi+UG+/KsDz+TT5k+nP6CwvBHbAXXtISv +S51TKKnTFpvjcgJc1BMFN0pGf7JnZx1QfRfsZO2BvS4qVzYCWbSS9hlpMq4aIgOc +ERBMsZYMPnI4ijbXysksecDC91kbJH0q5j8aGir5sDyrDwfVLp0SUAubRFU5gXuZ +SEv9QmeV7XoXKXzk9KEYy7GUgoAJzabvbF0rVXqd3DE8KFkwK7rKBe8sGC04DWlK +j/sHJcAfMSqCi/SZyYpO+FSfnB+uJ1BNc05hABEBAAG0FnNzaDovL2hvc3QuZXhh +bXBsZS5uZXSJAU4EEwEIADgWIQT3S0Ap5pBtEuvajuO9d0SQD9q8jQUCWKLNaAIb +IQULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRC9d0SQD9q8jZBrB/41MJWUeclV +tM60+ydPNgUJwyRXpKdLIm/AtM1zOijlFkwsaMmzbFSFJJX98HGASHdU5OpL2Lv3 +1NNDNMbUuFumApVrLzJUBugFRb+8/uY7H3Z0/YKQ9g9OC3z7+uqFFv/+/wA+VdYX +Zy6uim8E4OlJ41S68fQcMiTxbLTCDkvBbpf505t6JhNqF6JB+SBFQJXvRqjoydXf +dyoiDz9N1V0ERzmGEiPewvHg2zWcVia07NGhxN3slQ3klOfYJQ8Ye72feNq1zKCy +AyU3X8fL10XKWooCAU+t4hR5hXYxYTSZse5q0FHZ38Lt9c3ApMSZ2+ueeOtGbsH9 +kV8icGkI6KXp +=zMXp +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc b/tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc new file mode 100644 index 0000000..9d72421 --- /dev/null +++ b/tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc @@ -0,0 +1,38 @@ +sec rsa2048 2017-02-14 [CA] + F74B4029E6906D12EBDA8EE3BD7744900FDABC8D + Keygrip = AB1BB1843677AF7CC4D6C14444320C3FF4147E98 +uid [ unknown] ssh://host.example.net + +Passprase: none + +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQOYBFiizWgBCACi28riS0AaC7UvXaZfoafEvcXq/MAq6akiowPf3eY4zz5DkBPf +Ep3kGuDMAFqULvchIt9vpg719Zar/Xldi+UG+/KsDz+TT5k+nP6CwvBHbAXXtISv +S51TKKnTFpvjcgJc1BMFN0pGf7JnZx1QfRfsZO2BvS4qVzYCWbSS9hlpMq4aIgOc +ERBMsZYMPnI4ijbXysksecDC91kbJH0q5j8aGir5sDyrDwfVLp0SUAubRFU5gXuZ +SEv9QmeV7XoXKXzk9KEYy7GUgoAJzabvbF0rVXqd3DE8KFkwK7rKBe8sGC04DWlK +j/sHJcAfMSqCi/SZyYpO+FSfnB+uJ1BNc05hABEBAAEAB/wN0yan4HIdQ+fU5i2c +v0uknI9+i9zW8mWUi84Puks0K15CZ1VTLHC8JQ6hgq4twhw3HeS7GkJO3X2K4BuQ +tggdIv94slqtQKaQ9XbNgYraz/AMXZtIiNy0FdGaGmM6rY+ccwxM9w1BFXn+48v4 +lzCUCq/2wX53wwDSC5dpRPw8km6+uksFh3dfY8kgfpjU/lUCCwQiooYrQhut1EGB +lDLRHp2ntC1xsnowtdPzluIHFetFSnmn2ehGqXqXtXLAMF0HOirViO5dUVMuj2Pe +ra3IYVYANYK/7FEsRXHxU6aB/BSnubb5EiqB1Oi1JNyMrvYZnRsoRUaMjVgjA4ne +RwD5BADBZN2USYGgciDVh7kvTbrtS1igPhoe3xUUQsM0hVIEwBzG4A4pWXznIQyW +BziVTnRNp953EbHJIYdn7vmJzdiRKI+hOvrF8dfvVsq+fp4pWxrc+zrC6qptpo6H +IhkHWUpyfIPuTI8d+glIUIuDshwKau0UZ8VDTOYuRYEZX9PrAwQA15RdS3geA1cf +UK/ZaKs5VnohcLtEE/z3BlvlQaEdHxSQJSLYC4By7zKVOFZlZkHk36IPikwYNTgc +P57aLe7rwNZqPhADue1ZN6Ypetvrek55lAYL9XoPJ/mWaYz6oDWWW8vHYqEPk8OL +N8/8a6DhK0iydXi9/ztHQllbOt0EUcsEAJBjX84FgIi3VRotRSEDN/tIhekNo8p6 +Pl8YF4V8A1hCVBEKRIcsPVx603DFiGFRcQQcBbblqVG4fpOYYgiBtEgJksRiMg/o +kmVkl8BPrIhBGe2ez7byhhFvJDAoOWCdH0MWGaPGUoCGTDvd046GE8B3UWN9TSmo +qAqfrUG0hQVQLEa0FnNzaDovL2hvc3QuZXhhbXBsZS5uZXSJAU4EEwEIADgWIQT3 +S0Ap5pBtEuvajuO9d0SQD9q8jQUCWKLNaAIbIQULCQgHAgYVCAkKCwIEFgIDAQIe +AQIXgAAKCRC9d0SQD9q8jZBrB/41MJWUeclVtM60+ydPNgUJwyRXpKdLIm/AtM1z +OijlFkwsaMmzbFSFJJX98HGASHdU5OpL2Lv31NNDNMbUuFumApVrLzJUBugFRb+8 +/uY7H3Z0/YKQ9g9OC3z7+uqFFv/+/wA+VdYXZy6uim8E4OlJ41S68fQcMiTxbLTC +DkvBbpf505t6JhNqF6JB+SBFQJXvRqjoydXfdyoiDz9N1V0ERzmGEiPewvHg2zWc +Via07NGhxN3slQ3klOfYJQ8Ye72feNq1zKCyAyU3X8fL10XKWooCAU+t4hR5hXYx +YTSZse5q0FHZ38Lt9c3ApMSZ2+ueeOtGbsH9kV8icGkI6KXp +=3QG9 +-----END PGP PRIVATE KEY BLOCK----- ----------------------------------------------------------------------- Summary of changes: g10/export.c | 42 ++++++++++++++++++++++ tests/openpgp/samplekeys/README | 2 ++ .../samplekeys/rsa-primary-auth-only.pub.asc | 23 ++++++++++++ .../samplekeys/rsa-primary-auth-only.sec.asc | 38 ++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc create mode 100644 tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 14 12:20:31 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 14 Feb 2017 12:20:31 +0100 Subject: [git] gnupg-doc - branch, master, updated. d6a2c2992be786c94ce0e1aae5a71d80bc860e92 Message-ID: This is an 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 d6a2c2992be786c94ce0e1aae5a71d80bc860e92 (commit) via 7b350bf5bf12203443d0e4efd7e7a6ce165869cc (commit) from 7a6a12e6aa916f4b09910d34df7ca16049edee86 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d6a2c2992be786c94ce0e1aae5a71d80bc860e92 Author: Justus Winter Date: Tue Feb 14 12:14:13 2017 +0100 jenkins: hack around the RUNPATH issue diff --git a/misc/jenkins/bin/build.bash b/misc/jenkins/bin/build.bash index 68e1ee7..9cb5f0d 100755 --- a/misc/jenkins/bin/build.bash +++ b/misc/jenkins/bin/build.bash @@ -114,11 +114,24 @@ case "$JOB_NAME" in ;; esac -# The libraries use rpath when linking the tests, so they locate their -# dependencies that way. GnuPG, however, does not. Therefore, we set -# LD_LIBRARY_PATH. +# The libraries use RUNPATH when linking the tests, so they locate +# their dependencies that way. GnuPG, however, does not. Therefore, +# we set LD_LIBRARY_PATH. test_environment="LD_LIBRARY_PATH=$ORIGINAL_PREFIX/lib" +# HACKHACKHACK: +# +# Because newer Debian toolchains prefer RUNPATH over RPATH, and +# RUNPATH has lower precedence than LD_LIBRARY_PATH, we need to +# explicitly add libtool's .libs directory: +test_environment="LD_LIBRARY_PATH=$(pwd)/obj/src/.libs:$ORIGINAL_PREFIX/lib" +# +# If we don't do this, the version tests fail because the runtime +# linker will pick up the library from LD_LIBRARY_PATH. Also, testing +# the installed version is not what we want ofc. +# +# KCAHKCAHKCAH + # See if we have a GPGME checkout for the tesets. xtest_gpgme_srcdir="$HOME/src/gpgme-for-gnupgs-tests" if [ -d "$xtest_gpgme_srcdir/obj" ]; then @@ -232,6 +245,20 @@ case "$XTARGET" in cd "$WORKDIR" $abs_configure --prefix=$PREFIX --enable-maintainer-mode \ $CONFIGUREFLAGS + + # Extract the directory / tarname from the package + tarname=$(awk Date: Mon Feb 13 13:09:14 2017 +0100 jenkins: tweak scute configuration diff --git a/misc/jenkins/jobs/scute/config.xml b/misc/jenkins/jobs/scute/config.xml index f63ca2a..4cb4d3b 100644 --- a/misc/jenkins/jobs/scute/config.xml +++ b/misc/jenkins/jobs/scute/config.xml @@ -91,7 +91,7 @@ - FAIL: + FAIL:\s*[0-9]*[1-9][0-9]* false true true ----------------------------------------------------------------------- Summary of changes: misc/jenkins/bin/build.bash | 40 +++++++++++++++++++++++++++++--------- misc/jenkins/jobs/scute/config.xml | 2 +- 2 files changed, 32 insertions(+), 10 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 14 12:46:16 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 14 Feb 2017 12:46:16 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-66-g30a6035 Message-ID: This is an 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 30a603580e0f196c721fa4bd44d24077d9bc06c3 (commit) via 01d5c17587578c729bbbb60f8a65635975e35592 (commit) via aa49be1ab80c200ab6b62d33bf5d0f5aa334fc56 (commit) via d35651917097ae2eee7d52396d53d010bc34df19 (commit) via d184dbbba8987d9f387feb25791ed891e108dabc (commit) via fe65a26ab584bd70fad45c7c4d44330e30a748a4 (commit) from 60273e8b2c11d42215a5707bc55e3e0d8f350e07 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 30a603580e0f196c721fa4bd44d24077d9bc06c3 Author: Justus Winter Date: Tue Feb 14 12:45:15 2017 +0100 qt: Make sure to remove the tofu.db on clean. * lang/qt/tests/Makefile.am (CLEANFILES): Add 'tofu.db'. Signed-off-by: Justus Winter diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index e3aa3be..93dce07 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -72,7 +72,7 @@ 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~ \ random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp $(moc_files) \ - gpg.conf + gpg.conf tofu.db clean-local: -rm -fR private-keys-v1.d crls.d commit 01d5c17587578c729bbbb60f8a65635975e35592 Author: Tobias Mueller Date: Tue Dec 20 18:02:36 2016 +0100 python: Extend SWIG gpgme_{sub,}key with a __repr__ method. * lang/python/gpgme.i: Added a genericrepr macro and use it for gpgme_key, gpgme_subkey, and gpgme_key_sig. -- To look nicer in Python's REPL. We define a generic __repr__ as a SWIG macro and use that to extend some defined SWIG objects. The alternative would have been to write a custom __repr__ function for each class but that would need to be changed everytime the object's structure changes. The bindings should be easy to maintain, I guess. This comes at the expense that the reprs are now relatively long and contain, for example, both keyid and fingerprint. Signed-off-by: Tobias Mueller diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index e21aa6c..c0993ee 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -649,3 +649,30 @@ _gpg_unwrap_gpgme_ctx_t(PyObject *wrapped) /* ... but only the public definitions here. They will be exposed to the Python world, so let's be careful. */ %include "helpers.h" + + +%define genericrepr(cls) +%pythoncode %{ + def __repr__(self): + names = [name for name in dir(self) + if not name.startswith("_") and name != "this"] + props = ", ".join(("{}={!r}".format(name, getattr(self, name)) + for name in names) + ) + return "cls({})".format(props) +%} + +%enddef + +%extend _gpgme_key { + genericrepr(Key) +}; + + +%extend _gpgme_subkey { + genericrepr(SubKey) +}; + +%extend _gpgme_key_sig { + genericrepr(KeySig) +}; commit aa49be1ab80c200ab6b62d33bf5d0f5aa334fc56 Author: Tobias Mueller Date: Tue Dec 20 18:02:20 2016 +0100 python: Remove the -builtin flag for SWIG. * lang/python/setup.py.in: Call SWIG without the builtin flag. -- The SWIG documentation leaves the impression that -builtin is solely for increasing performance: New in SWIG version 2.0.4: The use of Python proxy classes has performance implications that may be unacceptable for a high- performance library. The new -builtin option instructs SWIG to forego the use of proxy classes, and instead create wrapped types as new built-in Python types. When this option is used, the following section ("Proxy classes") does not apply. Details on the use of the -builtin option are in the Built-in Types section. While not wasting CPU cycles is good, it also prevents Python code being written in the wrapper itself. That, however, may be useful to make it easier to extend the wrapper. Partially reverts: 856bcfe2934237011984fab0bc69800a7c25c34b Signed-off-by: Tobias Mueller diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index c7f981a..5b5d5be 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -154,7 +154,7 @@ class BuildExtFirstHack(build): py3 = [] if sys.version_info.major < 3 else ['-py3'] swige = Extension("gpg._gpgme", ["gpgme.i", "helpers.c"], - swig_opts = ['-threads', '-builtin', + swig_opts = ['-threads', '-outdir', 'gpg'] + py3 + extra_swig_opts, include_dirs = include_dirs, define_macros = define_macros, commit d35651917097ae2eee7d52396d53d010bc34df19 Author: Tobias Mueller Date: Tue Dec 20 18:01:27 2016 +0100 python: Call SWIG_NewPointerObj rather than SWIG_Python_NewPointerObj. * lang/python/gpgme.i (pygpgme_wrap_gpgme_data_t): Provide a "self" variable for SWIG_NewPointerObj and call SWIG_NewPointerObj rather than SWIG_Python_NewPointerObj. -- SWIG_Python_NewPointerObj seems to be an implementation detail, because SWIG's documentation does not mention that function at all. In fact, SWIG_NewPointerObj is a call to SWIG_Python_NewPointerObj with the first parameter being either NULL or the "self" variable, depending on whether SWIG is called with the -builtin flag. So far, the first parameter was hard-coded to NULL. This change also hard-codes it to NULL but makes it more explicit. The benefit is that the documented function is being used and that compilation works regardless of the -builtin flag. Partially reverts: 856bcfe2934237011984fab0bc69800a7c25c34b Signed-off-by: Tobias Mueller diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index c7d89db..e21aa6c 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -620,7 +620,17 @@ FILE *fdopen(int fildes, const char *mode); PyObject * _gpg_wrap_gpgme_data_t(gpgme_data_t data) { - return SWIG_Python_NewPointerObj(NULL, data, SWIGTYPE_p_gpgme_data, 0); + /* + * If SWIG is invoked without -builtin, the macro SWIG_NewPointerObj + * expects a variable named "self". + * + * XXX: It is not quite clear why passing NULL as self is okay, but + * it works with -builtin, and it seems to work just fine without + * it too. + */ + PyObject* self = NULL; + (void) self; + return SWIG_NewPointerObj(data, SWIGTYPE_p_gpgme_data, 0); } gpgme_ctx_t commit d184dbbba8987d9f387feb25791ed891e108dabc Author: Tobias Mueller Date: Tue Dec 20 18:00:36 2016 +0100 python: Conditionally provide py3 argument to SWIG * lang/python/setup.py.in: Only call with -py3 when we run under python3 or higher. -- If we ever remove the -builtin flag and leave the the -py3 flag, SWIG will generate Python code which will be incompatible with Python 2, because the py3 flag generates python3 code which is incompatible with python2. So we conditionally generate SWIG bindings with -py3. Signed-off-by: Tobias Mueller diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index 9669c28..c7f981a 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -152,9 +152,10 @@ class BuildExtFirstHack(build): self.run_command('build_ext') build.run(self) +py3 = [] if sys.version_info.major < 3 else ['-py3'] swige = Extension("gpg._gpgme", ["gpgme.i", "helpers.c"], - swig_opts = ['-py3', '-builtin', '-threads', - '-outdir', 'gpg'] + extra_swig_opts, + swig_opts = ['-threads', '-builtin', + '-outdir', 'gpg'] + py3 + extra_swig_opts, include_dirs = include_dirs, define_macros = define_macros, library_dirs = library_dirs, commit fe65a26ab584bd70fad45c7c4d44330e30a748a4 Author: Justus Winter Date: Mon Feb 13 16:44:53 2017 +0100 python: Use one copy of the source tree per Python version. * lang/python/Makefile.am (copystamp): Create one copy per Python version. (all-local): Adapt. (clean-local): Likewise. (install-exec-local): Likewise. * lang/python/tests/run-tests.py: Likewise. -- Currently, we use one copy of the Python module's source to build for all Python versions. This is problematic, because SWIG writes a wrapper file into the source tree. Currently, this file works with both Python 2 and 3, but this is purely by chance. Improve the situation by creating one copy per Python version so that SWIG can write version-specific code into each copy. Signed-off-by: Justus Winter diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am index e32fd12..908f622 100644 --- a/lang/python/Makefile.am +++ b/lang/python/Makefile.am @@ -47,10 +47,12 @@ COPY_FILES_GPG = \ # For VPATH builds we need to copy some files because Python's # distutils are not VPATH-aware. copystamp: $(COPY_FILES) $(COPY_FILES_GPG) data.h config.h - if test "$(srcdir)" != "$(builddir)" ; then \ - cp -R $(COPY_FILES) . ; \ - cp -R $(COPY_FILES_GPG) gpg ; \ - fi + for VERSION in $(PYTHON_VERSIONS); do \ + $(MKDIR_P) python$${VERSION}-gpg/gpg && \ + cp -R $(COPY_FILES) python$${VERSION}-gpg && \ + cp gpg/version.py python$${VERSION}-gpg/gpg && \ + cp -R $(COPY_FILES_GPG) python$${VERSION}-gpg/gpg ; \ + done touch $@ data.h: @@ -60,9 +62,12 @@ config.h: ln -s "$(top_builddir)/config.h" . all-local: copystamp - for PYTHON in $(PYTHONS); do \ + set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \ + PYTHON="$$1" ; shift ; \ + cd python$${VERSION}-gpg && \ CFLAGS="$(CFLAGS)" \ - $$PYTHON setup.py build --verbose ; \ + $$PYTHON ../setup.py build --verbose ; \ + cd .. ; \ done dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc: copystamp @@ -89,23 +94,23 @@ CLEANFILES = gpgme.h errors.i gpgme_wrap.c gpg/gpgme.py \ # permissions. clean-local: rm -rf -- build - 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_GPG); do \ - rm -rf -- gpg/`basename $$F` ; \ - done ; \ - fi + for VERSION in $(PYTHON_VERSIONS); do \ + find python$${VERSION}-gpg -type d ! -perm -200 -exec chmod u+w {} ';' ; \ + rm -rf -- python$${VERSION}-gpg ; \ + done install-exec-local: rm -f install_files.txt - for PYTHON in $(PYTHONS); do \ - $$PYTHON setup.py install \ + set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \ + PYTHON="$$1" ; shift ; \ + cd python$${VERSION}-gpg && \ + $$PYTHON ../setup.py install \ --prefix $(DESTDIR)$(prefix) \ --record files.txt \ --verbose ; \ - cat files.txt >> install_files.txt ; \ + cat files.txt >> ../install_files.txt ; \ rm files.txt ; \ + cd .. ; \ done $(MKDIR_P) $(DESTDIR)$(pythondir)/gpg mv install_files.txt $(DESTDIR)$(pythondir)/gpg diff --git a/lang/python/tests/run-tests.py b/lang/python/tests/run-tests.py index 46c6d8c..e76acb2 100644 --- a/lang/python/tests/run-tests.py +++ b/lang/python/tests/run-tests.py @@ -69,7 +69,9 @@ for interpreter in args.interpreters: version = subprocess.check_output( [interpreter, "-c", "import sys; print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))"]).strip().decode() - builddirs = glob.glob(os.path.join(args.builddir, "..", "build", + builddirs = glob.glob(os.path.join(args.builddir, "..", + "python{0}-gpg".format(version), + "build", "lib*"+version)) assert len(builddirs) == 1, \ "Expected one build directory, got {0}".format(builddirs) ----------------------------------------------------------------------- Summary of changes: lang/python/Makefile.am | 37 +++++++++++++++++++++---------------- lang/python/gpgme.i | 39 ++++++++++++++++++++++++++++++++++++++- lang/python/setup.py.in | 5 +++-- lang/python/tests/run-tests.py | 4 +++- lang/qt/tests/Makefile.am | 2 +- 5 files changed, 66 insertions(+), 21 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 14 16:36:19 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 14 Feb 2017 16:36:19 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-71-g92adc9b Message-ID: This is an 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 92adc9bbf640eb5d9177d3ba0189e0f6cee4e995 (commit) via 9fc9533c2835ec53c4fd4f822b09e9fec14626d0 (commit) via fdc4e33dc3f6c84fe9d7bf9795c603ae3cf5f28d (commit) via e17ab84129045512cf60c221ee43aa877507662f (commit) via 99b7f4f34dd595579181a696ae976a678fe00d49 (commit) from 30a603580e0f196c721fa4bd44d24077d9bc06c3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 92adc9bbf640eb5d9177d3ba0189e0f6cee4e995 Author: Justus Winter Date: Tue Feb 14 16:30:30 2017 +0100 python: Wrap utility functions. * NEWS: Update. * lang/python/gpg/core.py (pubkey_algo_string): New function. (pubkey_algo_name): Add docstring. (hash_algo_name): Likewise. (get_protocol_name): Likewise. (addrspec_from_uid): New function. * lang/python/gpgme.i (gpgme_pubkey_algo_string): Result must be freed. (gpgme_addrspec_from_uid): Likewise. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 125d54e..a974ec7 100644 --- a/NEWS +++ b/NEWS @@ -13,9 +13,11 @@ Noteworthy changes in version 1.8.1 (unreleased) cpp: Key::addUid() NEW. qt: CryptoConfig::stringValueList() NEW. gpgme_data_rewind UN-DEPRECATE. - py: Context.__init__ EXTENDED: New keyword argument home_dir. - py: Context.home_dir NEW. - py: Context.keylist EXTENDED: New keyword argument mode. + py: Context.__init__ EXTENDED: New keyword arg home_dir. + py: Context.home_dir NEW. + py: Context.keylist EXTENDED: New keyword arg mode. + py: core.pubkey_algo_string NEW. + py: core.addrspec_from_uid NEW. Noteworthy changes in version 1.8.0 (2016-11-16) diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index e07ec33..18a7e3a 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -1118,15 +1118,64 @@ class Data(GpgmeWrapper): chunks.append(result) return b''.join(chunks) +def pubkey_algo_string(subkey): + """Return short algorithm string + + Return a public key algorithm string (e.g. "rsa2048") for a given + SUBKEY. + + Returns: + algo - a string + + """ + return gpgme.gpgme_pubkey_algo_string(subkey) + def pubkey_algo_name(algo): + """Return name of public key algorithm + + Return the name of the public key algorithm for a given numeric + algorithm id ALGO (cf. RFC4880). + + Returns: + algo - a string + + """ return gpgme.gpgme_pubkey_algo_name(algo) def hash_algo_name(algo): + """Return name of hash algorithm + + Return the name of the hash algorithm for a given numeric + algorithm id ALGO (cf. RFC4880). + + Returns: + algo - a string + + """ return gpgme.gpgme_hash_algo_name(algo) def get_protocol_name(proto): + """Get protocol description + + Get the string describing protocol PROTO. + + Returns: + proto - a string + + """ return gpgme.gpgme_get_protocol_name(proto) +def addrspec_from_uid(uid): + """Return the address spec + + Return the addr-spec (cf. RFC2822 section 4.3) from a user id UID. + + Returns: + addr_spec - a string + + """ + return gpgme.gpgme_addrspec_from_uid(uid) + def check_version(version=None): return gpgme.gpgme_check_version(version) diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index dc691dd..c7fc14e 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -113,6 +113,8 @@ /* Release returned buffers as necessary. */ %typemap(newfree) char * "gpgme_free($1);"; %newobject gpgme_data_release_and_get_mem; +%newobject gpgme_pubkey_algo_string; +%newobject gpgme_addrspec_from_uid; %typemap(arginit) gpgme_key_t [] { $1 = NULL; commit 9fc9533c2835ec53c4fd4f822b09e9fec14626d0 Author: Justus Winter Date: Tue Feb 14 16:16:05 2017 +0100 python: Use the correct function to free buffers. * lang/python/gpgme.i (char *): Free using 'gpgme_free'. Signed-off-by: Justus Winter diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index 792567f..dc691dd 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -111,7 +111,7 @@ } /* Release returned buffers as necessary. */ -%typemap(newfree) char * "free($1);"; +%typemap(newfree) char * "gpgme_free($1);"; %newobject gpgme_data_release_and_get_mem; %typemap(arginit) gpgme_key_t [] { commit fdc4e33dc3f6c84fe9d7bf9795c603ae3cf5f28d Author: Justus Winter Date: Tue Feb 14 15:56:41 2017 +0100 python: Add keylist mode parameter. * NEWS: Update. * lang/python/gpg/core.py (Context.keylist): Add 'mode' parameter. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 7ec3dfb..125d54e 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ Noteworthy changes in version 1.8.1 (unreleased) gpgme_data_rewind UN-DEPRECATE. py: Context.__init__ EXTENDED: New keyword argument home_dir. py: Context.home_dir NEW. + py: Context.keylist EXTENDED: New keyword argument mode. Noteworthy changes in version 1.8.0 (2016-11-16) diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index 79d1f53..e07ec33 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -483,12 +483,14 @@ class Context(GpgmeWrapper): plainbytes = data.read() return plainbytes, result - def keylist(self, pattern=None, secret=False): + def keylist(self, pattern=None, secret=False, + mode=constants.keylist.mode.LOCAL): """List keys Keyword arguments: pattern -- return keys matching pattern (default: all keys) - secret -- return only secret keys + secret -- return only secret keys (default: False) + mode -- keylist mode (default: list local keys) Returns: -- an iterator returning key objects @@ -496,6 +498,7 @@ class Context(GpgmeWrapper): Raises: GPGMEError -- as signaled by the underlying library """ + self.set_keylist_mode(mode) return self.op_keylist_all(pattern, secret) def assuan_transact(self, command, commit e17ab84129045512cf60c221ee43aa877507662f Author: Justus Winter Date: Tue Feb 14 15:55:20 2017 +0100 python: Nicer repr for user ids. * lang/python/gpgme.i (_gpgme_user_id): Provide a nicer repr() for user ids. Signed-off-by: Justus Winter diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index c0993ee..792567f 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -676,3 +676,7 @@ _gpg_unwrap_gpgme_ctx_t(PyObject *wrapped) %extend _gpgme_key_sig { genericrepr(KeySig) }; + +%extend _gpgme_user_id { + genericrepr(UID) +}; commit 99b7f4f34dd595579181a696ae976a678fe00d49 Author: Justus Winter Date: Tue Feb 14 13:43:01 2017 +0100 python: Add convenience functions for the home directory. * NEWS: Update. * lang/python/gpg/core.py (Context.__init__): Add 'home_dir' argument. (__repr__): Include 'home_dir'. (Context.home_dir): New property. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 4405f6c..7ec3dfb 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ Noteworthy changes in version 1.8.1 (unreleased) cpp: Key::addUid() NEW. qt: CryptoConfig::stringValueList() NEW. gpgme_data_rewind UN-DEPRECATE. + py: Context.__init__ EXTENDED: New keyword argument home_dir. + py: Context.home_dir NEW. Noteworthy changes in version 1.8.0 (2016-11-16) diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index 43856ab..79d1f53 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -176,7 +176,7 @@ class Context(GpgmeWrapper): def __init__(self, armor=False, textmode=False, offline=False, signers=[], pinentry_mode=constants.PINENTRY_MODE_DEFAULT, protocol=constants.PROTOCOL_OpenPGP, - wrapped=None): + wrapped=None, home_dir=None): """Construct a context object Keyword arguments: @@ -186,6 +186,7 @@ class Context(GpgmeWrapper): signers -- list of keys used for signing (default []) pinentry_mode -- pinentry mode (default PINENTRY_MODE_DEFAULT) protocol -- protocol to use (default PROTOCOL_OpenPGP) + home_dir -- state directory (default is the engine default) """ if wrapped: @@ -203,13 +204,14 @@ class Context(GpgmeWrapper): self.signers = signers self.pinentry_mode = pinentry_mode self.protocol = protocol + self.home_dir = home_dir def __repr__(self): return ( "Context(armor={0.armor}, " "textmode={0.textmode}, offline={0.offline}, " "signers={0.signers}, pinentry_mode={0.pinentry_mode}, " - "protocol={0.protocol}" + "protocol={0.protocol}, home_dir={0.home_dir}" ")").format(self) def encrypt(self, plaintext, recipients=[], sign=True, sink=None, @@ -610,6 +612,14 @@ class Context(GpgmeWrapper): errorcheck(gpgme.gpgme_engine_check_version(value)) self.set_protocol(value) + @property + def home_dir(self): + """Engine's home directory""" + return self.engine_info.home_dir + @home_dir.setter + def home_dir(self, value): + self.set_engine_info(self.protocol, home_dir=value) + _ctype = 'gpgme_ctx_t' _cprefix = 'gpgme_' ----------------------------------------------------------------------- Summary of changes: NEWS | 5 ++++ lang/python/gpg/core.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- lang/python/gpgme.i | 8 +++++- 3 files changed, 78 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 15 10:27:26 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 15 Feb 2017 10:27:26 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-75-ge279281 Message-ID: This is an 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 e2792813a55e091c51be7b1b089a71beb6466f1d (commit) from b456e5be91dc064fc9509ea86edab113721ed299 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e2792813a55e091c51be7b1b089a71beb6466f1d Author: NIIBE Yutaka Date: Wed Feb 15 18:23:01 2017 +0900 scd: Fix RESET command handling. * scd/app.c (release_application_internal): Remove. (release_application): Merge release_application_internal. (app_reset): Kick the loop and let close the reader. Sleep is required here to wait closing. (scd_update_reader_status_file): When APP is no use, close it. Signed-off-by: NIIBE Yutaka diff --git a/scd/app.c b/scd/app.c index 7e72870..29c9dad 100644 --- a/scd/app.c +++ b/scd/app.c @@ -136,40 +136,28 @@ check_application_conflict (const char *name, app_t app) } -static void -release_application_internal (app_t app) -{ - if (!app->ref_count) - log_bug ("trying to release an already released context\n"); - - --app->ref_count; -} - gpg_error_t app_reset (app_t app, ctrl_t ctrl, int send_reset) { gpg_error_t err; - err = lock_app (app, ctrl); - if (err) - return err; - if (send_reset) { int sw = apdu_reset (app->slot); if (sw) err = gpg_error (GPG_ERR_CARD_RESET); - /* Release the same application which is used by other sessions. */ + /* Release the same application which is used by all sessions. */ send_client_notifications (app, 1); + scd_kick_the_loop (); + gnupg_sleep (1); } else { ctrl->app_ctx = NULL; - release_application_internal (app); + release_application (app); } - unlock_app (app); return err; } @@ -486,7 +474,10 @@ release_application (app_t app) are preserved. */ lock_app (app, NULL); - release_application_internal (app); + if (!app->ref_count) + log_bug ("trying to release an already released context\n"); + + --app->ref_count; unlock_app (app); } @@ -1028,20 +1019,25 @@ scd_update_reader_status_file (void) int sw; unsigned int status; - sw = apdu_get_status (a->slot, 0, &status); app_next = a->next; - if (sw == SW_HOST_NO_READER) - { - /* Most likely the _reader_ has been unplugged. */ - status = 0; - } - else if (sw) + if (a->ref_count == 0) + status = 0; + else { - /* Get status failed. Ignore that. */ - if (a->periodical_check_needed) - periodical_check_needed = 1; - continue; + sw = apdu_get_status (a->slot, 0, &status); + if (sw == SW_HOST_NO_READER) + { + /* Most likely the _reader_ has been unplugged. */ + status = 0; + } + else if (sw) + { + /* Get status failed. Ignore that. */ + if (a->periodical_check_needed) + periodical_check_needed = 1; + continue; + } } if (a->card_status != status) ----------------------------------------------------------------------- Summary of changes: scd/app.c | 52 ++++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 15 15:56:23 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 15 Feb 2017 15:56:23 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-77-g90d383f Message-ID: This is an 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 90d383f1eb07fc823518dea10eb15ca390f5cf8e (commit) via 127e1e532da4083ccd3c307555b6177fab16f408 (commit) from e2792813a55e091c51be7b1b089a71beb6466f1d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 90d383f1eb07fc823518dea10eb15ca390f5cf8e Author: Justus Winter Date: Wed Feb 15 15:51:09 2017 +0100 tests: Test and document other ways to create keys. * doc/gpg.texi: Clarify usage and expiration arguments for key generation. * tests/openpgp/quick-key-manipulation.scm: Test all variants. Signed-off-by: Justus Winter diff --git a/doc/gpg.texi b/doc/gpg.texi index b79b783..16c9674 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -644,10 +644,13 @@ For a description of these optional arguments see the command the default is to a create certification and signing key. The @code{expire} argument can be used to specify an expiration date -for the key. Several formats are supported; commonly the ISO -YYYY-MM-DD format is used. The values ``never'', ``none'' can be used -for no expiration date. Not specifying a value, or using ``-'' -results in a key expiring in a reasonable default interval. +for the key. Several formats are supported; commonly the ISO formats +``YYYY-MM-DD'' or ``YYYYMMDDThhmmss'' are used. To make the key +expire in N seconds, N days, N weeks, N months, or N years use +``seconds=N'', ``Nd'', ``Nw'', ``Nm'', or ``Ny'' respectively. Not +specifying a value, or using ``-'' results in a key expiring in a +reasonable default interval. The values ``never'', ``none'' can be +used for no expiration date. If this command is used with @option{--batch}, @option{--pinentry-mode} has been set to @code{loopback}, and one of @@ -684,15 +687,20 @@ Depending on the given @code{algo} the subkey may either be an encryption subkey or a signing subkey. If an algorithm is capable of signing and encryption and such a subkey is desired, a @code{usage} string must be given. This string is either ``default'' or ``-'' to -keep the default or a comma delimited list of keywords: ``sign'' for a -signing subkey, ``auth'' for an authentication subkey, and ``encr'' -for an encryption subkey (``encrypt'' can be used as alias for -``encr''). The valid combinations depend on the algorithm. +keep the default or a comma delimited list (or space delimited list) +of keywords: ``sign'' for a signing subkey, ``auth'' for an +authentication subkey, and ``encr'' for an encryption subkey +(``encrypt'' can be used as alias for ``encr''). The valid +combinations depend on the algorithm. The @code{expire} argument can be used to specify an expiration date -for the subkey. Several formats are supported; commonly the ISO -YYYY-MM-DD format is used. The values ``never'', ``none'', or ``-'' -can be used for no expiration date. +for the key. Several formats are supported; commonly the ISO formats +``YYYY-MM-DD'' or ``YYYYMMDDThhmmss'' are used. To make the key +expire in N seconds, N days, N weeks, N months, or N years use +``seconds=N'', ``Nd'', ``Nw'', ``Nm'', or ``Ny'' respectively. Not +specifying a value, or using ``-'' results in a key expiring in a +reasonable default interval. The values ``never'', ``none'' can be +used for no expiration date. @item --generate-key @opindex generate-key diff --git a/tests/openpgp/quick-key-manipulation.scm b/tests/openpgp/quick-key-manipulation.scm index c0007d4..7ede5e9 100755 --- a/tests/openpgp/quick-key-manipulation.scm +++ b/tests/openpgp/quick-key-manipulation.scm @@ -121,6 +121,10 @@ '(() (- - -) (default default never) + (rsa "sign auth encr" "seconds=600") ;; GPGME uses this + (rsa "auth,encr" "2") ;; "without a letter, days is assumed" + (rsa "sign" "2105-01-01") ;; "last year GnuPG can represent is 2105" + (rsa "sign" "21050101T115500") ;; "last year GnuPG can represent is 2105" (rsa sign "2d") (rsa1024 sign "2w") (rsa2048 encr "2m") @@ -136,6 +140,35 @@ (lambda (subkey) (assert (= 1 (:alg subkey))) (assert (string-contains? (:cap subkey) "s")) + (assert (string-contains? (:cap subkey) "a")) + (assert (string-contains? (:cap subkey) "e")) + (assert (time-matches? (+ (get-time) 600) + (string->number (:expire subkey)) + (minutes->seconds 5)))) + (lambda (subkey) + (assert (= 1 (:alg subkey))) + (assert (string-contains? (:cap subkey) "a")) + (assert (string-contains? (:cap subkey) "e")) + (assert (time-matches? (+ (get-time) (days->seconds 2)) + (string->number (:expire subkey)) + (minutes->seconds 5)))) + (lambda (subkey) + (assert (= 1 (:alg subkey))) + (assert (string-contains? (:cap subkey) "s")) + (assert (time-matches? 4260207600 ;; 2105-01-01 + (string->number (:expire subkey)) + ;; This is off by 12h, but I guess it just + ;; choses the middle of the day. + (days->seconds 1)))) + (lambda (subkey) + (assert (= 1 (:alg subkey))) + (assert (string-contains? (:cap subkey) "s")) + (assert (time-matches? 4260254100 ;; UTC 2105-01-01 11:55:00 + (string->number (:expire subkey)) + (minutes->seconds 5)))) + (lambda (subkey) + (assert (= 1 (:alg subkey))) + (assert (string-contains? (:cap subkey) "s")) (assert (time-matches? (+ (get-time) (days->seconds 2)) (string->number (:expire subkey)) (minutes->seconds 5)))) commit 127e1e532da4083ccd3c307555b6177fab16f408 Author: Justus Winter Date: Wed Feb 15 14:50:44 2017 +0100 tests: Check expiration times of created keys. * tests/gpgscm/ffi.c (do_get_time): New function. (ffi_init): Expose new function. * tests/gpgscm/ffi.scm (get-time): Document new function. * tests/gpgscm/time.scm: New file. * tests/openpgp/quick-key-manipulation.scm: Use the new facilities to check the expiration times of created keys. * tests/openpgp/tofu.scm: Use the new module. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index c91d4aa..42facee 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -502,6 +502,14 @@ do_get_isotime (scheme *sc, pointer args) } static pointer +do_get_time (scheme *sc, pointer args) +{ + FFI_PROLOG (); + FFI_ARGS_DONE_OR_RETURN (sc, args); + FFI_RETURN_INT (sc, gnupg_get_time ()); +} + +static pointer do_getpid (scheme *sc, pointer args) { FFI_PROLOG (); @@ -1347,6 +1355,7 @@ ffi_init (scheme *sc, const char *argv0, const char *scriptname, ffi_define_function (sc, mkdir); ffi_define_function (sc, rmdir); ffi_define_function (sc, get_isotime); + ffi_define_function (sc, get_time); ffi_define_function (sc, getpid); /* Random numbers. */ diff --git a/tests/gpgscm/ffi.scm b/tests/gpgscm/ffi.scm index b62fd1f..3f2e553 100644 --- a/tests/gpgscm/ffi.scm +++ b/tests/gpgscm/ffi.scm @@ -47,3 +47,6 @@ ;; Low-level mechanism to terminate the process. (ffi-define (_exit status)) + +;; Get the current time in seconds since the epoch. +(ffi-define (get-time)) diff --git a/tests/gpgscm/time.scm b/tests/gpgscm/time.scm new file mode 100644 index 0000000..a9b06d0 --- /dev/null +++ b/tests/gpgscm/time.scm @@ -0,0 +1,42 @@ +;; Simple time manipulation library. +;; +;; Copyright (C) 2017 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see . + +;; This library mimics what GnuPG thinks about expiration times. +;; Granularity is one second. Its focus is not on correctness. + +;; Conversion functions. +(define (minutes->seconds minutes) + (* minutes 60)) +(define (hours->seconds hours) + (* hours 60 60)) +(define (days->seconds days) + (* days 24 60 60)) +(define (weeks->seconds weeks) + (days->seconds (* weeks 7))) +(define (months->seconds months) + (days->seconds (* months 30))) +(define (years->seconds years) + (days->seconds (* years 365))) + +(define (time-matches? a b slack) + (< (abs (- a b)) slack)) +(assert (time-matches? (hours->seconds 1) (hours->seconds 2) (hours->seconds 2))) +(assert (time-matches? (hours->seconds 2) (hours->seconds 1) (hours->seconds 2))) +(assert (not (time-matches? (hours->seconds 4) (hours->seconds 1) (hours->seconds 2)))) +(assert (not (time-matches? (hours->seconds 1) (hours->seconds 4) (hours->seconds 2)))) diff --git a/tests/openpgp/quick-key-manipulation.scm b/tests/openpgp/quick-key-manipulation.scm index d43f7b5..c0007d4 100755 --- a/tests/openpgp/quick-key-manipulation.scm +++ b/tests/openpgp/quick-key-manipulation.scm @@ -1,6 +1,6 @@ #!/usr/bin/env gpgscm -;; Copyright (C) 2016 g10 Code GmbH +;; Copyright (C) 2016-2017 g10 Code GmbH ;; ;; This file is part of GnuPG. ;; @@ -18,6 +18,7 @@ ;; along with this program; if not, see . (load (with-path "defs.scm")) +(load (with-path "time.scm")) (setup-environment) ;; XXX because of --always-trust, the trustdb is not created. @@ -91,8 +92,9 @@ ;; Make the key expire in one year. (call-check `(, at gpg --quick-set-expire ,fpr "1y")) -;; XXX It'd be nice to check that the value is right. -(assert (not (equal? "" (expiration-time fpr)))) +(assert (time-matches? (+ (get-time) (years->seconds 1)) + (string->number (expiration-time fpr)) + (minutes->seconds 5))) ;; @@ -134,21 +136,29 @@ (lambda (subkey) (assert (= 1 (:alg subkey))) (assert (string-contains? (:cap subkey) "s")) - (assert (not (equal? "" (:expire subkey))))) + (assert (time-matches? (+ (get-time) (days->seconds 2)) + (string->number (:expire subkey)) + (minutes->seconds 5)))) (lambda (subkey) (assert (= 1 (:alg subkey))) (assert (= 1024 (:length subkey))) (assert (string-contains? (:cap subkey) "s")) - (assert (not (equal? "" (:expire subkey))))) + (assert (time-matches? (+ (get-time) (weeks->seconds 2)) + (string->number (:expire subkey)) + (minutes->seconds 5)))) (lambda (subkey) (assert (= 1 (:alg subkey))) (assert (= 2048 (:length subkey))) (assert (string-contains? (:cap subkey) "e")) - (assert (not (equal? "" (:expire subkey))))) + (assert (time-matches? (+ (get-time) (months->seconds 2)) + (string->number (:expire subkey)) + (minutes->seconds 5)))) (lambda (subkey) (assert (= 1 (:alg subkey))) (assert (= 4096 (:length subkey))) (assert (string-contains? (:cap subkey) "s")) (assert (string-contains? (:cap subkey) "a")) - (assert (not (equal? "" (:expire subkey))))) + (assert (time-matches? (+ (get-time) (years->seconds 2)) + (string->number (:expire subkey)) + (minutes->seconds 5)))) #f)) diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm index ca5786b..2e32765 100755 --- a/tests/openpgp/tofu.scm +++ b/tests/openpgp/tofu.scm @@ -18,6 +18,7 @@ ;; along with this program; if not, see . (load (with-path "defs.scm")) +(load (with-path "time.scm")) (setup-environment) (define GPGTIME 1480943782) @@ -25,8 +26,6 @@ ;; Generate a --faked-system-time parameter for a particular offset. (define (faketime delta) (string-append "--faked-system-time=" (number->string (+ GPGTIME delta)))) -;; A convenience function for the above. -(define (days->seconds days) (* days 24 60 60)) ;; Redefine GPG without --always-trust and a fixed time. (define GPG `(,(tool 'gpg) --no-permission-warning ,(faketime 0))) ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 30 +++++++++++------ tests/gpgscm/ffi.c | 9 +++++ tests/gpgscm/ffi.scm | 3 ++ tests/gpgscm/time.scm | 42 +++++++++++++++++++++++ tests/openpgp/quick-key-manipulation.scm | 57 ++++++++++++++++++++++++++++---- tests/openpgp/tofu.scm | 3 +- 6 files changed, 124 insertions(+), 20 deletions(-) create mode 100644 tests/gpgscm/time.scm hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 15 16:08:15 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 15 Feb 2017 16:08:15 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-78-g2f7b6cb Message-ID: This is an 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 2f7b6cb279ea0ee27364fbb2b12df47e76166a39 (commit) from 90d383f1eb07fc823518dea10eb15ca390f5cf8e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f7b6cb279ea0ee27364fbb2b12df47e76166a39 Author: Justus Winter Date: Wed Feb 15 16:03:12 2017 +0100 tests,build: Fix distcheck. * tests/gpgscm/Makefile.am (EXTRA_DIST): Add 'time.scm'. Fixes-commit: 127e1e532da4083ccd3c307555b6177fab16f408 Signed-off-by: Justus Winter diff --git a/tests/gpgscm/Makefile.am b/tests/gpgscm/Makefile.am index 9a5edc2..8942c7c 100644 --- a/tests/gpgscm/Makefile.am +++ b/tests/gpgscm/Makefile.am @@ -25,7 +25,8 @@ EXTRA_DIST = \ lib.scm \ repl.scm \ t-child.scm \ - tests.scm + tests.scm \ + time.scm AM_CPPFLAGS = -I$(top_srcdir)/common include $(top_srcdir)/am/cmacros.am ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 15 16:47:32 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 15 Feb 2017 16:47:32 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-75-gde708e5 Message-ID: This is an 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 de708e5934cda380dbc3ae51f587c09041de7562 (commit) via 27544d0a74267ab6057dc816ea3311bc9149a200 (commit) via 25f0435a0022a70af77660d72d33f17bec2d4e51 (commit) via 6df6e01ed5a581765d245bf7303cda4497d0eb22 (commit) from 92adc9bbf640eb5d9177d3ba0189e0f6cee4e995 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit de708e5934cda380dbc3ae51f587c09041de7562 Author: Justus Winter Date: Wed Feb 15 16:17:13 2017 +0100 core: Fix expiration time handling when creating keys. * NEWS: Update. * doc/gpgme.texi (gpgme_op_createkey): Clarify the meaning of the 'expire' parameter. (GPGME_CREATE_NOEXPIRE): Document new flag. (gpgme_op_createsubkey): Clarify the meaning of the 'expire' parameter. * src/engine-gpg.c (gpg_add_algo_usage_expire): Fix handling of the expiration time. * src/gpgme.h.in (GPGME_CREATE_NOEXPIRE): New macro. -- Previously, the documentation stated that the expiration time was an absolute timestamp. However, this value was passed using the 'seconds=N' syntax to GnuPG which specifies the expiration time in seconds relative to the creation time. Fix the documentation. Furthermore, the documentation stated that using 0 results in keys that do not expire. This was communicated to GnuPG by using the implicit default. However, as of GnuPG 2.1.17, the default was changed to create keys that expire within a reasonable timespan. Fix this discrepancy by aligning the behavior with recent GnuPG versions: 0 means use a reasonable default, and introduce a flag that can be used to create keys that do not expire. Communicate this explicitly to GnuPG. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 0735882..82f403c 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ Noteworthy changes in version 1.8.1 (unreleased) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_strerror_r CHANGED: Use gpgme_error_t (compatible type). gpgme_data_set_flag CHANGED: Return gpgme_error_t (compatible type). + gpgme_op_createkey CHANGED: Meaning of 'expire' parameter. + gpgme_op_createsubkey CHANGED: Meaning of 'expire' parameter. + GPGME_CREATE_NOEXPIRE NEW. cpp: Context::revUid(const Key&, const char*) NEW. cpp: Context::startRevUid(const Key&, const char*) NEW. cpp: Context::addUid(const Key&, const char*) NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index e058fba..c088cfe 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3612,13 +3612,14 @@ primary key plus a secondary key (subkey). @var{reserved} must be set to zero. - at var{expires} can be set to the number of seconds since Epoch of the -desired expiration date in UTC for the new key. Using 0 does not -set an expiration date. Note that this parameter takes an unsigned long -value and not a @code{time_t} to avoid problems on systems which use a -signed 32 bit @code{time_t}. Note further that the OpenPGP protocol -uses 32 bit values for timestamps and thus can only encode dates up to -the year 2106. + at var{expires} specifies the expiration time in seconds. If you supply +0, a reasonable expiration time is chosen. Use the flag + at code{GPGME_CREATE_NOEXPIRE} to create keys that do not expire. Note +that this parameter takes an unsigned long value and not a + at code{time_t} to avoid problems on systems which use a signed 32 bit + at code{time_t}. Note further that the OpenPGP protocol uses 32 bit +values for timestamps and thus can only encode dates up to the year +2106. @var{extrakey} is currently not used and must be set to @code{NULL}. A future version of GPGME may use this parameter to create X.509 keys. @@ -3660,6 +3661,9 @@ The engine does not allow the creation of a key with a user ID already existing in the local key database. This flag can be used to override this check. + at item GPGME_CREATE_NOEXPIRE +Request generation of keys that do not expire. + @end table After the operation completed successfully, information about the @@ -3719,13 +3723,14 @@ able to already handle such future algorithms. @var{reserved} must be set to zero. - at var{expires} can be set to the number of seconds since Epoch of the -desired expiration date in UTC for the new subkey. Using 0 does not -set an expiration date. Note that this parameter takes an unsigned long -value and not a @code{time_t} to avoid problems on systems which use a -signed 32 bit @code{time_t}. Note further that the OpenPGP protocol -uses 32 bit values for timestamps and thus can only encode dates up to -the year 2106. + at var{expires} specifies the expiration time in seconds. If you supply +0, a reasonable expiration time is chosen. Use the flag + at code{GPGME_CREATE_NOEXPIRE} to create keys that do not expire. Note +that this parameter takes an unsigned long value and not a + at code{time_t} to avoid problems on systems which use a signed 32 bit + at code{time_t}. Note further that the OpenPGP protocol uses 32 bit +values for timestamps and thus can only encode dates up to the year +2106. @var{flags} takes the same values as described above for @code{gpgme_op_createkey}. diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 21ca02a..3443600 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2076,7 +2076,8 @@ gpg_add_algo_usage_expire (engine_gpg_t gpg, /* This condition is only required to allow the use of gpg < 2.1.16 */ if (algo || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR - | GPGME_CREATE_CERT | GPGME_CREATE_AUTH)) + | GPGME_CREATE_CERT | GPGME_CREATE_AUTH + | GPGME_CREATE_NOEXPIRE)) || expires) { err = add_arg (gpg, algo? algo : "default"); @@ -2090,11 +2091,18 @@ gpg_add_algo_usage_expire (engine_gpg_t gpg, (flags & GPGME_CREATE_AUTH)? " auth":""); err = add_arg (gpg, *tmpbuf? tmpbuf : "default"); } - if (!err && expires) + if (!err) { - char tmpbuf[8+20]; - snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires); - err = add_arg (gpg, tmpbuf); + if (flags & GPGME_CREATE_NOEXPIRE) + err = add_arg (gpg, "never"); + else if (expires == 0) + err = add_arg (gpg, "-"); + else + { + char tmpbuf[8+20]; + snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires); + err = add_arg (gpg, tmpbuf); + } } } else diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 7f2d34f..f76689e 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1637,6 +1637,7 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx, #define GPGME_CREATE_WANTPUB (1 << 10) /* Return the public key. */ #define GPGME_CREATE_WANTSEC (1 << 11) /* Return the secret key. */ #define GPGME_CREATE_FORCE (1 << 12) /* Force creation. */ +#define GPGME_CREATE_NOEXPIRE (1 << 13) /* Create w/o expiration. */ /* An object to return result from a key generation. * This structure shall be considered read-only and an application commit 27544d0a74267ab6057dc816ea3311bc9149a200 Author: Justus Winter Date: Wed Feb 15 11:31:27 2017 +0100 python: Fix build system integration. * lang/python/Makefile.am (copystamp): Also copy the setup script, and link the header files. (all-local): Use local setup script. (sdist): Fix Python source distribution creation. (CLEANFILES): Remove now obsolete files. (install-exec-local): Use local setup script. * lang/python/setup.py.in: Adjust relative paths to in-tree files. Fixes-commit: fe65a26ab584bd70fad45c7c4d44330e30a748a4 Signed-off-by: Justus Winter diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am index 908f622..2724d86 100644 --- a/lang/python/Makefile.am +++ b/lang/python/Makefile.am @@ -46,47 +46,48 @@ COPY_FILES_GPG = \ # For VPATH builds we need to copy some files because Python's # distutils are not VPATH-aware. -copystamp: $(COPY_FILES) $(COPY_FILES_GPG) data.h config.h +copystamp: $(COPY_FILES) $(COPY_FILES_GPG) + for F in $(COPY_FILES) $(COPY_FILES_GPG) ; do if [ $$F -nt $@ ]; then echo $F ; fi ; done for VERSION in $(PYTHON_VERSIONS); do \ $(MKDIR_P) python$${VERSION}-gpg/gpg && \ cp -R $(COPY_FILES) python$${VERSION}-gpg && \ + cp setup.py python$${VERSION}-gpg && \ cp gpg/version.py python$${VERSION}-gpg/gpg && \ + ln -sf "$(abs_top_srcdir)/src/data.h" python$${VERSION}-gpg && \ + ln -sf "$(abs_top_builddir)/config.h" python$${VERSION}-gpg && \ cp -R $(COPY_FILES_GPG) python$${VERSION}-gpg/gpg ; \ done touch $@ -data.h: - ln -s "$(top_srcdir)/src/data.h" . - -config.h: - ln -s "$(top_builddir)/config.h" . - all-local: copystamp set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \ PYTHON="$$1" ; shift ; \ cd python$${VERSION}-gpg && \ CFLAGS="$(CFLAGS)" \ - $$PYTHON ../setup.py build --verbose ; \ + $$PYTHON setup.py build --verbose ; \ cd .. ; \ done -dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc: copystamp +python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \ +python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc: copystamp + cd python$(PYTHON_VERSION)-gpg && \ CFLAGS="$(CFLAGS)" \ $(PYTHON) setup.py sdist --verbose - gpg2 --detach-sign --armor dist/gpg-$(VERSION).tar.gz + gpg2 --detach-sign --armor python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz .PHONY: prepare prepare: copystamp .PHONY: sdist -sdist: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc +sdist: python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \ + python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc .PHONY: upload -upload: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc +upload: python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \ + python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc twine upload $^ -CLEANFILES = gpgme.h errors.i gpgme_wrap.c gpg/gpgme.py \ - data.h config.h copystamp +CLEANFILES = copystamp # Remove the rest. # @@ -104,7 +105,7 @@ install-exec-local: set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \ PYTHON="$$1" ; shift ; \ cd python$${VERSION}-gpg && \ - $$PYTHON ../setup.py install \ + $$PYTHON setup.py install \ --prefix $(DESTDIR)$(prefix) \ --record files.txt \ --verbose ; \ diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index 5b5d5be..e32237d 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -34,12 +34,12 @@ in_tree = False extra_swig_opts = [] extra_macros = dict() -if os.path.exists("../../src/gpgme-config"): +if os.path.exists("../../../src/gpgme-config"): # In-tree build. in_tree = True - gpgme_config = ["../../src/gpgme-config"] + gpgme_config_flags - gpgme_h = "../../src/gpgme.h" - library_dirs = ["../../src/.libs"] # XXX uses libtool internals + gpgme_config = ["../../../src/gpgme-config"] + gpgme_config_flags + gpgme_h = "../../../src/gpgme.h" + library_dirs = ["../../../src/.libs"] # XXX uses libtool internals extra_macros.update( HAVE_CONFIG_H=1, HAVE_DATA_H=1, commit 25f0435a0022a70af77660d72d33f17bec2d4e51 Author: Justus Winter Date: Wed Feb 15 11:28:02 2017 +0100 python: Update lists of functions returning gpgme_error_t. * lang/python/gpg/core.py (Context._errorcheck): Add instructions how to update the list. Update list. (Data._errorcheck): Likewise. (Context.set_engine_info): Simplify. Signed-off-by: Justus Winter diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index 18a7e3a..3a63516 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -628,22 +628,27 @@ class Context(GpgmeWrapper): def _errorcheck(self, name): """This function should list all functions returning gpgme_error_t""" + # The list of functions is created using: + # + # $ grep '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \ + # | grep -v _op_ | awk "/\(gpgme_ctx/ { printf (\"'%s',\\n\", \$2) } " return ((name.startswith('gpgme_op_') and not name.endswith('_result')) or name in { + 'gpgme_new', 'gpgme_set_ctx_flag', 'gpgme_set_protocol', 'gpgme_set_sub_protocol', 'gpgme_set_keylist_mode', 'gpgme_set_pinentry_mode', 'gpgme_set_locale', - 'gpgme_set_engine_info', + 'gpgme_ctx_set_engine_info', 'gpgme_signers_add', - 'gpgme_get_sig_key', 'gpgme_sig_notation_add', + 'gpgme_set_sender', 'gpgme_cancel', 'gpgme_cancel_async', - 'gpgme_cancel_get_key', + 'gpgme_get_key', }) _boolean_properties = {'armor', 'textmode', 'offline'} @@ -850,8 +855,7 @@ class Context(GpgmeWrapper): home_dir -- configuration directory (unchanged if None) """ - errorcheck(gpgme.gpgme_ctx_set_engine_info( - self.wrapped, proto, file_name, home_dir)) + self.ctx_set_engine_info(proto, file_name, home_dir) def wait(self, hang): """Wait for asynchronous call to finish. Wait forever if hang is True. @@ -905,11 +909,19 @@ class Data(GpgmeWrapper): def _errorcheck(self, name): """This function should list all functions returning gpgme_error_t""" + # This list is compiled using + # + # $ grep -v '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \ + # | awk "/\(gpgme_data_t/ { printf (\"'%s',\\n\", \$2) } " | sed "s/'\\*/'/" return name not in { + 'gpgme_data_read', + 'gpgme_data_write', + 'gpgme_data_seek', + 'gpgme_data_release', 'gpgme_data_release_and_get_mem', 'gpgme_data_get_encoding', - 'gpgme_data_seek', 'gpgme_data_get_file_name', + 'gpgme_data_identify', } def __init__(self, string=None, file=None, offset=None, commit 6df6e01ed5a581765d245bf7303cda4497d0eb22 Author: Justus Winter Date: Wed Feb 15 09:45:46 2017 +0100 core: Fix error types. * NEWS: Update. * src/data.c (gpgme_data_set_flag): Return a 'gpgme_error_t'. * src/error.c (gpgme_strerror_r): Fix type of first argument. * src/gpgme.h.in (gpgme_strerror_r): Adapt. (gpgme_data_set_flag): Likewise. -- Fix for consistency. This should not pose problems, because typedef gpg_error_t gpgme_error_t. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index a974ec7..0735882 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ Noteworthy changes in version 1.8.1 (unreleased) * Interface changes relative to the 1.8.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_strerror_r CHANGED: Use gpgme_error_t (compatible type). + gpgme_data_set_flag CHANGED: Return gpgme_error_t (compatible type). cpp: Context::revUid(const Key&, const char*) NEW. cpp: Context::startRevUid(const Key&, const char*) NEW. cpp: Context::addUid(const Key&, const char*) NEW. diff --git a/src/data.c b/src/data.c index e4e9ee3..6fe7e71 100644 --- a/src/data.c +++ b/src/data.c @@ -259,7 +259,7 @@ gpgme_data_get_file_name (gpgme_data_t dh) /* Set a flag for the data object DH. See the manual for details. */ -gpg_error_t +gpgme_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, diff --git a/src/error.c b/src/error.c index a84b867..d9c5fd0 100644 --- a/src/error.c +++ b/src/error.c @@ -41,7 +41,7 @@ gpgme_strerror (gpgme_error_t err) large enough, ERANGE is returned and BUF contains as much of the beginning of the error string as fits into the buffer. */ int -gpgme_strerror_r (gpg_error_t err, char *buf, size_t buflen) +gpgme_strerror_r (gpgme_error_t err, char *buf, size_t buflen) { return gpg_strerror_r (err, buf, buflen); } diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 67c139b..7f2d34f 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -177,7 +177,7 @@ const char *gpgme_strerror (gpgme_error_t err); contains the string describing the error. If the buffer was not large enough, ERANGE is returned and BUF contains as much of the beginning of the error string as fits into the buffer. */ -int gpgme_strerror_r (gpg_error_t err, char *buf, size_t buflen); +int gpgme_strerror_r (gpgme_error_t err, char *buf, size_t buflen); /* Return a pointer to a string containing a description of the error source in the error value ERR. */ @@ -1161,8 +1161,8 @@ 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); +gpgme_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); ----------------------------------------------------------------------- Summary of changes: NEWS | 5 +++++ doc/gpgme.texi | 33 +++++++++++++++++++-------------- lang/python/Makefile.am | 31 ++++++++++++++++--------------- lang/python/gpg/core.py | 24 ++++++++++++++++++------ lang/python/setup.py.in | 8 ++++---- src/data.c | 2 +- src/engine-gpg.c | 18 +++++++++++++----- src/error.c | 2 +- src/gpgme.h.in | 7 ++++--- 9 files changed, 81 insertions(+), 49 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 15 19:23:41 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 15 Feb 2017 19:23:41 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-81-ga3509e1 Message-ID: This is an 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 a3509e12b6626a585ce7da6ceed8cfddcba2460f (commit) via a75325faf163275674a91971e75f1018035ca348 (commit) via da2ba20868093e3054d18adc2b1bc56cb23e4ba7 (commit) from 2f7b6cb279ea0ee27364fbb2b12df47e76166a39 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a3509e12b6626a585ce7da6ceed8cfddcba2460f Author: Werner Koch Date: Wed Feb 15 19:17:08 2017 +0100 libdns: Workaround for bracketed numerical addresses. * dirmngr/dns-stuff.c (resolve_name_libdns): Work around an incompatibility between the glibc resolver and libdns. Signed-off-by: Werner Koch diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index e57ddc7..074e012 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -719,6 +719,7 @@ resolve_name_libdns (const char *name, unsigned short port, struct addrinfo *ent; char portstr_[21]; char *portstr = NULL; + char *namebuf = NULL; int derr; *r_dai = NULL; @@ -731,8 +732,6 @@ resolve_name_libdns (const char *name, unsigned short port, hints.ai_flags = AI_ADDRCONFIG; if (r_canonname) hints.ai_flags |= AI_CANONNAME; - if (is_ip_address (name)) - hints.ai_flags |= AI_NUMERICHOST; if (port) { @@ -744,6 +743,25 @@ resolve_name_libdns (const char *name, unsigned short port, if (err) goto leave; + + if (is_ip_address (name)) + { + hints.ai_flags |= AI_NUMERICHOST; + /* libdns does not grok brackets - remove them. */ + if (*name == '[' && name[strlen(name)-1] == ']') + { + namebuf = xtrymalloc (strlen (name)); + if (!namebuf) + { + err = gpg_error_from_syserror (); + goto leave; + } + strcpy (namebuf, name+1); + namebuf[strlen (namebuf)-1] = 0; + name = namebuf; + } + } + ai = dns_ai_open (name, portstr, 0, &hints, res, &derr); if (!ai) { @@ -825,6 +843,7 @@ resolve_name_libdns (const char *name, unsigned short port, else *r_dai = daihead; + xfree (namebuf); return err; } #endif /*USE_LIBDNS*/ @@ -1208,7 +1227,7 @@ is_ip_address (const char *name) if (*name == '[') return 6; /* yes: A legal DNS name may not contain this character; - this mut be bracketed v6 address. */ + this must be bracketed v6 address. */ if (*name == '.') return 0; /* No. A leading dot is not a valid IP address. */ commit a75325faf163275674a91971e75f1018035ca348 Author: Werner Koch Date: Wed Feb 15 19:14:20 2017 +0100 dirmngr: Do PTR lookups only for 'keyserver --hosttable'. * dirmngr/ks-engine-hkp.c (hostinfo_s): Remove fields v4addr and v5addr and add fields iporname and iporname_valid. (create_new_hostinfo): Clear them. (add_host): Remove the code to set the v4addr and v6addr fields. (ks_hkp_print_hosttable): Remove printing of the fields. Compute the iporname field and display it. (ks_hkp_reload): Force re-computing of the iporname field in ks_hkp_print_hosttable. -- GnuPG-bug-id: 2928 Signed-off-by: Werner Koch diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 6505ca9..e39d60e 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -82,16 +82,13 @@ struct hostinfo_s unsigned int v6:1; /* Host supports AF_INET6. */ unsigned int onion:1;/* NAME is an onion (Tor HS) address. */ unsigned int dead:1; /* Host is currently unresponsive. */ + unsigned int iporname_valid:1; /* The field IPORNAME below is valid */ + /* (but may be NULL) */ time_t died_at; /* The time the host was marked dead. If this is 0 the host has been manually marked dead. */ char *cname; /* Canonical name of the host. Only set if this is a pool or NAME has a numerical IP address. */ - char *v4addr; /* A string with the v4 IP address of the host. - NULL if NAME has a numeric IP address or no v4 - address is available. */ - char *v6addr; /* A string with the v6 IP address of the host. - NULL if NAME has a numeric IP address or no v6 - address is available. */ + char *iporname; /* Numeric IP address or name for printing. */ unsigned short port; /* The port used by the host, 0 if unknown. */ char name[1]; /* The hostname. */ }; @@ -128,10 +125,10 @@ create_new_hostinfo (const char *name) hi->v6 = 0; hi->onion = 0; hi->dead = 0; + hi->iporname_valid = 0; hi->died_at = 0; hi->cname = NULL; - hi->v4addr = NULL; - hi->v6addr = NULL; + hi->iporname = NULL; hi->port = 0; /* Add it to the hosttable. */ @@ -295,7 +292,6 @@ add_host (const char *name, int is_pool, gpg_error_t tmperr; char *tmphost; int idx, tmpidx; - int is_numeric = 0; int i; idx = find_hostinfo (name); @@ -305,7 +301,6 @@ add_host (const char *name, int is_pool, /* For a pool immediately convert the address to a string. */ tmperr = resolve_dns_addr (ai->addr, ai->addrlen, (DNS_NUMERICHOST | DNS_WITHBRACKET), &tmphost); - is_numeric = 1; } else if (!is_ip_address (name)) { @@ -320,13 +315,9 @@ add_host (const char *name, int is_pool, else { /* Do a PTR lookup on AI. If a name was not found the function - * returns the numeric address (with brackets) and we set a flag - * so that we know that the conversion to a numerical string has - * already be done. */ + * returns the numeric address (with brackets). */ tmperr = resolve_dns_addr (ai->addr, ai->addrlen, DNS_WITHBRACKET, &tmphost); - if (tmphost && is_ip_address (tmphost)) - is_numeric = 1; } if (tmperr) @@ -360,42 +351,16 @@ add_host (const char *name, int is_pool, } else /* Set or update the entry. */ { - char *ipaddr = NULL; - if (port) hosttable[tmpidx]->port = port; - /* If TMPHOST is not yet a numerical value do this now. - * Note: This is a simple string operations and not a PTR - * lookup (due to DNS_NUMERICHOST). */ - if (!is_numeric) - { - xfree (tmphost); - tmperr = resolve_dns_addr (ai->addr, ai->addrlen, - (DNS_NUMERICHOST - | DNS_WITHBRACKET), - &tmphost); - if (tmperr) - log_info ("resolve_dns_addr failed: %s\n", - gpg_strerror (tmperr)); - else - { - ipaddr = tmphost; - tmphost = NULL; - } - } - if (ai->family == AF_INET6) { hosttable[tmpidx]->v6 = 1; - xfree (hosttable[tmpidx]->v6addr); - hosttable[tmpidx]->v6addr = ipaddr; } else if (ai->family == AF_INET) { hosttable[tmpidx]->v4 = 1; - xfree (hosttable[tmpidx]->v4addr); - hosttable[tmpidx]->v4addr = ipaddr; } else BUG (); @@ -832,6 +797,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl) if (err) return err; + /* FIXME: We need a lock for the hosttable. */ curtime = gnupg_get_time (); for (idx=0; idx < hosttable_size; idx++) if ((hi=hosttable[idx])) @@ -843,16 +809,82 @@ ks_hkp_print_hosttable (ctrl_t ctrl) } else diedstr = died = NULL; - err = ks_printf_help (ctrl, "%3d %s %s %s %s%s%s%s%s%s%s%s\n", + + if (!hi->iporname_valid) + { + char *canon = NULL; + + xfree (hi->iporname); + hi->iporname = NULL; + + /* Do a lookup just for the display purpose. */ + if (hi->onion || hi->pool) + ; + else if (is_ip_address (hi->name)) + { + dns_addrinfo_t aibuf, ai; + + /* Turn the numerical IP address string into an AI and + * then do a DNS PTR lookup. */ + if (!resolve_dns_name (hi->name, 0, 0, + SOCK_STREAM, + &aibuf, &canon)) + { + if (canon && is_ip_address (canon)) + { + xfree (canon); + canon = NULL; + } + for (ai = aibuf; !canon && ai; ai = ai->next) + { + resolve_dns_addr (ai->addr, ai->addrlen, + DNS_WITHBRACKET, &canon); + if (canon && is_ip_address (canon)) + { + /* We already have the numeric IP - no need to + * display it a second time. */ + xfree (canon); + canon = NULL; + } + } + } + free_dns_addrinfo (aibuf); + } + else + { + dns_addrinfo_t aibuf, ai; + + /* Get the IP address as a string from a name. Note + * that resolve_dns_addr allocates CANON on success + * and thus terminates the loop. */ + if (!resolve_dns_name (hi->name, 0, + hi->v6? AF_INET6 : AF_INET, + SOCK_STREAM, + &aibuf, NULL)) + { + for (ai = aibuf; !canon && ai; ai = ai->next) + { + resolve_dns_addr (ai->addr, ai->addrlen, + DNS_NUMERICHOST|DNS_WITHBRACKET, + &canon); + } + } + free_dns_addrinfo (aibuf); + } + + hi->iporname = canon; + hi->iporname_valid = 1; + } + + err = ks_printf_help (ctrl, "%3d %s %s %s %s%s%s%s%s%s%s\n", idx, hi->onion? "O" : hi->v6? "6":" ", hi->v4? "4":" ", hi->dead? "d":" ", hi->name, - hi->v6addr? " v6=":"", - hi->v6addr? hi->v6addr:"", - hi->v4addr? " v4=":"", - hi->v4addr? hi->v4addr:"", + hi->iporname? " (":"", + hi->iporname? hi->iporname : "", + hi->iporname? ")":"", diedstr? " (":"", diedstr? diedstr:"", diedstr? ")":"" ); @@ -1059,6 +1091,7 @@ ks_hkp_reload (void) hi = hosttable[idx]; if (!hi) continue; + hi->iporname_valid = 0; if (!hi->dead) continue; hi->dead = 0; commit da2ba20868093e3054d18adc2b1bc56cb23e4ba7 Author: Werner Koch Date: Wed Feb 15 17:03:57 2017 +0100 dirmngr: Avoid PTR lookup for hosts in a pool * dirmngr/ks-engine-hkp.c (add_host): Don't to a PTR lookup for hosts in a pool. -- GnuPG-bug-id: 2928 Signed-off-by: Werner Koch diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 40f3521..6505ca9 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -300,10 +300,17 @@ add_host (const char *name, int is_pool, idx = find_hostinfo (name); - if (!is_pool && !is_ip_address (name)) + if (is_pool) { - /* This is a hostname but not a pool. Use the name - as given without going through resolve_dns_addr. */ + /* For a pool immediately convert the address to a string. */ + tmperr = resolve_dns_addr (ai->addr, ai->addrlen, + (DNS_NUMERICHOST | DNS_WITHBRACKET), &tmphost); + is_numeric = 1; + } + else if (!is_ip_address (name)) + { + /* This is a hostname. Use the name as given without going + * through resolve_dns_addr. */ tmphost = xtrystrdup (name); if (!tmphost) tmperr = gpg_error_from_syserror (); @@ -312,6 +319,10 @@ add_host (const char *name, int is_pool, } else { + /* Do a PTR lookup on AI. If a name was not found the function + * returns the numeric address (with brackets) and we set a flag + * so that we know that the conversion to a numerical string has + * already be done. */ tmperr = resolve_dns_addr (ai->addr, ai->addrlen, DNS_WITHBRACKET, &tmphost); if (tmphost && is_ip_address (tmphost)) @@ -344,8 +355,7 @@ add_host (const char *name, int is_pool, if (tmpidx == -1) { - log_error ("map_host for '%s' problem: %s - '%s'" - " [ignored]\n", + log_error ("map_host for '%s' problem: %s - '%s' [ignored]\n", name, strerror (errno), tmphost); } else /* Set or update the entry. */ @@ -355,6 +365,9 @@ add_host (const char *name, int is_pool, if (port) hosttable[tmpidx]->port = port; + /* If TMPHOST is not yet a numerical value do this now. + * Note: This is a simple string operations and not a PTR + * lookup (due to DNS_NUMERICHOST). */ if (!is_numeric) { xfree (tmphost); ----------------------------------------------------------------------- Summary of changes: dirmngr/dns-stuff.c | 25 +++++++-- dirmngr/ks-engine-hkp.c | 134 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 112 insertions(+), 47 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 16 03:51:39 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 16 Feb 2017 03:51:39 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-82-g7a666cc Message-ID: This is an 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 7a666ccb44f43c4efbaa51c1ca16fc0b37c3399d (commit) from a3509e12b6626a585ce7da6ceed8cfddcba2460f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7a666ccb44f43c4efbaa51c1ca16fc0b37c3399d Author: NIIBE Yutaka Date: Thu Feb 16 11:49:37 2017 +0900 scd: Minor fixes to silence compiler warnings. * scd/app.c (app_reset): Initialize ERR. * scd/scdaemon.c (scd_kick_the_loop, handle_connections): Catch the return value. Signed-off-by: NIIBE Yutaka diff --git a/scd/app.c b/scd/app.c index 29c9dad..b6f3a05 100644 --- a/scd/app.c +++ b/scd/app.c @@ -139,7 +139,7 @@ check_application_conflict (const char *name, app_t app) gpg_error_t app_reset (app_t app, ctrl_t ctrl, int send_reset) { - gpg_error_t err; + gpg_error_t err = 0; if (send_reset) { diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e4b0ef8..f7e9f83 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1182,8 +1182,11 @@ start_connection_thread (void *arg) void scd_kick_the_loop (void) { + int ret; + /* Kick the select loop. */ - write (notify_fd, "", 1); + ret = write (notify_fd, "", 1); + (void)ret; } /* Connection handler loop. Wait for connection requests and spawn a @@ -1308,8 +1311,7 @@ handle_connections (int listen_fd) { char buf[256]; - read (pipe_fd[0], buf, sizeof buf); - ret--; + ret = read (pipe_fd[0], buf, sizeof buf); } if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset)) ----------------------------------------------------------------------- Summary of changes: scd/app.c | 2 +- scd/scdaemon.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 16 11:03:49 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 16 Feb 2017 11:03:49 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-84-g1af733f Message-ID: This is an 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 1af733f37bf6fd55ccac787a7e34c3b3ca002126 (commit) via aef60abe6a1772e18634984a94bd70f57d57ccdd (commit) from 7a666ccb44f43c4efbaa51c1ca16fc0b37c3399d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1af733f37bf6fd55ccac787a7e34c3b3ca002126 Author: Werner Koch Date: Thu Feb 16 10:35:18 2017 +0100 indent: Reformat and extend some comments in dirmngr. -- Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 10757c8..d13d80b 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -154,8 +154,8 @@ compare_serialno (ksba_sexp_t serial1, ksba_sexp_t serial2 ) /* Return a malloced canonical S-Expression with the serial number - converted from the hex string HEXSN. Return NULL on memory - error. */ + * converted from the hex string HEXSN. Return NULL on memory + * error. */ ksba_sexp_t hexsn_to_sexp (const char *hexsn) { @@ -981,7 +981,7 @@ get_certs_bypattern (const char *pattern, /* Return the certificate matching ISSUER_DN and SERIALNO; if it is - not already in the cache, try to find it from other resources. */ + * not already in the cache, try to find it from other resources. */ ksba_cert_t find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno) { @@ -996,8 +996,8 @@ find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno) return cert; /* Ask back to the service requester to return the certificate. - This is because we can assume that he already used the - certificate while checking for the CRL. */ + * This is because we can assume that he already used the + * certificate while checking for the CRL. */ hexsn = serial_hex (serialno); if (!hexsn) { @@ -1093,10 +1093,10 @@ find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno) /* Return the certificate matching SUBJECT_DN and (if not NULL) - KEYID. If it is not already in the cache, try to find it from other - resources. Note, that the external search does not work for user - certificates because the LDAP lookup is on the caCertificate - attribute. For our purposes this is just fine. */ + * KEYID. If it is not already in the cache, try to find it from other + * resources. Note, that the external search does not work for user + * certificates because the LDAP lookup is on the caCertificate + * attribute. For our purposes this is just fine. */ ksba_cert_t find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) { @@ -1107,11 +1107,11 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) ksba_sexp_t subj; /* If we have certificates from an OCSP request we first try to use - them. This is because these certificates will really be the - required ones and thus even in the case that they can't be - uniquely located by the following code we can use them. This is - for example required by Telesec certificates where a keyId is - used but the issuer certificate comes without a subject keyId! */ + * them. This is because these certificates will really be the + * required ones and thus even in the case that they can't be + * uniquely located by the following code we can use them. This is + * for example required by Telesec certificates where a keyId is + * used but the issuer certificate comes without a subject keyId! */ if (ctrl->ocsp_certs && subject_dn) { cert_item_t ci; @@ -1136,8 +1136,7 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) log_debug ("find_cert_bysubject: certificate not in ocsp_certs\n"); } - - /* First we check whether the certificate is cached. */ + /* No check whether the certificate is cached. */ for (seq=0; (cert = get_cert_bysubject (subject_dn, seq)); seq++) { if (!keyid) @@ -1158,15 +1157,15 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) log_debug ("find_cert_bysubject: certificate not in cache\n"); /* Ask back to the service requester to return the certificate. - This is because we can assume that he already used the - certificate while checking for the CRL. */ + * This is because we can assume that he already used the + * certificate while checking for the CRL. */ if (keyid) cert = get_cert_local_ski (ctrl, subject_dn, keyid); else { /* In contrast to get_cert_local_ski, get_cert_local uses any - passed pattern, so we need to make sure that an exact subject - search is done. */ + * passed pattern, so we need to make sure that an exact subject + * search is done. */ char *buf; buf = strconcat ("/", subject_dn, NULL); @@ -1263,7 +1262,6 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) } - /* Return 0 if the certificate is a trusted certificate. Returns GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in case of systems errors. */ @@ -1294,8 +1292,8 @@ is_trusted_cert (ksba_cert_t cert) /* Given the certificate CERT locate the issuer for this certificate - and return it at R_CERT. Returns 0 on success or - GPG_ERR_NOT_FOUND. */ + * and return it at R_CERT. Returns 0 on success or + * GPG_ERR_NOT_FOUND. */ gpg_error_t find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert) { @@ -1331,16 +1329,18 @@ find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert) { issuer_cert = find_cert_bysn (ctrl, s, authidno); } + if (!issuer_cert && keyid) { /* Not found by issuer+s/n. Now that we have an AKI - keyIdentifier look for a certificate with a matching - SKI. */ + * keyIdentifier look for a certificate with a matching + * SKI. */ issuer_cert = find_cert_bysubject (ctrl, issuer_dn, keyid); } + /* Print a note so that the user does not feel too helpless when - an issuer certificate was found and gpgsm prints BAD - signature because it is not the correct one. */ + * an issuer certificate was found and gpgsm prints BAD + * signature because it is not the correct one. */ if (!issuer_cert) { log_info ("issuer certificate "); @@ -1366,8 +1366,8 @@ find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert) } /* If this did not work, try just with the issuer's name and assume - that there is only one such certificate. We only look into our - cache then. */ + * that there is only one such certificate. We only look into our + * cache then. */ if (err || !issuer_cert) { issuer_cert = get_cert_bysubject (issuer_dn, 0); diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c index 337fe6e..f7a23ff 100644 --- a/dirmngr/crlfetch.c +++ b/dirmngr/crlfetch.c @@ -167,10 +167,11 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader) http_release_parsed_uri (uri); if (err && !strncmp (url, "https:", 6)) { - /* Our HTTP code does not support TLS, thus we can't use this - scheme and it is frankly not useful for CRL retrieval anyway. - We resort to using http, assuming that the server also - provides plain http access. */ + /* FIXME: We now support https. + * Our HTTP code does not support TLS, thus we can't use this + * scheme and it is frankly not useful for CRL retrieval anyway. + * We resort to using http, assuming that the server also + * provides plain http access. */ free_this = xtrymalloc (strlen (url) + 1); if (free_this) { @@ -343,10 +344,10 @@ crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader) } -/* Fetch a CA certificate for DN using the default server. This - function only initiates the fetch; fetch_next_cert must be used to - actually read the certificate; end_cert_fetch to end the - operation. */ +/* Fetch a CA certificate for DN using the default server. This + * function only initiates the fetch; fetch_next_cert must be used to + * actually read the certificate; end_cert_fetch to end the + * operation. */ gpg_error_t ca_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, const char *dn) { @@ -417,7 +418,7 @@ fetch_next_cert (cert_fetch_context_t context, /* Fetch the next data from CONTEXT, assuming it is a certificate and return - it as a cert object in R_CERT. */ + * it as a cert object in R_CERT. */ gpg_error_t fetch_next_ksba_cert (cert_fetch_context_t context, ksba_cert_t *r_cert) { diff --git a/dirmngr/misc.c b/dirmngr/misc.c index 2ee6d82..6d7c963 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -62,6 +62,8 @@ hashify_data( const char* data, size_t len ) return hexify_data (buf, 20, 0); } + +/* FIXME: Replace this by hextobin. */ char* hexify_data (const unsigned char* data, size_t len, int with_prefix) { diff --git a/dirmngr/server.c b/dirmngr/server.c index 32ce5bb..bc373f5 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -403,12 +403,11 @@ do_get_cert_local (ctrl_t ctrl, const char *name, const char *command) -/* Ask back to return a certificate for name, given as a regular - gpgsm certificate indentificates (e.g. fingerprint or one of the - other methods). Alternatively, NULL may be used for NAME to - return the current target certificate. Either return the certificate - in a KSBA object or NULL if it is not available. -*/ +/* Ask back to return a certificate for NAME, given as a regular gpgsm + * certificate identifier (e.g. fingerprint or one of the other + * methods). Alternatively, NULL may be used for NAME to return the + * current target certificate. Either return the certificate in a + * KSBA object or NULL if it is not available. */ ksba_cert_t get_cert_local (ctrl_t ctrl, const char *name) { @@ -422,13 +421,12 @@ get_cert_local (ctrl_t ctrl, const char *name) } -/* Ask back to return the issuing certificate for name, given as a - regular gpgsm certificate indentificates (e.g. fingerprint or one - of the other methods). Alternatively, NULL may be used for NAME to - return thecurrent target certificate. Either return the certificate - in a KSBA object or NULL if it is not available. -*/ +/* Ask back to return the issuing certificate for NAME, given as a + * regular gpgsm certificate identifier (e.g. fingerprint or one + * of the other methods). Alternatively, NULL may be used for NAME to + * return the current target certificate. Either return the certificate + * in a KSBA object or NULL if it is not available. */ ksba_cert_t get_issuing_cert_local (ctrl_t ctrl, const char *name) { @@ -441,8 +439,9 @@ get_issuing_cert_local (ctrl_t ctrl, const char *name) return do_get_cert_local (ctrl, name, "SENDISSUERCERT"); } + /* Ask back to return a certificate with subject NAME and a - subjectKeyIdentifier of KEYID. */ + * subjectKeyIdentifier of KEYID. */ ksba_cert_t get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid) { @@ -1773,8 +1772,8 @@ cmd_validate (assuan_context_t ctx, char *line) goto leave; /* If we have this certificate already in our cache, use the cached - version for validation because this will take care of any cached - results. */ + * version for validation because this will take care of any cached + * results. */ { unsigned char fpr[20]; ksba_cert_t tmpcert; diff --git a/dirmngr/validate.c b/dirmngr/validate.c index b3dc9d8..68e1bb3 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -371,7 +371,8 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, int depth, maxdepth; char *issuer = NULL; char *subject = NULL; - ksba_cert_t subject_cert = NULL, issuer_cert = NULL; + ksba_cert_t subject_cert = NULL; + ksba_cert_t issuer_cert = NULL; ksba_isotime_t current_time; ksba_isotime_t exptime; int any_expired = 0; @@ -438,7 +439,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, /* We walk up the chain until we find a trust anchor. */ subject_cert = cert; - maxdepth = 10; + maxdepth = 10; /* Sensible limit on the length of the chain. */ chain = NULL; depth = 0; for (;;) @@ -520,7 +521,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, goto leave; /* Is this a self-signed certificate? */ - if (is_root_cert ( subject_cert, issuer, subject)) + if (is_root_cert (subject_cert, issuer, subject)) { /* Yes, this is our trust anchor. */ if (check_cert_sig (subject_cert, subject_cert) ) @@ -630,9 +631,9 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, dump_cert ("issuer", issuer_cert); } - /* Now check the signature of the certificate. Well, we - should delay this until later so that faked certificates - can't be turned into a DoS easily. */ + /* Now check the signature of the certificate. FIXME: we should + * delay this until later so that faked certificates can't be + * turned into a DoS easily. */ err = check_cert_sig (issuer_cert, subject_cert); if (err) { @@ -669,14 +670,14 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, } } #endif - /* We give a more descriptive error code than the one - returned from the signature checking. */ + /* Return a more descriptive error code than the one + * returned from the signature checking. */ err = gpg_error (GPG_ERR_BAD_CERT_CHAIN); goto leave; } /* Check that the length of the chain is not longer than allowed - by the CA. */ + * by the CA. */ { int chainlen; @@ -722,9 +723,11 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, issuer_cert = NULL; } + /* Even if we have no error here we need to check whether we + * encountered an error somewhere during the checks. Set the error + * code to the most critical one. */ if (!err) - { /* If we encountered an error somewhere during the checks, set - the error code to the most critical one */ + { if (any_expired) err = gpg_error (GPG_ERR_CERT_EXPIRED); else if (any_no_policy_match) @@ -742,19 +745,19 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (!err && mode != VALIDATE_MODE_CRL) { /* Now that everything is fine, walk the chain and check each - certificate for revocations. - - 1. item in the chain - The root certificate. - 2. item - the CA below the root - last item - the target certificate. - - Now for each certificate in the chain check whether it has - been included in a CRL and thus be revoked. We don't do OCSP - here because this does not seem to make much sense. This - might become a recursive process and we should better cache - our validity results to avoid double work. Far worse a - catch-22 may happen for an improper setup hierarchy and we - need a way to break up such a deadlock. */ + * certificate for revocations. + * + * 1. item in the chain - The root certificate. + * 2. item - the CA below the root + * last item - the target certificate. + * + * Now for each certificate in the chain check whether it has + * been included in a CRL and thus be revoked. We don't do OCSP + * here because this does not seem to make much sense. This + * might become a recursive process and we should better cache + * our validity results to avoid double work. Far worse a + * catch-22 may happen for an improper setup hierarchy and we + * need a way to break up such a deadlock. */ err = check_revocations (ctrl, chain); } @@ -773,11 +776,11 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (!err && !(r_trust_anchor && *r_trust_anchor)) { /* With no error we can update the validation cache. We do this - for all certificates in the chain. Note that we can't use - the cache if the caller requested to check the trustiness of - the root certificate himself. Adding such a feature would - require us to also store the fingerprint of root - certificate. */ + * for all certificates in the chain. Note that we can't use + * the cache if the caller requested to check the trustiness of + * the root certificate himself. Adding such a feature would + * require us to also store the fingerprint of root + * certificate. */ chain_item_t citem; time_t validated_at = gnupg_get_time (); @@ -853,8 +856,8 @@ pk_algo_from_sexp (gcry_sexp_t pkey) /* Check the signature on CERT using the ISSUER_CERT. This function - does only test the cryptographic signature and nothing else. It is - assumed that the ISSUER_CERT is valid. */ + * does only test the cryptographic signature and nothing else. It is + * assumed that the ISSUER_CERT is valid. */ static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) { @@ -952,20 +955,23 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) /* Prepare the values for signature verification. At this point we - have these values: - - S_PKEY - S-expression with the issuer's public key. - S_SIG - Signature value as given in the certrificate. - MD - Finalized hash context with hash of the certificate. - ALGO_NAME - Lowercase hash algorithm name + * have these values: + * + * S_PKEY - S-expression with the issuer's public key. + * S_SIG - Signature value as given in the certificate. + * MD - Finalized hash context with hash of the certificate. + * ALGO_NAME - Lowercase hash algorithm name */ digestlen = gcry_md_get_algo_dlen (algo); digest = gcry_md_read (md, algo); if (pk_algo_from_sexp (s_pkey) == GCRY_PK_DSA) { + /* NB.: We support only SHA-1 here because we had problems back + * then to get test data for DSA-2. Meanwhile DSA has been + * replaced by ECDSA which we do not yet support. */ if (digestlen != 20) { - log_error (_("DSA requires the use of a 160 bit hash algorithm\n")); + log_error ("DSA requires the use of a 160 bit hash algorithm\n"); gcry_md_close (md); gcry_sexp_release (s_sig); gcry_sexp_release (s_pkey); @@ -975,7 +981,7 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) (int)digestlen, digest) ) BUG (); } - else /* Not DSA. */ + else /* Not DSA - we assume RSA */ { if ( gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))", algo_name, (int)digestlen, digest) ) commit aef60abe6a1772e18634984a94bd70f57d57ccdd Author: Werner Koch Date: Thu Feb 16 10:19:59 2017 +0100 dirmngr: Replace stpcpy chains by strconcat. * dirmngr/certcache.c (find_cert_bysn): Use strconcat. (find_cert_bysubject): Ditto. * dirmngr/http.c (store_header): Ditto. * dirmngr/ldap.c (make_url): Ditto. * dirmngr/server.c (get_cert_local_ski): Ditto. (do_get_cert_local): Use xstrconcat. -- Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index ad85d99..10757c8 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -1004,15 +1004,15 @@ find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno) log_error ("serial_hex() failed\n"); return NULL; } - buf = xtrymalloc (1 + strlen (hexsn) + 1 + strlen (issuer_dn) + 1); + buf = strconcat ("#", hexsn, "/", issuer_dn, NULL); if (!buf) { log_error ("can't allocate enough memory: %s\n", strerror (errno)); xfree (hexsn); return NULL; } - strcpy (stpcpy (stpcpy (stpcpy (buf, "#"), hexsn),"/"), issuer_dn); xfree (hexsn); + cert = get_cert_local (ctrl, buf); xfree (buf); if (cert) @@ -1169,13 +1169,12 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) search is done. */ char *buf; - buf = xtrymalloc (1 + strlen (subject_dn) + 1); + buf = strconcat ("/", subject_dn, NULL); if (!buf) { log_error ("can't allocate enough memory: %s\n", strerror (errno)); return NULL; } - strcpy (stpcpy (buf, "/"), subject_dn); cert = get_cert_local (ctrl, buf); xfree (buf); } diff --git a/dirmngr/http.c b/dirmngr/http.c index fe9c3c7..0889cb1 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2150,11 +2150,10 @@ store_header (http_t hd, char *line) if (h) { /* We have already seen a line with that name. Thus we assume - it is a comma separated list and merge them. */ - p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1); + * it is a comma separated list and merge them. */ + p = strconcat (h->value, ",", value, NULL); if (!p) return gpg_err_code_from_syserror (); - strcpy (stpcpy (stpcpy (p, h->value), ","), value); xfree (h->value); h->value = p; return 0; diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c index 20cbbd8..a037f5d 100644 --- a/dirmngr/ldap.c +++ b/dirmngr/ldap.c @@ -445,26 +445,16 @@ make_url (char **url, const char *dn, const char *filter) xfree (u_dn); return err; } - *url = malloc ( 8 + strlen (u_dn) - + 1 + strlen (attrs) - + 5 + strlen (u_filter) + 1 ); + + *url = strconcat ("ldap:///", u_dn, "?", attrs, "?sub?", u_filter, NULL); if (!*url) - { - err = gpg_error_from_errno (errno); - xfree (u_dn); - xfree (u_filter); - return err; - } + err = gpg_error_from_syserror (); + else + err = 0; - stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (*url, "ldap:///"), - u_dn), - "?"), - attrs), - "?sub?"), - u_filter); xfree (u_dn); xfree (u_filter); - return 0; + return err; } diff --git a/dirmngr/server.c b/dirmngr/server.c index bca3a61..32ce5bb 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -367,10 +367,7 @@ do_get_cert_local (ctrl_t ctrl, const char *name, const char *command) ksba_cert_t cert; if (name) - { - buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1); - strcpy (stpcpy (stpcpy (buf, command), " "), name); - } + buf = xstrconcat (command, " ", name, NULL); else buf = xstrdup (command); @@ -475,15 +472,13 @@ get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid) return NULL; } - buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1); + buf = strconcat ("SENDCERT_SKI ", hexkeyid, " /", name, NULL); if (!buf) { - log_error ("can't allocate enough memory: %s\n", strerror (errno)); xfree (hexkeyid); return NULL; } - strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name); xfree (hexkeyid); rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf, ----------------------------------------------------------------------- Summary of changes: dirmngr/certcache.c | 65 ++++++++++++++++++++--------------------- dirmngr/crlfetch.c | 19 ++++++------ dirmngr/http.c | 5 ++-- dirmngr/ldap.c | 22 ++++---------- dirmngr/misc.c | 2 ++ dirmngr/server.c | 38 ++++++++++-------------- dirmngr/validate.c | 84 ++++++++++++++++++++++++++++------------------------- 7 files changed, 113 insertions(+), 122 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 16 17:26:31 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 16 Feb 2017 17:26:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-89-ge1dfd86 Message-ID: This is an 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 e1dfd862367cf91b66abe86bd73664409354bb14 (commit) via 28c31524be84f20b34573c78bd3a94a81e4b1d61 (commit) via 919e76b407ac557b0f518ec03f3cc59e9e5740c9 (commit) via 04bfa6fe6597b8ffcec61cbcacdc7eb137444e80 (commit) via 5c4e67afd6385b48065de6a0f2dd0bfd936ab90b (commit) from 1af733f37bf6fd55ccac787a7e34c3b3ca002126 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e1dfd862367cf91b66abe86bd73664409354bb14 Author: Werner Koch Date: Thu Feb 16 17:11:38 2017 +0100 common: Rename remaining symbols in ksba-io-support. * common/ksba-io-support.c (gpgsm_reader_eof_seen): Rename to ... (gnupg_ksba_reader_eof_seen): this. Change all callers. (gpgsm_destroy_reader): Rename to ... (gnupg_ksba_destroy_reader): this. Change all callers. (gpgsm_finish_writer): Rename to ... (gnupg_ksba_finish_writer): this. Change all callers. (gpgsm_destroy_writer): Rename to ... (gnupg_ksba_destroy_writer): this. Change all callers. * common/ksba-io-support.c (struct base64_context_s): Rename to ... (gnupg_ksba_io_s): this. * common/ksba-io-support.h (base64_context_s): Ditto. (Base64Context): Rename this typedef to ... (gnupg_ksba_io_t): this. Change all users. Signed-off-by: Werner Koch diff --git a/common/ksba-io-support.c b/common/ksba-io-support.c index 48a7ac1..5c7fd22 100644 --- a/common/ksba-io-support.c +++ b/common/ksba-io-support.c @@ -101,8 +101,8 @@ struct writer_cb_parm_s }; -/* context for this module's functions */ -struct base64_context_s { +/* Context for this module's functions. */ +struct gnupg_ksba_io_s { union { struct reader_cb_parm_s rparm; struct writer_cb_parm_s wparm; @@ -475,7 +475,7 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count) } -/* This callback is only used in stream mode. Hiowever, we don't +/* This callback is only used in stream mode. However, we don't restrict it to this. */ static int plain_writer_cb (void *cb_value, const void *buffer, size_t count) @@ -553,7 +553,7 @@ base64_finish_write (struct writer_cb_parm_s *parm) /* Create a reader for the stream FP. FLAGS can be used to specify * the expected input encoding. * - * The function returns a Base64Context object which must be passed to + * The function returns a gnupg_ksba_io_t object which must be passed to * the gpgme_destroy_reader function. The created ksba_reader_t * object is stored at R_READER - the caller must not call the * ksba_reader_release function on. @@ -571,7 +571,7 @@ base64_finish_write (struct writer_cb_parm_s *parm) * which in turn has a gight priority than the AUTODETECT flag. */ gpg_error_t -gnupg_ksba_create_reader (Base64Context *ctx, +gnupg_ksba_create_reader (gnupg_ksba_io_t *ctx, unsigned int flags, estream_t fp, ksba_reader_t *r_reader) { @@ -624,14 +624,17 @@ gnupg_ksba_create_reader (Base64Context *ctx, } +/* Return True if an EOF as been seen. */ int -gpgsm_reader_eof_seen (Base64Context ctx) +gnupg_ksba_reader_eof_seen (gnupg_ksba_io_t ctx) { return ctx && ctx->u.rparm.eof_seen; } + +/* Destroy a reader object. */ void -gpgsm_destroy_reader (Base64Context ctx) +gnupg_ksba_destroy_reader (gnupg_ksba_io_t ctx) { if (!ctx) return; @@ -647,7 +650,7 @@ gpgsm_destroy_reader (Base64Context ctx) * and footer lines; if PEM_NAME is NULL the string "CMS OBJECT" is * used. * - * The function returns a Base64Context object which must be passed to + * The function returns a gnupg_ksba_io_t object which must be passed to * the gpgme_destroy_writer function. The created ksba_writer_t * object is stored at R_WRITER - the caller must not call the * ksba_reader_release function on it. @@ -660,7 +663,7 @@ gpgsm_destroy_reader (Base64Context ctx) * */ gpg_error_t -gnupg_ksba_create_writer (Base64Context *ctx, unsigned int flags, +gnupg_ksba_create_writer (gnupg_ksba_io_t *ctx, unsigned int flags, const char *pem_name, estream_t stream, ksba_writer_t *r_writer) { @@ -718,8 +721,10 @@ gnupg_ksba_create_writer (Base64Context *ctx, unsigned int flags, } -int -gpgsm_finish_writer (Base64Context ctx) +/* Flush a writer. This is for example required to write the padding + * or the PEM footer. */ +gpg_error_t +gnupg_ksba_finish_writer (gnupg_ksba_io_t ctx) { struct writer_cb_parm_s *parm; @@ -735,8 +740,9 @@ gpgsm_finish_writer (Base64Context ctx) } +/* Destroy a writer object. */ void -gpgsm_destroy_writer (Base64Context ctx) +gnupg_ksba_destroy_writer (gnupg_ksba_io_t ctx) { if (!ctx) return; diff --git a/common/ksba-io-support.h b/common/ksba-io-support.h index 0f448ec..e33e0ed 100644 --- a/common/ksba-io-support.h +++ b/common/ksba-io-support.h @@ -34,31 +34,31 @@ * gnupg_ksba_create_writer. */ #define GNUPG_KSBA_IO_PEM 1 /* X.509 PEM format. */ #define GNUPG_KSBA_IO_BASE64 2 /* Plain Base64 format. */ -#define GNUPG_KSBA_IO_AUTODETECT 4 /* Try toautodeect the format. */ +#define GNUPG_KSBA_IO_AUTODETECT 4 /* Try to autodetect the format. */ #define GNUPG_KSBA_IO_MULTIPEM 8 /* Allow more than one PEM chunk. */ /* Context object. */ -typedef struct base64_context_s *Base64Context; +typedef struct gnupg_ksba_io_s *gnupg_ksba_io_t; -gpg_error_t gnupg_ksba_create_reader (Base64Context *ctx, +gpg_error_t gnupg_ksba_create_reader (gnupg_ksba_io_t *ctx, unsigned int flags, estream_t fp, ksba_reader_t *r_reader); -int gpgsm_reader_eof_seen (Base64Context ctx); -void gpgsm_destroy_reader (Base64Context ctx); +int gnupg_ksba_reader_eof_seen (gnupg_ksba_io_t ctx); +void gnupg_ksba_destroy_reader (gnupg_ksba_io_t ctx); -gpg_error_t gnupg_ksba_create_writer (Base64Context *ctx, +gpg_error_t gnupg_ksba_create_writer (gnupg_ksba_io_t *ctx, unsigned int flags, const char *pem_name, estream_t stream, ksba_writer_t *r_writer); -int gpgsm_finish_writer (Base64Context ctx); -void gpgsm_destroy_writer (Base64Context ctx); +gpg_error_t gnupg_ksba_finish_writer (gnupg_ksba_io_t ctx); +void gnupg_ksba_destroy_writer (gnupg_ksba_io_t ctx); diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 2290d3d..fe35ea8 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -737,7 +737,7 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, if (!outctrl->dryrun) { - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64writer = NULL; ksba_writer_t writer; int create_cert ; @@ -756,7 +756,7 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, rc = create_request (ctrl, para, cardkeyid, public, sigkey, writer); if (!rc) { - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) log_error ("write failed: %s\n", gpg_strerror (rc)); else @@ -766,7 +766,7 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, create_cert?"":" request"); } } - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); } } diff --git a/sm/decrypt.c b/sm/decrypt.c index 35c0b8d..cda4d29 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -243,8 +243,8 @@ int gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) { int rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64reader = NULL; + gnupg_ksba_io_t b64writer = NULL; ksba_reader_t reader; ksba_writer_t writer; ksba_cms_t cms = NULL; @@ -564,7 +564,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) } while (stopreason != KSBA_SR_READY); - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); @@ -582,8 +582,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) gpg_strerror (rc), gpg_strsource (rc)); } ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_reader (b64reader); + gnupg_ksba_destroy_writer (b64writer); keydb_release (kh); es_fclose (in_fp); if (dfparm.hd) diff --git a/sm/encrypt.c b/sm/encrypt.c index 468f785..3a7d4bb 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -299,7 +299,7 @@ int gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) { int rc = 0; - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64writer = NULL; gpg_error_t err; ksba_writer_t writer; ksba_reader_t reader = NULL; @@ -502,7 +502,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) } - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); @@ -513,7 +513,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) leave: ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); ksba_reader_release (reader); keydb_release (kh); xfree (dek); diff --git a/sm/export.c b/sm/export.c index 8e3f2de..d721d52 100644 --- a/sm/export.c +++ b/sm/export.c @@ -133,7 +133,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) KEYDB_HANDLE hd = NULL; KEYDB_SEARCH_DESC *desc = NULL; int ndesc; - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64writer = NULL; ksba_writer_t writer; strlist_t sl; ksba_cert_t cert = NULL; @@ -284,13 +284,13 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) if (ctrl->create_pem) { /* We want one certificate per PEM block */ - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); goto leave; } - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); b64writer = NULL; } } @@ -302,7 +302,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); else if (b64writer) { - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); @@ -311,7 +311,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) } leave: - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); ksba_cert_release (cert); xfree (desc); keydb_release (hd); @@ -331,7 +331,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) gpg_error_t err = 0; KEYDB_HANDLE hd; KEYDB_SEARCH_DESC *desc = NULL; - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64writer = NULL; ksba_writer_t writer; ksba_cert_t cert = NULL; const unsigned char *image; @@ -463,13 +463,13 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) if (ctrl->create_pem) { /* We want one certificate per PEM block */ - err = gpgsm_finish_writer (b64writer); + err = gnupg_ksba_finish_writer (b64writer); if (err) { log_error ("write failed: %s\n", gpg_strerror (err)); goto leave; } - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); b64writer = NULL; } @@ -477,7 +477,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) cert = NULL; leave: - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); ksba_cert_release (cert); xfree (desc); keydb_release (hd); diff --git a/sm/import.c b/sm/import.c index 2a07108..b284b51 100644 --- a/sm/import.c +++ b/sm/import.c @@ -272,7 +272,7 @@ static int import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) { int rc; - Base64Context b64reader = NULL; + gnupg_ksba_io_t b64reader = NULL; ksba_reader_t reader; ksba_cert_t cert = NULL; ksba_cms_t cms = NULL; @@ -380,14 +380,14 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) ksba_reader_clear (reader, NULL, NULL); } - while (!gpgsm_reader_eof_seen (b64reader)); + while (!gnupg_ksba_reader_eof_seen (b64reader)); leave: if (any && gpg_err_code (rc) == GPG_ERR_EOF) rc = 0; ksba_cms_release (cms); ksba_cert_release (cert); - gpgsm_destroy_reader (b64reader); + gnupg_ksba_destroy_reader (b64reader); es_fclose (fp); return rc; } diff --git a/sm/sign.c b/sm/sign.c index b5a486c..0ca575b 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -316,7 +316,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { int i, rc; gpg_error_t err; - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64writer = NULL; ksba_writer_t writer; ksba_cms_t cms = NULL; ksba_stop_reason_t stopreason; @@ -763,7 +763,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, } while (stopreason != KSBA_SR_READY); - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); @@ -781,7 +781,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (release_signerlist) gpgsm_release_certlist (signerlist); ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_writer (b64writer); keydb_release (kh); gcry_md_close (data_md); return rc; diff --git a/sm/verify.c b/sm/verify.c index b80948f..1ac97cb 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -90,8 +90,8 @@ int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) { int i, rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; + gnupg_ksba_io_t b64reader = NULL; + gnupg_ksba_io_t b64writer = NULL; ksba_reader_t reader; ksba_writer_t writer = NULL; ksba_cms_t cms = NULL; @@ -253,7 +253,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) if (b64writer) { - rc = gpgsm_finish_writer (b64writer); + rc = gnupg_ksba_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); @@ -650,8 +650,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) leave: ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); + gnupg_ksba_destroy_reader (b64reader); + gnupg_ksba_destroy_writer (b64writer); keydb_release (kh); gcry_md_close (data_md); es_fclose (in_fp); commit 28c31524be84f20b34573c78bd3a94a81e4b1d61 Author: Werner Koch Date: Thu Feb 16 15:16:48 2017 +0100 common: Remove gpgsm dependencies from ksba-io-support. * common/ksba-io-support.c: Include ksba-io-support.h instead of ../sm/gpgsm.h. Include util.h. (writer_cb_parm_s): Remove const from 'pem_name'. (gpgsm_destroy_writer): Free 'pem_name'. (gpgsm_create_reader): Rename to ... (gnupg_ksba_create_reader): this. Replace args CTRL and ALLOW_MULTI_PEM by a new arg FLAGS. Change the code to evaluate FLAGS. Change all callers to pass the FLAGS. (gpgsm_create_writer): Rename to ... (gnupg_ksba_create_writer): this. Replace arg CTRL by new arg FLAGS. Add arg PEM_NAME. Evaluate FLAGS. Store a copy of PEM_NAME. Change all callers to pass the FLAGS and PEM_NAME. Signed-off-by: Werner Koch diff --git a/common/ksba-io-support.c b/common/ksba-io-support.c index da7b4d6..48a7ac1 100644 --- a/common/ksba-io-support.c +++ b/common/ksba-io-support.c @@ -36,13 +36,12 @@ #include #include #include - -#include "../sm/gpgsm.h" - - #include +#include "util.h" #include "i18n.h" +#include "ksba-io-support.h" + #ifdef HAVE_DOSISH_SYSTEM #define LF "\r\n" @@ -50,6 +49,7 @@ #define LF "\n" #endif + /* Data used by the reader callbacks. */ struct reader_cb_parm_s { @@ -87,7 +87,7 @@ struct writer_cb_parm_s { estream_t stream; /* Output stream. */ - const char *pem_name; + char *pem_name; /* Malloced. */ int wrote_begin; int did_finish; @@ -550,18 +550,30 @@ base64_finish_write (struct writer_cb_parm_s *parm) -/* Create a reader for the given file descriptor. Depending on the - control information an input decoding is automagically chosen. - The function returns a Base64Context object which must be passed to - the gpgme_destroy_reader function. The created KsbaReader object - is also returned, but the caller must not call the - ksba_reader_release function on. If ALLOW_MULTI_PEM is true, the - reader expects that the caller uses ksba_reader_clear after EOF - until no more objects were found. */ -int -gpgsm_create_reader (Base64Context *ctx, - ctrl_t ctrl, estream_t fp, int allow_multi_pem, - ksba_reader_t *r_reader) +/* Create a reader for the stream FP. FLAGS can be used to specify + * the expected input encoding. + * + * The function returns a Base64Context object which must be passed to + * the gpgme_destroy_reader function. The created ksba_reader_t + * object is stored at R_READER - the caller must not call the + * ksba_reader_release function on. + * + * The supported flags are: + * + * GNUPG_KSBA_IO_PEM - Assume the input is PEM encoded + * GNUPG_KSBA_IO_BASE64 - Assume the input is Base64 encoded. + * GNUPG_KSBA_IO_AUTODETECT - The reader tries to detect the encoding. + * GNUPG_KSBA_IO_MULTIPEM - The reader expects that the caller uses + * ksba_reader_clear after EOF until no more + * objects were found. + * + * Note that the PEM flag has a higher priority than the BASE64 flag + * which in turn has a gight priority than the AUTODETECT flag. + */ +gpg_error_t +gnupg_ksba_create_reader (Base64Context *ctx, + unsigned int flags, estream_t fp, + ksba_reader_t *r_reader) { int rc; ksba_reader_t r; @@ -570,7 +582,7 @@ gpgsm_create_reader (Base64Context *ctx, *ctx = xtrycalloc (1, sizeof **ctx); if (!*ctx) return out_of_core (); - (*ctx)->u.rparm.allow_multi_pem = allow_multi_pem; + (*ctx)->u.rparm.allow_multi_pem = !!(flags & GNUPG_KSBA_IO_MULTIPEM); rc = ksba_reader_new (&r); if (rc) @@ -580,18 +592,18 @@ gpgsm_create_reader (Base64Context *ctx, } (*ctx)->u.rparm.fp = fp; - if (ctrl->is_pem) + if ((flags & GNUPG_KSBA_IO_PEM)) { (*ctx)->u.rparm.assume_pem = 1; (*ctx)->u.rparm.assume_base64 = 1; rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); } - else if (ctrl->is_base64) + else if ((flags & GNUPG_KSBA_IO_BASE64)) { (*ctx)->u.rparm.assume_base64 = 1; rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); } - else if (ctrl->autodetect_encoding) + else if ((flags & GNUPG_KSBA_IO_AUTODETECT)) { (*ctx)->u.rparm.autodetect = 1; rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); @@ -630,15 +642,27 @@ gpgsm_destroy_reader (Base64Context ctx) -/* Create a writer for the given STREAM. Depending on - the control information an output encoding is automagically - chosen. The function returns a Base64Context object which must be - passed to the gpgme_destroy_writer function. The created - KsbaWriter object is also returned, but the caller must not call - the ksba_reader_release function on it. */ -int -gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream, - ksba_writer_t *r_writer) +/* Create a writer for the given STREAM. Depending on FLAGS an output + * encoding is chosen. In PEM mode PEM_NAME is used for the header + * and footer lines; if PEM_NAME is NULL the string "CMS OBJECT" is + * used. + * + * The function returns a Base64Context object which must be passed to + * the gpgme_destroy_writer function. The created ksba_writer_t + * object is stored at R_WRITER - the caller must not call the + * ksba_reader_release function on it. + * + * The supported flags are: + * + * GNUPG_KSBA_IO_PEM - Write output as PEM + * GNUPG_KSBA_IO_BASE64 - Write output as plain Base64; note that the PEM + * flag overrides this flag. + * + */ +gpg_error_t +gnupg_ksba_create_writer (Base64Context *ctx, unsigned int flags, + const char *pem_name, estream_t stream, + ksba_writer_t *r_writer) { int rc; ksba_writer_t w; @@ -646,7 +670,7 @@ gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream, *r_writer = NULL; *ctx = xtrycalloc (1, sizeof **ctx); if (!*ctx) - return out_of_core (); + return gpg_error_from_syserror (); rc = ksba_writer_new (&w); if (rc) @@ -655,12 +679,22 @@ gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream, return rc; } - if (ctrl->create_pem || ctrl->create_base64) + if ((flags & GNUPG_KSBA_IO_PEM) || (flags & GNUPG_KSBA_IO_BASE64)) { (*ctx)->u.wparm.stream = stream; - if (ctrl->create_pem) - (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name - : "CMS OBJECT"; + if ((flags & GNUPG_KSBA_IO_PEM)) + { + (*ctx)->u.wparm.pem_name = xtrystrdup (pem_name + ? pem_name + : "CMS OBJECT"); + if (!(*ctx)->u.wparm.pem_name) + { + rc = gpg_error_from_syserror (); + ksba_writer_release (w); + xfree (*ctx); *ctx = NULL; + return rc; + } + } rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm); } else if (stream) @@ -700,6 +734,7 @@ gpgsm_finish_writer (Base64Context ctx) return base64_finish_write (parm); } + void gpgsm_destroy_writer (Base64Context ctx) { @@ -707,5 +742,6 @@ gpgsm_destroy_writer (Base64Context ctx) return; ksba_writer_release (ctx->u2.writer); + xfree (ctx->u.wparm.pem_name); xfree (ctx); } diff --git a/common/ksba-io-support.h b/common/ksba-io-support.h index 7028686..0f448ec 100644 --- a/common/ksba-io-support.h +++ b/common/ksba-io-support.h @@ -30,4 +30,37 @@ #ifndef GNUPG_KSBA_IO_SUPPORT_H #define GNUPG_KSBA_IO_SUPPORT_H +/* Flags used with gnupg_ksba_create_reader and + * gnupg_ksba_create_writer. */ +#define GNUPG_KSBA_IO_PEM 1 /* X.509 PEM format. */ +#define GNUPG_KSBA_IO_BASE64 2 /* Plain Base64 format. */ +#define GNUPG_KSBA_IO_AUTODETECT 4 /* Try toautodeect the format. */ +#define GNUPG_KSBA_IO_MULTIPEM 8 /* Allow more than one PEM chunk. */ + + +/* Context object. */ +typedef struct base64_context_s *Base64Context; + + + +gpg_error_t gnupg_ksba_create_reader (Base64Context *ctx, + unsigned int flags, + estream_t fp, + ksba_reader_t *r_reader); + +int gpgsm_reader_eof_seen (Base64Context ctx); +void gpgsm_destroy_reader (Base64Context ctx); + +gpg_error_t gnupg_ksba_create_writer (Base64Context *ctx, + unsigned int flags, + const char *pem_name, + estream_t stream, + ksba_writer_t *r_writer); + +int gpgsm_finish_writer (Base64Context ctx); +void gpgsm_destroy_writer (Base64Context ctx); + + + + #endif /*GNUPG_KSBA_IO_SUPPORT_H*/ diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 9b4ffc9..2290d3d 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -744,7 +744,11 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, create_cert = !!get_parameter_value (para, pSERIAL, 0); ctrl->pem_name = create_cert? "CERTIFICATE" : "CERTIFICATE REQUEST"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) log_error ("can't create writer: %s\n", gpg_strerror (rc)); else diff --git a/sm/decrypt.c b/sm/decrypt.c index a2907f6..35c0b8d 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -274,14 +274,21 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) goto leave; } - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader); + rc = gnupg_ksba_create_reader + (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) + | (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0)), + in_fp, &reader); if (rc) { log_error ("can't create reader: %s\n", gpg_strerror (rc)); goto leave; } - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); diff --git a/sm/encrypt.c b/sm/encrypt.c index 2c664f8..468f785 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -364,7 +364,10 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) encparm.fp = data_fp; ctrl->pem_name = "ENCRYPTED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); diff --git a/sm/export.c b/sm/export.c index a32414e..8e3f2de 100644 --- a/sm/export.c +++ b/sm/export.c @@ -263,7 +263,10 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) if (!b64writer) { ctrl->pem_name = "CERTIFICATE"; - rc = gpgsm_create_writer (&b64writer, ctrl, stream, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 :0)), + ctrl->pem_name, stream, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); @@ -433,7 +436,10 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) ctrl->pem_name = "PRIVATE KEY"; else ctrl->pem_name = "RSA PRIVATE KEY"; - err = gpgsm_create_writer (&b64writer, ctrl, stream, &writer); + err = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, stream, &writer); if (err) { log_error ("can't create writer: %s\n", gpg_strerror (err)); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 76ff327..df96770 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -33,6 +33,7 @@ #include "../common/status.h" #include "../common/audit.h" #include "../common/session-env.h" +#include "../common/ksba-io-support.h" #define MAX_DIGEST_LEN 64 @@ -205,10 +206,6 @@ struct server_control_s }; -/* Data structure used in base64.c. */ -typedef struct base64_context_s *Base64Context; - - /* An object to keep a list of certificates. */ struct certlist_s { @@ -262,19 +259,6 @@ int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); char *gpgsm_get_certid (ksba_cert_t cert); -/*-- base64.c --*/ -int gpgsm_create_reader (Base64Context *ctx, - ctrl_t ctrl, estream_t fp, int allow_multi_pem, - ksba_reader_t *r_reader); -int gpgsm_reader_eof_seen (Base64Context ctx); -void gpgsm_destroy_reader (Base64Context ctx); -int gpgsm_create_writer (Base64Context *ctx, - ctrl_t ctrl, estream_t stream, - ksba_writer_t *r_writer); -int gpgsm_finish_writer (Base64Context ctx); -void gpgsm_destroy_writer (Base64Context ctx); - - /*-- certdump.c --*/ void gpgsm_print_serial (estream_t fp, ksba_const_sexp_t p); void gpgsm_print_time (estream_t fp, ksba_isotime_t t); diff --git a/sm/import.c b/sm/import.c index 4a8ecf7..2a07108 100644 --- a/sm/import.c +++ b/sm/import.c @@ -288,7 +288,12 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) goto leave; } - rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader); + rc = gnupg_ksba_create_reader + (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) + | (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0) + | GNUPG_KSBA_IO_MULTIPEM), + fp, &reader); if (rc) { log_error ("can't create reader: %s\n", gpg_strerror (rc)); diff --git a/sm/sign.c b/sm/sign.c index 9153d58..b5a486c 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -340,7 +340,10 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, } ctrl->pem_name = "SIGNED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); diff --git a/sm/verify.c b/sm/verify.c index a046883..b80948f 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -125,7 +125,11 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) goto leave; } - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader); + rc = gnupg_ksba_create_reader + (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) + | (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0)), + in_fp, &reader); if (rc) { log_error ("can't create reader: %s\n", gpg_strerror (rc)); @@ -134,7 +138,10 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) if (out_fp) { - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); commit 919e76b407ac557b0f518ec03f3cc59e9e5740c9 Author: Werner Koch Date: Thu Feb 16 14:17:43 2017 +0100 common: Change license of ksba-io-support.c * common/ksba-io-support.c: Change from GPLv3+ to LGPLv3+/GPLv2+. -- According to the sm/ChangeLog-2011 and the git log all code has been written by me or g10 Code employees. Also changed the copyright notices so that the file can be sued separately. Signed-off-by: Werner Koch diff --git a/common/ksba-io-support.c b/common/ksba-io-support.c index a47e47b..da7b4d6 100644 --- a/common/ksba-io-support.c +++ b/common/ksba-io-support.c @@ -1,14 +1,25 @@ /* kska-io-support.c - Supporting functions for ksba reader and writer - * Copyright (C) 2001, 2003, 2010 Free Software Foundation, Inc. + * Copyright (C) 2001-2005, 2007, 2010-2011, 2017 Werner Koch + * Copyright (C) 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 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. + * This file is free software; you can redistribute it and/or modify + * it under the terms of either * - * GnuPG is distributed in the hope that it will be useful, + * - 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. + * + * 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. commit 04bfa6fe6597b8ffcec61cbcacdc7eb137444e80 Author: Werner Koch Date: Thu Feb 16 14:07:27 2017 +0100 sm,common: Move ksba reader and writer support to common/. * sm/base64.c: Rename to ... * common/ksba-io-support.c: this. * common/ksba-io-support.h: New. * common/Makefile.am (common_sources): Add new files. * sm/Makefile.am (gpgsm_SOURCES): Remove base64.c Signed-off-by: Werner Koch diff --git a/common/Makefile.am b/common/Makefile.am index 72e3fb4..68b8710 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -91,7 +91,9 @@ common_sources = \ exectool.c exectool.h \ server-help.c server-help.h \ name-value.c name-value.h \ - recsel.c recsel.h + recsel.c recsel.h \ + ksba-io-support.c ksba-io-support.h + if HAVE_W32_SYSTEM common_sources += w32-reg.c diff --git a/sm/base64.c b/common/ksba-io-support.c similarity index 99% rename from sm/base64.c rename to common/ksba-io-support.c index f3c7def..a47e47b 100644 --- a/sm/base64.c +++ b/common/ksba-io-support.c @@ -1,4 +1,4 @@ -/* base64.c +/* kska-io-support.c - Supporting functions for ksba reader and writer * Copyright (C) 2001, 2003, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. @@ -26,7 +26,7 @@ #include #include -#include "gpgsm.h" +#include "../sm/gpgsm.h" #include diff --git a/common/ksba-io-support.h b/common/ksba-io-support.h new file mode 100644 index 0000000..7028686 --- /dev/null +++ b/common/ksba-io-support.h @@ -0,0 +1,33 @@ +/* ksba-io-support.h - Supporting functions for ksba reader and writer + * Copyright (C) 2017 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 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. + * + * 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 + * along with this program; if not, see . + */ + +#ifndef GNUPG_KSBA_IO_SUPPORT_H +#define GNUPG_KSBA_IO_SUPPORT_H + +#endif /*GNUPG_KSBA_IO_SUPPORT_H*/ diff --git a/sm/Makefile.am b/sm/Makefile.am index a9c67a8..4cfb246 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -38,7 +38,6 @@ gpgsm_SOURCES = \ call-agent.c \ call-dirmngr.c \ fingerprint.c \ - base64.c \ certlist.c \ certdump.c \ certcheck.c \ commit 5c4e67afd6385b48065de6a0f2dd0bfd936ab90b Author: Werner Koch Date: Thu Feb 16 11:51:57 2017 +0100 dirmngr: Prepare certcache for forthcoming changes. * dirmngr/certcache.c (cert_item_s): Rename 'flags.loaded' to 'flags.config'. Add 'flags.systrust'. (total_loaded_certificates): Rename to total_config_certificates. (put_cert): Rename args for clarity. Set SYSTRUST flag. (load_certs_from_dir): Make sure put_cert does not set the SYSTRUST flag. Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index d13d80b..d68d503 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -68,8 +68,12 @@ struct cert_item_s char *subject_dn; /* The malloced subject DN - maybe NULL. */ struct { - unsigned int loaded:1; /* It has been explicitly loaded. */ + unsigned int config:1; /* This has been loaded from the configuration. */ unsigned int trusted:1; /* This is a trusted root certificate. */ + unsigned int systrust:1;/* The certifciate is trusted because it + * is in the system's store of trusted + * certificates (i.e. not configured using + * GnuPG mechanisms. */ } flags; }; typedef struct cert_item_s *cert_item_t; @@ -88,9 +92,9 @@ static npth_rwlock_t cert_cache_lock; /* Flag to track whether the cache has been initialized. */ static int initialization_done; -/* Total number of certificates loaded during initialization and - cached during operation. */ -static unsigned int total_loaded_certificates; +/* Total number of certificates loaded during initialization + * (ie. configured) and extra certifcates cached during operation. */ +static unsigned int total_config_certificates; static unsigned int total_extra_certificates; @@ -229,13 +233,20 @@ clean_cache_slot (cert_item_t ci) /* Put the certificate CERT into the cache. It is assumed that the - cache is locked while this function is called. If FPR_BUFFER is not - NULL the fingerprint of the certificate will be stored there. - FPR_BUFFER neds to point to a buffer of at least 20 bytes. The - fingerprint will be stored on success or when the function returns - gpg_err_code(GPG_ERR_DUP_VALUE). */ + * cache is locked while this function is called. + * + * FROM_CONFIG indicates that CERT is a permanent certificate and + * should stay in the cache. IS_TRUSTED requests that the trusted + * flag is set for the certificate; a value of 1 indicates the the + * cert is trusted due to GnuPG mechanisms, a value of 2 indicates + * that it is trusted because it has been taken from the system's + * store of trusted certificates. If FPR_BUFFER is not NULL the + * fingerprint of the certificate will be stored there. FPR_BUFFER + * needs to point to a buffer of at least 20 bytes. The fingerprint + * will be stored on success or when the function returns + * GPG_ERR_DUP_VALUE. */ static gpg_error_t -put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer) +put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) { unsigned char help_fpr_buffer[20], *fpr; cert_item_t ci; @@ -243,17 +254,17 @@ put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer) fpr = fpr_buffer? fpr_buffer : &help_fpr_buffer; /* If we already reached the caching limit, drop a couple of certs - from the cache. Our dropping strategy is simple: We keep a - static index counter and use this to start looking for - certificates, then we drop 5 percent of the oldest certificates - starting at that index. For a large cache this is a fair way of - removing items. An LRU strategy would be better of course. - Because we append new entries to the head of the list and we want - to remove old ones first, we need to do this from the tail. The - implementation is not very efficient but compared to the long - time it takes to retrieve a certifciate from an external resource - it seems to be reasonable. */ - if (!is_loaded && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS) + * from the cache. Our dropping strategy is simple: We keep a + * static index counter and use this to start looking for + * certificates, then we drop 5 percent of the oldest certificates + * starting at that index. For a large cache this is a fair way of + * removing items. An LRU strategy would be better of course. + * Because we append new entries to the head of the list and we want + * to remove old ones first, we need to do this from the tail. The + * implementation is not very efficient but compared to the long + * time it takes to retrieve a certificate from an external resource + * it seems to be reasonable. */ + if (!from_config && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS) { static int idx; cert_item_t ci_mark; @@ -270,7 +281,7 @@ put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer) { ci_mark = NULL; for (ci = cert_cache[i]; ci; ci = ci->next) - if (ci->cert && !ci->flags.loaded) + if (ci->cert && !ci->flags.config) ci_mark = ci; if (ci_mark) { @@ -316,11 +327,12 @@ put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer) return gpg_error (GPG_ERR_INV_CERT_OBJ); } ci->subject_dn = ksba_cert_get_subject (cert, 0); - ci->flags.loaded = !!is_loaded; + ci->flags.config = !!from_config; ci->flags.trusted = !!is_trusted; + ci->flags.systrust = (is_trusted && is_trusted == 2); - if (is_loaded) - total_loaded_certificates++; + if (from_config) + total_config_certificates++; else total_extra_certificates++; @@ -390,7 +402,7 @@ load_certs_from_dir (const char *dirname, int are_trusted) continue; } - err = put_cert (cert, 1, are_trusted, NULL); + err = put_cert (cert, 1, !!are_trusted, NULL); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate '%s' already cached\n"), fname); else if (!err) @@ -476,7 +488,7 @@ cert_cache_deinit (int full) } } - total_loaded_certificates = 0; + total_config_certificates = 0; total_extra_certificates = 0; initialization_done = 0; release_cache_lock (); @@ -487,7 +499,7 @@ void cert_cache_print_stats (void) { log_info (_("permanently loaded certificates: %u\n"), - total_loaded_certificates); + total_config_certificates); log_info (_(" runtime cached certificates: %u\n"), total_extra_certificates); } ----------------------------------------------------------------------- Summary of changes: common/Makefile.am | 4 +- sm/base64.c => common/ksba-io-support.c | 153 +++++++++++++++++++++----------- common/ksba-io-support.h | 66 ++++++++++++++ dirmngr/certcache.c | 68 ++++++++------ sm/Makefile.am | 1 - sm/certreqgen.c | 12 ++- sm/decrypt.c | 21 +++-- sm/encrypt.c | 11 ++- sm/export.c | 28 +++--- sm/gpgsm.h | 18 +--- sm/import.c | 13 ++- sm/sign.c | 11 ++- sm/verify.c | 21 +++-- 13 files changed, 289 insertions(+), 138 deletions(-) rename sm/base64.c => common/ksba-io-support.c (79%) create mode 100644 common/ksba-io-support.h hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 16 17:28:32 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 16 Feb 2017 17:28:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-90-g09d71de Message-ID: This is an 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 09d71de4d4f0a813ba3e584540f899bfd6c568cd (commit) from e1dfd862367cf91b66abe86bd73664409354bb14 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 09d71de4d4f0a813ba3e584540f899bfd6c568cd Author: Werner Koch Date: Thu Feb 16 17:26:01 2017 +0100 po: Adjust POTFILES for renamed sm/base64.c. -- Signed-off-by: Werner Koch diff --git a/po/POTFILES.in b/po/POTFILES.in index d2f3592..f071651 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -23,6 +23,7 @@ common/asshelp.c common/audit.c common/helpfile.c common/gettime.c +common/ksba-io-support.c common/argparse.c common/logging.c @@ -82,7 +83,6 @@ scd/app-openpgp.c scd/app-dinsig.c scd/scdaemon.c -sm/base64.c sm/call-agent.c sm/call-dirmngr.c sm/certchain.c ----------------------------------------------------------------------- Summary of changes: po/POTFILES.in | 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 Thu Feb 16 17:47:29 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 16 Feb 2017 17:47:29 +0100 Subject: [git] gnupg-doc - branch, master, updated. c47eef0711fad9e4c6b3c23cf51ec65333f9acb9 Message-ID: This is an 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 c47eef0711fad9e4c6b3c23cf51ec65333f9acb9 (commit) from d6a2c2992be786c94ce0e1aae5a71d80bc860e92 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c47eef0711fad9e4c6b3c23cf51ec65333f9acb9 Author: Werner Koch Date: Thu Feb 16 17:44:56 2017 +0100 drafts,openpgp-webkey-service: Fixed Content-Type Reported-by: Patrick Brunschwig diff --git a/misc/id/openpgp-webkey-service/draft.org b/misc/id/openpgp-webkey-service/draft.org index 1239442..44d9fb0 100644 --- a/misc/id/openpgp-webkey-service/draft.org +++ b/misc/id/openpgp-webkey-service/draft.org @@ -307,7 +307,7 @@ The first part MUST have "text" as its Content-Type and can be used to explain the purpose of the mail. For example it may point to this RFC and explain on how to manually perform the protocol. -The second part MUST have "application/vnd.gnupg.wkd" as its +The second part MUST have "application/vnd.gnupg.wks" as its Content-Type and carry an OpenPGP encrypted message in ASCII Armor format. The message MUST be encrypted to the target key and MUST NOT be signed. After decryption a text file in the Web Key data format @@ -387,7 +387,7 @@ key and the encryption key is the key associated with the provider's submission address. The Content-Type used for the plaintext message MUST also be -"application/vnd.gnupg.wkd". The format is the same as described above +"application/vnd.gnupg.wks". The format is the same as described above for the Confirmation Request. The body must contain three name-value pairs in this order: @@ -688,6 +688,7 @@ ShZ91YKkcZffevdY72omqTk10a1SUXehPooIlRFmroDsi3VDaRKrUIo= #+end_example -* Changes Since -02 +* Changes Since -03 -- Specified the use of DNS SRV. +- Fixed Content-Type in the description. The one used in the example + was correct. ----------------------------------------------------------------------- Summary of changes: misc/id/openpgp-webkey-service/draft.org | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 16 17:56:27 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Thu, 16 Feb 2017 17:56:27 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-80-g7641b7b Message-ID: This is an 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 7641b7b5f2c9d5b38c60cd9326bcb4810c37dae5 (commit) via 13bace25e3d8422f93fd24919994be36042fd220 (commit) via 476b97822b169c30cc246c1de2ff94cf89084706 (commit) via 3bdce4aa3ddd4a3f55b24678faf978d61daa8909 (commit) via 048c5f74b61d5e4fa7617ce7c9111c6754bd4409 (commit) from de708e5934cda380dbc3ae51f587c09041de7562 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7641b7b5f2c9d5b38c60cd9326bcb4810c37dae5 Author: Justus Winter Date: Thu Feb 16 17:52:49 2017 +0100 python: Support adding and revoking UIDs. * NEWS: Update. * lang/python/gpg/core.py (Context.key_add_uid): New function. (Context.key_revoke_uid): Likewise. * lang/python/tests/Makefile.am (XTESTS): Add new test. * lang/python/tests/t-quick-key-manipulation.py: New file. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index d2df444..889a526 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,8 @@ Noteworthy changes in version 1.8.1 (unreleased) py: Context.keylist EXTENDED: New keyword arg mode. py: Context.create_key NEW. py: Context.create_subkey NEW. + py: Context.key_add_uid NEW. + py: Context.key_revoke_uid NEW. py: core.pubkey_algo_string NEW. py: core.addrspec_from_uid NEW. diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index 2a4df99..beaebda 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -651,6 +651,30 @@ class Context(GpgmeWrapper): return self.op_genkey_result() + def key_add_uid(self, key, uid): + """Add a UID + + Add the uid UID to the given KEY. Calling this function is + only valid for the OpenPGP protocol. + + Raises: + GPGMEError -- as signaled by the underlying library + + """ + self.op_adduid(key, uid, 0) + + def key_revoke_uid(self, key, uid): + """Revoke a UID + + Revoke the uid UID from the given KEY. Calling this function + is only valid for the OpenPGP protocol. + + Raises: + GPGMEError -- as signaled by the underlying library + + """ + self.op_revuid(key, uid, 0) + 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/Makefile.am b/lang/python/tests/Makefile.am index 62c6087..1d5e1db 100644 --- a/lang/python/tests/Makefile.am +++ b/lang/python/tests/Makefile.am @@ -52,7 +52,8 @@ py_tests = t-wrapper.py \ t-idiomatic.py \ t-protocol-assuan.py \ t-quick-key-creation.py \ - t-quick-subkey-creation.py + t-quick-subkey-creation.py \ + t-quick-key-manipulation.py XTESTS = initial.py $(py_tests) final.py EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \ diff --git a/lang/python/tests/t-quick-key-manipulation.py b/lang/python/tests/t-quick-key-manipulation.py new file mode 100755 index 0000000..62c395a --- /dev/null +++ b/lang/python/tests/t-quick-key-manipulation.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +# Copyright (C) 2017 g10 Code 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 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 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 . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +import gpg +import itertools +import os +import shutil +import time + +import support + +alpha = "Alpha " +bravo = "Bravo " + +def copy_configuration(destination): + home = os.environ['GNUPGHOME'] + shutil.copy(os.path.join(home, "gpg.conf"), destination) + shutil.copy(os.path.join(home, "gpg-agent.conf"), destination) + +with support.TemporaryDirectory() as tmp: + copy_configuration(tmp) + with gpg.Context(home_dir=tmp) as ctx: + res = ctx.create_key(alpha, certify=True) + key = ctx.get_key(res.fpr) + assert len(key.subkeys) == 1, "Expected one primary key and no subkeys" + assert len(key.uids) == 1, "Expected exactly one UID" + + def get_uid(uid): + key = ctx.get_key(res.fpr) + for u in key.uids: + if u.uid == uid: + return u + return None + + # sanity check + uid = get_uid(alpha) + assert uid, "UID alpha not found" + assert uid.revoked == 0 + + # add bravo + ctx.key_add_uid(key, bravo) + uid = get_uid(bravo) + assert uid, "UID bravo not found" + assert uid.revoked == 0 + + # revoke alpha + ctx.key_revoke_uid(key, alpha) + uid = get_uid(alpha) + assert uid, "UID alpha not found" + assert uid.revoked == 1 + uid = get_uid(bravo) + assert uid, "UID bravo not found" + assert uid.revoked == 0 + + # try to revoke the last UID + try: + ctx.key_revoke_uid(key, alpha) + # IMHO this should fail. issue2961. + # assert False, "Expected an error but got none" + except gpg.errors.GpgError: + pass + + # Everything should be the same + uid = get_uid(alpha) + assert uid, "UID alpha not found" + assert uid.revoked == 1 + uid = get_uid(bravo) + assert uid, "UID bravo not found" + assert uid.revoked == 0 + + # try to revoke a non-existent UID + try: + ctx.key_revoke_uid(key, "i dont exist") + # IMHO this should fail. issue2963. + # assert False, "Expected an error but got none" + except gpg.errors.GpgError: + pass + + # try to add an pre-existent UID + try: + ctx.key_add_uid(key, bravo) + assert False, "Expected an error but got none" + except gpg.errors.GpgError: + pass commit 13bace25e3d8422f93fd24919994be36042fd220 Author: Justus Winter Date: Thu Feb 16 16:38:21 2017 +0100 python: Support quick subkey creation. * NEWS: Update. * lang/python/gpg/core.py (Context.create_subkey): New function. * lang/python/tests/Makefile.am (XTESTS): Add new test. * lang/python/tests/t-quick-subkey-creation.py: New file. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 7d30b94..d2df444 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ Noteworthy changes in version 1.8.1 (unreleased) py: Context.home_dir NEW. py: Context.keylist EXTENDED: New keyword arg mode. py: Context.create_key NEW. + py: Context.create_subkey NEW. py: core.pubkey_algo_string NEW. py: core.addrspec_from_uid NEW. diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index c5af1b1..2a4df99 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -579,6 +579,78 @@ class Context(GpgmeWrapper): return self.op_genkey_result() + def create_subkey(self, key, algorithm=None, expires_in=0, expires=True, + sign=False, encrypt=False, authenticate=False, passphrase=None): + """Create a subkey + + Create a subkey for the given KEY. As subkeys are a concept + of OpenPGP, calling this is only valid for the OpenPGP + protocol. + + ALGORITHM may be used to specify the public key encryption + algorithm for the new subkey. By default, a reasonable + default is chosen. You may use "future-default" to select an + algorithm that will be the default in a future implementation + of the engine. ALGORITHM may be a string like "rsa", or + "rsa2048" to explicitly request an algorithm and a key size. + + EXPIRES_IN specifies the expiration time of the subkey in + number of seconds since the subkeys creation. By default, a + reasonable expiration time is chosen. If you want to create a + subkey that does not expire, use the keyword argument EXPIRES. + + SIGN, ENCRYPT, and AUTHENTICATE can be used to request the + capabilities of the new subkey. If you don't request any, an + encryption subkey is generated. + + If PASSPHRASE is None (the default), then the subkey will not + be protected with a passphrase. If PASSPHRASE is a string, it + will be used to protect the subkey. If PASSPHRASE is True, + the passphrase must be supplied using a passphrase callback or + out-of-band with a pinentry. + + Keyword arguments: + algorithm -- public key algorithm, see above (default: reasonable) + expires_in -- expiration time in seconds (default: reasonable) + expires -- whether or not the subkey should expire (default: True) + sign -- request the signing capability (see above) + encrypt -- request the encryption capability (see above) + authenticate -- request the authentication capability (see above) + passphrase -- protect the subkey with a passphrase (default: no passphrase) + + Returns: + -- an object describing the result of the subkey creation + + Raises: + GPGMEError -- as signaled by the underlying library + + """ + if util.is_a_string(passphrase): + old_pinentry_mode = self.pinentry_mode + old_passphrase_cb = getattr(self, '_passphrase_cb', None) + self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK + def passphrase_cb(hint, desc, prev_bad, hook=None): + return passphrase + self.set_passphrase_cb(passphrase_cb) + + try: + self.op_createsubkey(key, algorithm, + 0, # reserved + expires_in, + ((constants.create.SIGN if sign else 0) + | (constants.create.ENCR if encrypt else 0) + | (constants.create.AUTH if authenticate else 0) + | (constants.create.NOPASSWD + if passphrase == None else 0) + | (0 if expires else constants.create.NOEXPIRE))) + finally: + if util.is_a_string(passphrase): + self.pinentry_mode = old_pinentry_mode + if old_passphrase_cb: + self.set_passphrase_cb(*old_passphrase_cb[1:]) + + return self.op_genkey_result() + 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/Makefile.am b/lang/python/tests/Makefile.am index 5469e75..62c6087 100644 --- a/lang/python/tests/Makefile.am +++ b/lang/python/tests/Makefile.am @@ -51,7 +51,8 @@ py_tests = t-wrapper.py \ t-file-name.py \ t-idiomatic.py \ t-protocol-assuan.py \ - t-quick-key-creation.py + t-quick-key-creation.py \ + t-quick-subkey-creation.py XTESTS = initial.py $(py_tests) final.py EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \ diff --git a/lang/python/tests/t-quick-subkey-creation.py b/lang/python/tests/t-quick-subkey-creation.py new file mode 100755 index 0000000..0d9f71f --- /dev/null +++ b/lang/python/tests/t-quick-subkey-creation.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +# Copyright (C) 2017 g10 Code 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 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 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 . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +import gpg +import itertools +import os +import shutil +import time + +import support + +alpha = "Alpha " +bravo = "Bravo " + +def copy_configuration(destination): + home = os.environ['GNUPGHOME'] + shutil.copy(os.path.join(home, "gpg.conf"), destination) + shutil.copy(os.path.join(home, "gpg-agent.conf"), destination) + +with support.TemporaryDirectory() as tmp: + copy_configuration(tmp) + with gpg.Context(home_dir=tmp) as ctx: + res = ctx.create_key(alpha, certify=True) + keys = list(ctx.keylist()) + assert len(keys) == 1, "Weird number of keys created" + key = keys[0] + assert key.fpr == res.fpr + assert len(key.subkeys) == 1, "Expected one primary key and no subkeys" + + def get_subkey(fpr): + k = ctx.get_key(fpr) + for sk in k.subkeys: + if sk.fpr == fpr: + return sk + return None + + # Check gpg.constants.create.NOEXPIRE... + res = ctx.create_subkey(key, expires=False) + subkey = get_subkey(res.fpr) + assert subkey.expires == 0, "Expected subkey not to expire" + assert subkey.can_encrypt, \ + "Default subkey capabilities do not include encryption" + + t = 2 * 24 * 60 * 60 + slack = 5 * 60 + res = ctx.create_subkey(key, expires_in=t) + subkey = get_subkey(res.fpr) + assert abs(time.time() + t - subkey.expires) < slack, \ + "subkeys expiration time is off" + + # Check capabilities + for sign, encrypt, authenticate in itertools.product([False, True], + [False, True], + [False, True]): + # Filter some out + if not (sign or encrypt or authenticate): + # This triggers the default capabilities tested before. + continue + + res = ctx.create_subkey(key, sign=sign, encrypt=encrypt, + authenticate=authenticate) + subkey = get_subkey(res.fpr) + assert sign == subkey.can_sign + assert encrypt == subkey.can_encrypt + assert authenticate == subkey.can_authenticate + + # Check algorithm + res = ctx.create_subkey(key, algorithm="rsa") + subkey = get_subkey(res.fpr) + assert subkey.pubkey_algo == 1 + + # Check algorithm with size + res = ctx.create_subkey(key, algorithm="rsa1024") + subkey = get_subkey(res.fpr) + assert subkey.pubkey_algo == 1 + assert subkey.length == 1024 + + # Check algorithm future-default + ctx.create_subkey(key, algorithm="future-default") + + # Check passphrase protection. For this we create a new key + # so that we have a key with just one encryption subkey. + bravo_res = ctx.create_key(bravo, certify=True) + bravo_key = ctx.get_key(bravo_res.fpr) + assert len(bravo_key.subkeys) == 1, "Expected one primary key and no subkeys" + + passphrase = "streng geheim" + res = ctx.create_subkey(bravo_key, passphrase=passphrase) + ciphertext, _, _ = ctx.encrypt(b"hello there", + recipients=[ctx.get_key(bravo_res.fpr)]) + + cb_called = False + def cb(*args): + global cb_called + cb_called = True + return passphrase + ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK + ctx.set_passphrase_cb(cb) + + plaintext, _, _ = ctx.decrypt(ciphertext) + assert plaintext == b"hello there" + assert cb_called commit 476b97822b169c30cc246c1de2ff94cf89084706 Author: Justus Winter Date: Thu Feb 16 14:53:11 2017 +0100 python: Support quick key creation. * NEWS: Update. * lang/python/gpg/constants/__init__.py: Import new file. * lang/python/gpg/constants/create.py: New file. * lang/python/gpg/core.py (Context.create_key): New function. * lang/python/tests/Makefile.am (XTESTS): Add new test. * lang/python/tests/support.py (TemporaryDirectory): New class. * lang/python/tests/t-quick-key-creation.py: New file. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 82f403c..7d30b94 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,7 @@ Noteworthy changes in version 1.8.1 (unreleased) py: Context.__init__ EXTENDED: New keyword arg home_dir. py: Context.home_dir NEW. py: Context.keylist EXTENDED: New keyword arg mode. + py: Context.create_key NEW. py: core.pubkey_algo_string NEW. py: core.addrspec_from_uid NEW. diff --git a/lang/python/gpg/constants/__init__.py b/lang/python/gpg/constants/__init__.py index 4fb3d6f..2bf180e 100644 --- a/lang/python/gpg/constants/__init__.py +++ b/lang/python/gpg/constants/__init__.py @@ -25,8 +25,8 @@ util.process_constants('GPGME_', globals()) del util # For convenience, we import the modules here. -from . import data, event, keylist, md, pk -from . import protocol, sig, sigsum, status, validity +from . import data, keylist, sig # The subdirs. +from . import create, event, md, pk, protocol, sigsum, status, validity # A complication arises because 'import' is a reserved keyword. # Import it as 'Import' instead. @@ -34,7 +34,7 @@ globals()['Import'] = getattr(__import__('', globals(), locals(), [str('import')], 1), "import") __all__ = ['data', 'event', 'import', 'keylist', 'md', 'pk', - 'protocol', 'sig', 'sigsum', 'status', 'validity'] + 'protocol', 'sig', 'sigsum', 'status', 'validity', 'create'] # GPGME 1.7 replaced gpgme_op_edit with gpgme_op_interact. We # implement gpg.Context.op_edit using gpgme_op_interact, so the diff --git a/lang/python/gpg/constants/create.py b/lang/python/gpg/constants/create.py new file mode 100644 index 0000000..132e96d --- /dev/null +++ b/lang/python/gpg/constants/create.py @@ -0,0 +1,25 @@ +# Flags for key creation +# +# Copyright (C) 2017 g10 Code 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, see . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +from gpg import util +util.process_constants('GPGME_CREATE_', globals()) +del util diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index 3a63516..c5af1b1 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -1,4 +1,4 @@ -# Copyright (C) 2016 g10 Code GmbH +# Copyright (C) 2016-2017 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # Copyright (C) 2002 John Goerzen # @@ -501,6 +501,84 @@ class Context(GpgmeWrapper): self.set_keylist_mode(mode) return self.op_keylist_all(pattern, secret) + def create_key(self, userid, algorithm=None, expires_in=0, expires=True, + sign=False, encrypt=False, certify=False, authenticate=False, + passphrase=None, force=False): + """Create a primary key + + Create a primary key for the user id USERID. + + ALGORITHM may be used to specify the public key encryption + algorithm for the new key. By default, a reasonable default + is chosen. You may use "future-default" to select an + algorithm that will be the default in a future implementation + of the engine. ALGORITHM may be a string like "rsa", or + "rsa2048" to explicitly request an algorithm and a key size. + + EXPIRES_IN specifies the expiration time of the key in number + of seconds since the keys creation. By default, a reasonable + expiration time is chosen. If you want to create a key that + does not expire, use the keyword argument EXPIRES. + + SIGN, ENCRYPT, CERTIFY, and AUTHENTICATE can be used to + request the capabilities of the new key. If you don't request + any, a reasonable set of capabilities is selected, and in case + of OpenPGP, a subkey with a reasonable set of capabilities is + created. + + If PASSPHRASE is None (the default), then the key will not be + protected with a passphrase. If PASSPHRASE is a string, it + will be used to protect the key. If PASSPHRASE is True, the + passphrase must be supplied using a passphrase callback or + out-of-band with a pinentry. + + Keyword arguments: + algorithm -- public key algorithm, see above (default: reasonable) + expires_in -- expiration time in seconds (default: reasonable) + expires -- whether or not the key should expire (default: True) + sign -- request the signing capability (see above) + encrypt -- request the encryption capability (see above) + certify -- request the certification capability (see above) + authenticate -- request the authentication capability (see above) + passphrase -- protect the key with a passphrase (default: no passphrase) + force -- force key creation even if a key with the same userid exists + (default: False) + + Returns: + -- an object describing the result of the key creation + + Raises: + GPGMEError -- as signaled by the underlying library + + """ + if util.is_a_string(passphrase): + old_pinentry_mode = self.pinentry_mode + old_passphrase_cb = getattr(self, '_passphrase_cb', None) + self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK + def passphrase_cb(hint, desc, prev_bad, hook=None): + return passphrase + self.set_passphrase_cb(passphrase_cb) + + try: + self.op_createkey(userid, algorithm, + 0, # reserved + expires_in, + None, # extrakey + ((constants.create.SIGN if sign else 0) + | (constants.create.ENCR if encrypt else 0) + | (constants.create.CERT if certify else 0) + | (constants.create.AUTH if authenticate else 0) + | (constants.create.NOPASSWD if passphrase == None else 0) + | (0 if expires else constants.create.NOEXPIRE) + | (constants.create.FORCE if force else 0))) + finally: + if util.is_a_string(passphrase): + self.pinentry_mode = old_pinentry_mode + if old_passphrase_cb: + self.set_passphrase_cb(*old_passphrase_cb[1:]) + + return self.op_genkey_result() + 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/Makefile.am b/lang/python/tests/Makefile.am index d7f2e58..5469e75 100644 --- a/lang/python/tests/Makefile.am +++ b/lang/python/tests/Makefile.am @@ -50,7 +50,8 @@ py_tests = t-wrapper.py \ t-encrypt-large.py \ t-file-name.py \ t-idiomatic.py \ - t-protocol-assuan.py + t-protocol-assuan.py \ + t-quick-key-creation.py XTESTS = initial.py $(py_tests) final.py EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \ diff --git a/lang/python/tests/support.py b/lang/python/tests/support.py index 0b04bb6..ed5bf61 100644 --- a/lang/python/tests/support.py +++ b/lang/python/tests/support.py @@ -20,6 +20,7 @@ del absolute_import, print_function, unicode_literals import sys import os +import tempfile import gpg # known keys @@ -72,3 +73,17 @@ def mark_key_trusted(ctx, key): return result with gpg.Data() as sink: ctx.op_edit(key, Editor().edit, sink, sink) + + +# Python2/3 compatibility +if hasattr(tempfile, "TemporaryDirectory"): + # Python3.2 and up + TemporaryDirectory = tempfile.TemporaryDirectory +else: + class TemporaryDirectory(object): + def __enter__(self): + self.path = tempfile.mkdtemp() + return self.path + def __exit__(self, *args): + import shutil + shutil.rmtree(self.path) diff --git a/lang/python/tests/t-quick-key-creation.py b/lang/python/tests/t-quick-key-creation.py new file mode 100755 index 0000000..ea63dc3 --- /dev/null +++ b/lang/python/tests/t-quick-key-creation.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python + +# Copyright (C) 2017 g10 Code 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 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 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 . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +import gpg +import itertools +import os +import shutil +import time + +import support + +alpha = "Alpha " + +def copy_configuration(destination): + home = os.environ['GNUPGHOME'] + shutil.copy(os.path.join(home, "gpg.conf"), destination) + shutil.copy(os.path.join(home, "gpg-agent.conf"), destination) + +with support.TemporaryDirectory() as tmp: + copy_configuration(tmp) + with gpg.Context(home_dir=tmp) as ctx: + res = ctx.create_key(alpha) + + keys = list(ctx.keylist()) + assert len(keys) == 1, "Weird number of keys created" + + key = keys[0] + assert key.fpr == res.fpr + assert len(key.subkeys) == 2, "Expected one primary key and one subkey" + assert key.subkeys[0].expires > 0, "Expected primary key to expire" + + # Try to create a key with the same UID + try: + ctx.create_key(alpha) + assert False, "Expected an error but got none" + except gpg.errors.GpgError as e: + pass + + # Try to create a key with the same UID, now with force! + res2 = ctx.create_key(alpha, force=True) + assert res.fpr != res2.fpr + + +# From here on, we use one context, and create unique UIDs +uid_counter = 0 +def make_uid(): + global uid_counter + uid_counter += 1 + return "user{0}@invalid.example.org".format(uid_counter) + +with support.TemporaryDirectory() as tmp: + copy_configuration(tmp) + with gpg.Context(home_dir=tmp) as ctx: + + # Check gpg.constants.create.NOEXPIRE... + res = ctx.create_key(make_uid(), expires=False) + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + assert len(key.subkeys) == 2, "Expected one primary key and one subkey" + assert key.subkeys[0].expires == 0, "Expected primary key not to expire" + + t = 2 * 24 * 60 * 60 + slack = 5 * 60 + res = ctx.create_key(make_uid(), expires_in=t) + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + assert len(key.subkeys) == 2, "Expected one primary key and one subkey" + assert abs(time.time() + t - key.subkeys[0].expires) < slack, \ + "Primary keys expiration time is off" + + # Check capabilities + for sign, encrypt, certify, authenticate in itertools.product([False, True], + [False, True], + [False, True], + [False, True]): + # Filter some out + if not (sign or encrypt or certify or authenticate): + # This triggers the default capabilities tested before. + continue + if (sign or encrypt or authenticate) and not certify: + # The primary key always certifies. + continue + + res = ctx.create_key(make_uid(), algorithm="rsa", + sign=sign, encrypt=encrypt, certify=certify, + authenticate=authenticate) + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + assert len(key.subkeys) == 1, \ + "Expected no subkey for non-default capabilities" + + p = key.subkeys[0] + assert sign == p.can_sign + assert encrypt == p.can_encrypt + assert certify == p.can_certify + assert authenticate == p.can_authenticate + + # Check algorithm + res = ctx.create_key(make_uid(), algorithm="rsa") + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + for k in key.subkeys: + assert k.pubkey_algo == 1 + + # Check algorithm with size + res = ctx.create_key(make_uid(), algorithm="rsa1024") + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + for k in key.subkeys: + assert k.pubkey_algo == 1 + assert k.length == 1024 + + # Check algorithm future-default + ctx.create_key(make_uid(), algorithm="future-default") + + # Check passphrase protection + recipient = make_uid() + passphrase = "streng geheim" + res = ctx.create_key(recipient, passphrase=passphrase) + ciphertext, _, _ = ctx.encrypt(b"hello there", recipients=[ctx.get_key(res.fpr)]) + + cb_called = False + def cb(*args): + global cb_called + cb_called = True + return passphrase + ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK + ctx.set_passphrase_cb(cb) + + plaintext, _, _ = ctx.decrypt(ciphertext) + assert plaintext == b"hello there" + assert cb_called commit 3bdce4aa3ddd4a3f55b24678faf978d61daa8909 Author: Justus Winter Date: Thu Feb 16 14:49:27 2017 +0100 python: Fix passphrase callback wrapping. * lang/python/helpers.c (pyPassphraseCb): Cope with 'passphrase_info' being NULL. Signed-off-by: Justus Winter diff --git a/lang/python/helpers.c b/lang/python/helpers.c index 576767c..947819d 100644 --- a/lang/python/helpers.c +++ b/lang/python/helpers.c @@ -377,7 +377,21 @@ static gpgme_error_t pyPassphraseCb(void *hook, goto leave; } - PyTuple_SetItem(args, 1, PyBytes_FromString(passphrase_info)); + if (passphrase_info == NULL) + { + Py_INCREF(Py_None); + PyTuple_SetItem(args, 1, Py_None); + } + else + PyTuple_SetItem(args, 1, PyUnicode_DecodeUTF8(passphrase_info, + strlen (passphrase_info), + "strict")); + if (PyErr_Occurred()) { + Py_DECREF(args); + err_status = gpg_error(GPG_ERR_GENERAL); + goto leave; + } + PyTuple_SetItem(args, 2, PyBool_FromLong((long)prev_was_bad)); if (dataarg) { Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */ commit 048c5f74b61d5e4fa7617ce7c9111c6754bd4409 Author: Justus Winter Date: Thu Feb 16 14:42:17 2017 +0100 python: Fix error handling. * lang/python/gpgme.i (typemap gpgme_key_t[]): Set an error if a non-key element is discovered. Signed-off-by: Justus Winter diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index c7fc14e..3e89bb1 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -137,7 +137,12 @@ /* Following code is from swig's python.swg. */ if ((SWIG_ConvertPtr(pypointer,(void **) &$1[i], $*1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) { - Py_DECREF(pypointer); + Py_DECREF(pypointer); + PyErr_Format(PyExc_TypeError, + "arg %d: list must contain only gpgme_key_ts, got %s " + "at position %d", + $argnum, pypointer->ob_type->tp_name, i); + free($1); return NULL; } Py_DECREF(pypointer); ----------------------------------------------------------------------- Summary of changes: NEWS | 4 + lang/python/gpg/constants/__init__.py | 6 +- .../gpg/constants/{sig/notation.py => create.py} | 6 +- lang/python/gpg/core.py | 176 ++++++++++++++++++++- lang/python/gpgme.i | 7 +- lang/python/helpers.c | 16 +- lang/python/tests/Makefile.am | 5 +- lang/python/tests/support.py | 15 ++ lang/python/tests/t-quick-key-creation.py | 151 ++++++++++++++++++ lang/python/tests/t-quick-key-manipulation.py | 103 ++++++++++++ lang/python/tests/t-quick-subkey-creation.py | 121 ++++++++++++++ 11 files changed, 600 insertions(+), 10 deletions(-) copy lang/python/gpg/constants/{sig/notation.py => create.py} (86%) create mode 100755 lang/python/tests/t-quick-key-creation.py create mode 100755 lang/python/tests/t-quick-key-manipulation.py create mode 100755 lang/python/tests/t-quick-subkey-creation.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 16 21:33:20 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 16 Feb 2017 21:33:20 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-92-g7006352 Message-ID: This is an 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 7006352da773d82c47797bbf11e570ecafac6501 (commit) via 9a1a5ca0bc2cfb17ccf632de3e134b6d789c6855 (commit) from 09d71de4d4f0a813ba3e584540f899bfd6c568cd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7006352da773d82c47797bbf11e570ecafac6501 Author: Werner Koch Date: Thu Feb 16 21:25:58 2017 +0100 dirmngr,w32: Load all system provided certificates. * dirmngr/certcache.c (CERTOPENSYSTEMSTORE) [W32]: New type. (CERTENUMCERTIFICATESINSTORE) [W32]: New type. (CERTCLOSESTORE) [W32]: New type. (load_certs_from_file) [W32]: Do not build. (load_certs_from_w32_store) [W32]: New. (load_certs_from_system) [W32]: Call new function. -- GnuTLS loads the system certificates from the "ROOT" and "CA" store; thus we do the same. On a Visa box you may for example see 21 from "ROOT" and 6 from "CA". Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 626e440..cd026c2 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -100,6 +100,20 @@ static unsigned int total_extra_certificates; static unsigned int total_trusted_certificates; static unsigned int total_system_trusted_certificates; + +#ifdef HAVE_W32_SYSTEM +/* We load some functions dynamically. Provide typedefs for tehse + * fucntions. */ +typedef HCERTSTORE (WINAPI *CERTOPENSYSTEMSTORE) + (HCRYPTPROV hProv, LPCSTR szSubsystemProtocol); +typedef PCCERT_CONTEXT (WINAPI *CERTENUMCERTIFICATESINSTORE) + (HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext); +typedef WINBOOL (WINAPI *CERTCLOSESTORE) + (HCERTSTORE hCertStore,DWORD dwFlags); +#endif /*HAVE_W32_SYSTEM*/ + + + /* Helper to do the cache locking. */ static void @@ -444,9 +458,10 @@ load_certs_from_dir (const char *dirname, int are_trusted) } +#ifndef HAVE_W32_SYSTEM /* Load certificates from FILE. The certifciates are expected to be * PEM encoded so that it is possible to load several certificates. - * All certates rea considered to be system provided trusted + * All certificates are considered to be system provided trusted * certificates. The cache should be in a locked state when calling * this function. */ static gpg_error_t @@ -523,12 +538,133 @@ load_certs_from_file (const char *fname) return err; } +#endif /*!HAVE_W32_SYSTEM*/ + +#ifdef HAVE_W32_SYSTEM +/* Load all certificates from the Windows store named STORENAME. All + * certificates are considered to be system provided trusted + * certificates. The cache should be in a locked state when calling + * this function. */ +static void +load_certs_from_w32_store (const char *storename) +{ + static int init_done; + static CERTOPENSYSTEMSTORE pCertOpenSystemStore; + static CERTENUMCERTIFICATESINSTORE pCertEnumCertificatesInStore; + static CERTCLOSESTORE pCertCloseStore; + gpg_error_t err; + HCERTSTORE w32store; + const CERT_CONTEXT *w32cert; + ksba_cert_t cert = NULL; + unsigned int count = 0; + + /* Initialize on the first use. */ + if (!init_done) + { + static HANDLE hCrypt32; + + init_done = 1; + + hCrypt32 = LoadLibrary ("Crypt32.dll"); + if (!hCrypt32) + { + log_error ("can't load Crypt32.dll: %s\n", w32_strerror (-1)); + return; + } + + pCertOpenSystemStore = (CERTOPENSYSTEMSTORE) + GetProcAddress (hCrypt32, "CertOpenSystemStoreA"); + pCertEnumCertificatesInStore = (CERTENUMCERTIFICATESINSTORE) + GetProcAddress (hCrypt32, "CertEnumCertificatesInStore"); + pCertCloseStore = (CERTCLOSESTORE) + GetProcAddress (hCrypt32, "CertCloseStore"); + if ( !pCertOpenSystemStore + || !pCertEnumCertificatesInStore + || !pCertCloseStore) + { + log_error ("can't load crypt32.dll: %s\n", "missing function"); + pCertOpenSystemStore = NULL; + } + } + + if (!pCertOpenSystemStore) + return; /* Not initialized. */ + + + w32store = pCertOpenSystemStore (0, storename); + if (!w32store) + { + log_error ("can't open certificate store '%s': %s\n", + storename, w32_strerror (-1)); + return; + } + + w32cert = NULL; + while ((w32cert = pCertEnumCertificatesInStore (w32store, w32cert))) + { + if (w32cert->dwCertEncodingType == X509_ASN_ENCODING) + { + ksba_cert_release (cert); + cert = NULL; + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_init_from_mem (cert, + w32cert->pbCertEncoded, + w32cert->cbCertEncoded); + if (err) + { + log_error (_("can't parse certificate '%s': %s\n"), + storename, gpg_strerror (err)); + break; + } + + err = put_cert (cert, 1, 2, NULL); + if (!err) + count++; + if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) + log_info (_("certificate '%s' already cached\n"), storename); + else if (err) + log_error (_("error loading certificate '%s': %s\n"), + storename, gpg_strerror (err)); + else if (opt.verbose > 1) + { + char *p; + + log_info (_("trusted certificate '%s' loaded\n"), storename); + p = get_fingerprint_hexstring_colon (cert); + log_info (_(" SHA1 fingerprint = %s\n"), p); + xfree (p); + + cert_log_name (_(" issuer ="), cert); + cert_log_subject (_(" subject ="), cert); + } + } + } + + ksba_cert_release (cert); + pCertCloseStore (w32store, 0); + + if (DBG_X509) + log_debug ("number of certs loaded from store '%s': %u\n", + storename, count); + +} +#endif /*HAVE_W32_SYSTEM*/ /* Load the trusted certificates provided by the system. */ static gpg_error_t load_certs_from_system (void) { +#ifdef HAVE_W32_SYSTEM + + load_certs_from_w32_store ("ROOT"); + load_certs_from_w32_store ("CA"); + + return 0; + +#else /*!HAVE_W32_SYSTEM*/ + /* A list of certificate bundles to try. */ static struct { const char *name; @@ -554,8 +690,8 @@ load_certs_from_system (void) break; } - return err; +#endif /*!HAVE_W32_SYSTEM*/ } commit 9a1a5ca0bc2cfb17ccf632de3e134b6d789c6855 Author: Werner Koch Date: Thu Feb 16 18:58:27 2017 +0100 dirmngr: Load all system provided certificates. * configure.ac: Add option --default-trust-store. (DEFAULT_TRUST_STORE_FILE): New ac_define. * dirmngr/certcache.c: Include ksba-io-support.h. (total_trusted_certificates, total_system_trusted_certificates): New. (put_cert): Manage the new counters. (cert_cache_deinit): Reset them. (cert_cache_print_stats): Print them. (is_trusted_cert): Add arg WITH_SYSTRUST. Change all callers to pass false. (load_certs_from_file): New. (load_certs_from_system): New. (cert_cache_init): Load system certificates. -- Note that this code does not yet allow to load the system certificates on Windows. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index ce02d03..1733c5a 100644 --- a/configure.ac +++ b/configure.ac @@ -990,6 +990,22 @@ else fi fi +# +# Allow to set a fixed trust store file for system provided certificates. +# +AC_ARG_WITH([default-trust-store-file], + [AC_HELP_STRING([--with-default-trust-store-file=FILE], + [Use FILE as system trust store])], + default_trust_store_file="$withval", + default_trust_store_file="") +if test x"$default_trust_store_file" = xno;then + default_trust_store_file="" +fi +if test x"$default_trust_store_file" != x ; then + AC_DEFINE_UNQUOTED([DEFAULT_TRUST_STORE_FILE], + ["$default_trust_store_file"], [Use as default system trust store file]) +fi + AC_MSG_NOTICE([checking for networking options]) diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index d68d503..626e440 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -1,5 +1,5 @@ /* certcache.c - Certificate caching - * Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH + * Copyright (C) 2004, 2005, 2007, 2008, 2017 g10 Code GmbH * * This file is part of DirMngr. * @@ -29,10 +29,10 @@ #include "dirmngr.h" #include "misc.h" +#include "../common/ksba-io-support.h" #include "crlfetch.h" #include "certcache.h" - #define MAX_EXTRA_CACHED_CERTS 1000 /* Constants used to classify search patterns. */ @@ -93,10 +93,12 @@ static npth_rwlock_t cert_cache_lock; static int initialization_done; /* Total number of certificates loaded during initialization - * (ie. configured) and extra certifcates cached during operation. */ + * (ie. configured), extra certificates cached during operation, + * number of trusted and system trusted certificates. */ static unsigned int total_config_certificates; static unsigned int total_extra_certificates; - +static unsigned int total_trusted_certificates; +static unsigned int total_system_trusted_certificates; /* Helper to do the cache locking. */ @@ -288,6 +290,10 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) clean_cache_slot (ci_mark); drop_count--; total_extra_certificates--; + if (ci->flags.trusted) + total_trusted_certificates--; + if (ci->flags.systrust) + total_system_trusted_certificates--; } } if (i==idx) @@ -331,6 +337,11 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) ci->flags.trusted = !!is_trusted; ci->flags.systrust = (is_trusted && is_trusted == 2); + if (ci->flags.trusted) + total_trusted_certificates++; + if (ci->flags.systrust) + total_system_trusted_certificates++; + if (from_config) total_config_certificates++; else @@ -433,6 +444,121 @@ load_certs_from_dir (const char *dirname, int are_trusted) } +/* Load certificates from FILE. The certifciates are expected to be + * PEM encoded so that it is possible to load several certificates. + * All certates rea considered to be system provided trusted + * certificates. The cache should be in a locked state when calling + * this function. */ +static gpg_error_t +load_certs_from_file (const char *fname) +{ + gpg_error_t err; + estream_t fp = NULL; + gnupg_ksba_io_t ioctx = NULL; + ksba_reader_t reader; + ksba_cert_t cert = NULL; + + fp = es_fopen (fname, "rb"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); + goto leave; + } + + err = gnupg_ksba_create_reader (&ioctx, + (GNUPG_KSBA_IO_PEM | GNUPG_KSBA_IO_MULTIPEM), + fp, &reader); + if (err) + { + log_error ("can't create reader: %s\n", gpg_strerror (err)); + goto leave; + } + + /* Loop to read all certificates from the file. */ + do + { + ksba_cert_release (cert); + cert = NULL; + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_read_der (cert, reader); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_EOF) + err = 0; + else + log_error (_("can't parse certificate '%s': %s\n"), + fname, gpg_strerror (err)); + goto leave; + } + + err = put_cert (cert, 1, 2, NULL); + if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) + log_info (_("certificate '%s' already cached\n"), fname); + else if (err) + log_error (_("error loading certificate '%s': %s\n"), + fname, gpg_strerror (err)); + else if (opt.verbose > 1) + { + char *p; + + log_info (_("trusted certificate '%s' loaded\n"), fname); + p = get_fingerprint_hexstring_colon (cert); + log_info (_(" SHA1 fingerprint = %s\n"), p); + xfree (p); + + cert_log_name (_(" issuer ="), cert); + cert_log_subject (_(" subject ="), cert); + } + + ksba_reader_clear (reader, NULL, NULL); + } + while (!gnupg_ksba_reader_eof_seen (ioctx)); + + leave: + ksba_cert_release (cert); + gnupg_ksba_destroy_reader (ioctx); + es_fclose (fp); + + return err; +} + + +/* Load the trusted certificates provided by the system. */ +static gpg_error_t +load_certs_from_system (void) +{ + /* A list of certificate bundles to try. */ + static struct { + const char *name; + } table[] = { +#ifdef DEFAULT_TRUST_STORE_FILE + { DEFAULT_TRUST_STORE_FILE } +#else + { "/etc/ssl/ca-bundle.pem" }, + { "/etc/ssl/certs/ca-certificates.crt" }, + { "/etc/pki/tls/cert.pem" }, + { "/usr/local/share/certs/ca-root-nss.crt" }, + { "/etc/ssl/cert.pem" } +#endif /*!DEFAULT_TRUST_STORE_FILE*/ + }; + int idx; + gpg_error_t err = 0; + + for (idx=0; idx < DIM (table); idx++) + if (!access (table[idx].name, F_OK)) + { + /* Take the first available bundle. */ + err = load_certs_from_file (table[idx].name); + break; + } + + + return err; +} + + /* Initialize the certificate cache if not yet done. */ void cert_cache_init (void) @@ -444,6 +570,8 @@ cert_cache_init (void) init_cache_lock (); acquire_cache_write_lock (); + load_certs_from_system (); + dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL); load_certs_from_dir (dname, 1); xfree (dname); @@ -490,6 +618,8 @@ cert_cache_deinit (int full) total_config_certificates = 0; total_extra_certificates = 0; + total_trusted_certificates = 0; + total_system_trusted_certificates = 0; initialization_done = 0; release_cache_lock (); } @@ -502,6 +632,8 @@ cert_cache_print_stats (void) total_config_certificates); log_info (_(" runtime cached certificates: %u\n"), total_extra_certificates); + log_info (_(" trusted certificates: %u (%u)\n"), + total_trusted_certificates, total_system_trusted_certificates); } @@ -1274,11 +1406,12 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) } -/* Return 0 if the certificate is a trusted certificate. Returns - GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in - case of systems errors. */ +/* Return 0 if the certificate is a trusted certificate. Returns + * GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in + * case of systems errors. If WITH_SYSTRUST is set also system + * provided certificates are considered trusted. */ gpg_error_t -is_trusted_cert (ksba_cert_t cert) +is_trusted_cert (ksba_cert_t cert, int with_systrust) { unsigned char fpr[20]; cert_item_t ci; @@ -1289,7 +1422,7 @@ is_trusted_cert (ksba_cert_t cert) for (ci=cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp (ci->fpr, fpr, 20)) { - if (ci->flags.trusted) + if (ci->flags.trusted && (with_systrust || !ci->flags.systrust)) { release_cache_lock (); return 0; /* Yes, it is trusted. */ diff --git a/dirmngr/certcache.h b/dirmngr/certcache.h index 9986f15..ac93ee6 100644 --- a/dirmngr/certcache.h +++ b/dirmngr/certcache.h @@ -41,9 +41,10 @@ gpg_error_t cache_cert (ksba_cert_t cert); gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer); /* Return 0 if the certificate is a trusted certificate. Returns - GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in - case of systems errors. */ -gpg_error_t is_trusted_cert (ksba_cert_t cert); + * GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in + * case of systems errors. If WITH_SYSTRUST is set also system + * provided certificates are considered trusted. */ +gpg_error_t is_trusted_cert (ksba_cert_t cert, int with_systrust); /* Return a certificate object for the given fingerprint. FPR is diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 68e1bb3..4139c22 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -189,7 +189,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen) return err; if (!flag) { - if (!is_trusted_cert (cert)) + if (!is_trusted_cert (cert, 0)) { /* The German SigG Root CA's certificate does not flag itself as a CA; thus we relax this requirement if we @@ -537,7 +537,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (err) goto leave; /* No. */ - err = is_trusted_cert (subject_cert); + err = is_trusted_cert (subject_cert, 0); if (!err) ; /* Yes we trust this cert. */ else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) ----------------------------------------------------------------------- Summary of changes: configure.ac | 16 +++ dirmngr/certcache.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++-- dirmngr/certcache.h | 7 +- dirmngr/validate.c | 4 +- 4 files changed, 299 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 03:58:17 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 17 Feb 2017 03:58:17 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-93-g99d4dfe Message-ID: This is an 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 99d4dfe83661d05ef3a20ed04e6cec5647536738 (commit) from 7006352da773d82c47797bbf11e570ecafac6501 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 99d4dfe83661d05ef3a20ed04e6cec5647536738 Author: NIIBE Yutaka Date: Fri Feb 17 11:50:40 2017 +0900 scd: Fix RESET command handling (more). * scd/app-common.h (struct app_ctx_s): Add reset_requested. * scd/app.c (app_reset): Locking APP, set reset_requested. (deallocate_app): Release the lock. (release_application): Add LOCKED_ALREADY argument. (scd_update_reader_status_file): Hold the lock when accessing APP. When reset_requested is set, close the reader and deallocate APP. * scd/command.c (open_card_with_request, cmd_restart): Follow the change of release_application. (send_client_notifications): Here it calls release_application holding the lock. Signed-off-by: NIIBE Yutaka diff --git a/scd/app-common.h b/scd/app-common.h index c79e36b..38e6cc6 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -54,6 +54,7 @@ struct app_ctx_s { const char *apptype; unsigned int card_version; unsigned int card_status; + unsigned int reset_requested:1; unsigned int periodical_check_needed:1; unsigned int did_chv1:1; unsigned int force_chv1:1; /* True if the card does not cache CHV1. */ @@ -132,7 +133,7 @@ gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app, int scan, const unsigned char *serialno_bin, size_t serialno_bin_len); char *get_supported_applications (void); -void release_application (app_t app); +void release_application (app_t app, int locked_already); gpg_error_t app_munge_serialno (app_t app); gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags); diff --git a/scd/app.c b/scd/app.c index b6f3a05..1d81631 100644 --- a/scd/app.c +++ b/scd/app.c @@ -143,19 +143,23 @@ app_reset (app_t app, ctrl_t ctrl, int send_reset) if (send_reset) { - int sw = apdu_reset (app->slot); + int sw; + + lock_app (app, ctrl); + sw = apdu_reset (app->slot); if (sw) err = gpg_error (GPG_ERR_CARD_RESET); - /* Release the same application which is used by all sessions. */ - send_client_notifications (app, 1); + app->reset_requested = 1; + unlock_app (app); + scd_kick_the_loop (); gnupg_sleep (1); } else { ctrl->app_ctx = NULL; - release_application (app); + release_application (app, 0); } return err; @@ -454,6 +458,8 @@ deallocate_app (app_t app) } xfree (app->serialno); + + unlock_app (app); xfree (app); } @@ -463,7 +469,7 @@ deallocate_app (app_t app) actually deferring the deallocation to allow for a later reuse by a new connection. */ void -release_application (app_t app) +release_application (app_t app, int locked_already) { if (!app) return; @@ -473,12 +479,15 @@ release_application (app_t app) is using the card - this way the PIN cache and other cached data are preserved. */ - lock_app (app, NULL); + if (!locked_already) + lock_app (app, NULL); + if (!app->ref_count) log_bug ("trying to release an already released context\n"); --app->ref_count; - unlock_app (app); + if (!locked_already) + unlock_app (app); } @@ -1019,9 +1028,10 @@ scd_update_reader_status_file (void) int sw; unsigned int status; + lock_app (a, NULL); app_next = a->next; - if (a->ref_count == 0) + if (a->reset_requested) status = 0; else { @@ -1036,6 +1046,7 @@ scd_update_reader_status_file (void) /* Get status failed. Ignore that. */ if (a->periodical_check_needed) periodical_check_needed = 1; + unlock_app (a); continue; } } @@ -1056,12 +1067,14 @@ scd_update_reader_status_file (void) a->card_status = status; if (a->periodical_check_needed) periodical_check_needed = 1; + unlock_app (a); } } else { if (a->periodical_check_needed) periodical_check_needed = 1; + unlock_app (a); } } npth_mutex_unlock (&app_list_lock); diff --git a/scd/command.c b/scd/command.c index bd7e803..5b7ddc8 100644 --- a/scd/command.c +++ b/scd/command.c @@ -227,7 +227,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno) /* Re-scan USB devices. Release APP, before the scan. */ ctrl->app_ctx = NULL; - release_application (app); + release_application (app, 0); if (serialno) serialno_bin = hex_to_buffer (serialno, &serialno_bin_len); @@ -1495,7 +1495,7 @@ cmd_restart (assuan_context_t ctx, char *line) if (app) { ctrl->app_ctx = NULL; - release_application (app); + release_application (app, 0); } if (locked_session && ctrl->server_local == locked_session) { @@ -1922,7 +1922,7 @@ send_client_notifications (app_t app, int removal) { sl->ctrl_backlink->app_ctx = NULL; sl->card_removed = 1; - release_application (app); + release_application (app, 1); } if (!sl->event_signal || !sl->assuan_ctx) ----------------------------------------------------------------------- Summary of changes: scd/app-common.h | 3 ++- scd/app.c | 29 +++++++++++++++++++++-------- scd/command.c | 6 +++--- 3 files changed, 26 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 10:51:32 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 17 Feb 2017 10:51:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-94-gaab6ba0 Message-ID: This is an 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 aab6ba0bb60528b9e816e430be51170cf39611b0 (commit) from 99d4dfe83661d05ef3a20ed04e6cec5647536738 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aab6ba0bb60528b9e816e430be51170cf39611b0 Author: Justus Winter Date: Fri Feb 17 10:43:20 2017 +0100 gpgscm: Guard use of tagged expressions. * tests/gpgscm/init.scm (vm-history-print): Check that the tag added to expressions when parsing source files matches the expected format. * tests/gpgscm/lib.scm (assert): Likewise. -- This makes the error handling more robust. We saw the assumption about the format of the tags being violated on one build system, and it obscured the view on the underlying problem. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/init.scm b/tests/gpgscm/init.scm index 83261b0..87d3c88 100644 --- a/tests/gpgscm/init.scm +++ b/tests/gpgscm/init.scm @@ -547,11 +547,11 @@ (display n) (display ": ") (let ((tag (get-tag f))) - (unless (null? tag) - (display (basename (car tag))) - (display ":") - (display (+ 1 (cdr tag))) - (display ": "))) + (when (and (pair? tag) (string? (car tag)) (number? (cdr tag))) + (display (basename (car tag))) + (display ":") + (display (+ 1 (cdr tag))) + (display ": "))) (write f)) (newline) (loop (+ n 1) skip (cdr frames)))))) diff --git a/tests/gpgscm/lib.scm b/tests/gpgscm/lib.scm index 6959aa4..2cfe725 100644 --- a/tests/gpgscm/lib.scm +++ b/tests/gpgscm/lib.scm @@ -20,7 +20,7 @@ (macro (assert form) (let ((tag (get-tag form))) `(if (not ,(cadr form)) - (throw ,(if (pair? tag) + (throw ,(if (and (pair? tag) (string? (car tag)) (number? (cdr tag))) `(string-append ,(car tag) ":" ,(number->string (+ 1 (cdr tag))) ": Assertion failed: ") ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/init.scm | 10 +++++----- tests/gpgscm/lib.scm | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 11:46:38 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 17 Feb 2017 11:46:38 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-95-g3f4f64b Message-ID: This is an 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 3f4f64b6ac0d7160fd9e1301f95820894b219c3f (commit) from aab6ba0bb60528b9e816e430be51170cf39611b0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3f4f64b6ac0d7160fd9e1301f95820894b219c3f Author: NIIBE Yutaka Date: Fri Feb 17 19:39:28 2017 +0900 agent: Send back all public keys for available cards. * agent/call-scd.c (card_cardlist_cb, agent_card_cardlist): New. * agent/command-ssh.c (card_key_list): New. (ssh_handler_request_identities): Call card_key_list and loop for the list to send public keys for all available cards. Signed-off-by: NIIBE Yutaka diff --git a/agent/agent.h b/agent/agent.h index 2178384..2a722fd 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -556,6 +556,7 @@ int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg); gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result); +gpg_error_t agent_card_cardlist (ctrl_t ctrl, strlist_t *result); int agent_card_scd (ctrl_t ctrl, const char *cmdline, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, void *assuan_context); diff --git a/agent/call-scd.c b/agent/call-scd.c index 15a2ba5..71e0f58 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -39,6 +39,7 @@ #include "agent.h" #include +#include "strlist.h" #ifdef _POSIX_OPEN_MAX #define MAX_OPEN_FDS _POSIX_OPEN_MAX @@ -1189,9 +1190,74 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result) return unlock_scd (ctrl, err); } + +struct card_cardlist_parm_s { + int error; + strlist_t list; +}; +/* Callback function for agent_card_cardlist. */ +static gpg_error_t +card_cardlist_cb (void *opaque, const char *line) +{ + struct card_cardlist_parm_s *parm = opaque; + const char *keyword = line; + int keywordlen; + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) + { + const char *s; + int n; + + for (n=0,s=line; hexdigitp (s); s++, n++) + ; + + if (!n || (n&1) || *s) + parm->error = gpg_error (GPG_ERR_ASS_PARAMETER); + else + add_to_strlist (&parm->list, line); + } + + return 0; +} + +/* Call the scdaemon to retrieve list of available cards. On success + the allocated strlist is stored at RESULT. On error an error code is + returned and NULL stored at RESULT. */ +gpg_error_t +agent_card_cardlist (ctrl_t ctrl, strlist_t *result) +{ + int err; + struct card_cardlist_parm_s parm; + char line[ASSUAN_LINELENGTH]; + + *result = NULL; + + memset (&parm, 0, sizeof parm); + strcpy (line, "GETINFO card_list"); + + err = start_scd (ctrl); + if (err) + return err; + + err = assuan_transact (ctrl->scd_local->ctx, line, + NULL, NULL, NULL, NULL, + card_cardlist_cb, &parm); + if (!err && parm.error) + err = parm.error; + + if (!err) + *result = parm.list; + else + free_strlist (parm.list); + + return unlock_scd (ctrl, err); +} static gpg_error_t pass_status_thru (void *opaque, const char *line) diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 1d4453c..2c74618 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2382,6 +2382,29 @@ ssh_key_grip (gcry_sexp_t key, unsigned char *buffer) } +static gpg_error_t +card_key_list (ctrl_t ctrl, char **r_serialno, strlist_t *result) +{ + gpg_error_t err; + + err = agent_card_serialno (ctrl, r_serialno, NULL); + if (err) + { + if (opt.verbose) + log_info (_("error getting serial number of card: %s\n"), + gpg_strerror (err)); + return err; + } + + err = agent_card_cardlist (ctrl, result); + if (err) + { + xfree (*r_serialno); + *r_serialno = NULL; + } + return err; +} + /* Check whether a smartcard is available and whether it has a usable key. Store a copy of that key at R_PK and return 0. If no key is available store NULL at R_PK and return an error code. If CARDSN @@ -2561,17 +2584,54 @@ ssh_handler_request_identities (ctrl_t ctrl, reader - this should be allowed even without being listed in sshcontrol. */ - if (!opt.disable_scdaemon - && !card_key_available (ctrl, &key_public, &cardsn)) + if (!opt.disable_scdaemon) { - err = ssh_send_key_public (key_blobs, key_public, cardsn); - gcry_sexp_release (key_public); - key_public = NULL; - xfree (cardsn); + char *serialno; + strlist_t card_list, sl; + + err = card_key_list (ctrl, &serialno, &card_list); if (err) - goto out; + { + if (opt.verbose) + log_info (_("error getting list of cards: %s\n"), + gpg_strerror (err)); + goto out; + } - key_counter++; + for (sl = card_list; sl; sl = sl->next) + { + char *serialno0; + err = agent_card_serialno (ctrl, &serialno0, sl->d); + if (err) + { + if (opt.verbose) + log_info (_("error getting serial number of card: %s\n"), + gpg_strerror (err)); + xfree (serialno); + free_strlist (card_list); + goto out; + } + + xfree (serialno0); + if (card_key_available (ctrl, &key_public, &cardsn)) + continue; + + err = ssh_send_key_public (key_blobs, key_public, cardsn); + gcry_sexp_release (key_public); + key_public = NULL; + xfree (cardsn); + if (err) + { + xfree (serialno); + free_strlist (card_list); + goto out; + } + + key_counter++; + } + + xfree (serialno); + free_strlist (card_list); } /* Then look at all the registered and non-disabled keys. */ ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 1 + agent/call-scd.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ agent/command-ssh.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 135 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 12:04:06 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 17 Feb 2017 12:04:06 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-96-gdea4b3c Message-ID: This is an 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 dea4b3c742acbd195d6ab12b279b4dda315f2582 (commit) from 3f4f64b6ac0d7160fd9e1301f95820894b219c3f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dea4b3c742acbd195d6ab12b279b4dda315f2582 Author: NIIBE Yutaka Date: Fri Feb 17 20:02:38 2017 +0900 agent: No cards is not an error. * agent/command-ssh.c (card_key_list): Care the case of no cards. Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 2c74618..7298700 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2387,9 +2387,15 @@ card_key_list (ctrl_t ctrl, char **r_serialno, strlist_t *result) { gpg_error_t err; + *r_serialno = NULL; + *result = NULL; + err = agent_card_serialno (ctrl, r_serialno, NULL); if (err) { + if (gpg_err_code (err) == GPG_ERR_ENODEV) + return 0; /* Nothing available. */ + if (opt.verbose) log_info (_("error getting serial number of card: %s\n"), gpg_strerror (err)); ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 12:25:01 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 17 Feb 2017 12:25:01 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-82-gde8494b Message-ID: This is an 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 de8494b16bc50c60a8438f2cae1f8c88e8949f7a (commit) via 9350168a1eed3f055040d7cc8a9bf4cdf745b23a (commit) from 7641b7b5f2c9d5b38c60cd9326bcb4810c37dae5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit de8494b16bc50c60a8438f2cae1f8c88e8949f7a Author: Justus Winter Date: Fri Feb 17 12:18:56 2017 +0100 python: Fix teardown of ephemeral contexts. * lang/python/tests/support.py (EphemeralContext): New function. * lang/python/tests/t-quick-key-creation.py: Use the new function to manage ephemeral contexts. * lang/python/tests/t-quick-key-manipulation.py: Likewise. * lang/python/tests/t-quick-subkey-creation.py: Likewise. -- Previously, there was a problem with cleaning up ephemeral home directories. shutil.rmtree deleted the agents main socket, gpg-agent detected that, and deleted the other sockets as well, racing shutil.rmtree which did not cope will with that. Fix this by asking the agent nicely to shut down. Signed-off-by: Justus Winter diff --git a/lang/python/tests/support.py b/lang/python/tests/support.py index ed5bf61..a381270 100644 --- a/lang/python/tests/support.py +++ b/lang/python/tests/support.py @@ -18,9 +18,12 @@ from __future__ import absolute_import, print_function, unicode_literals del absolute_import, print_function, unicode_literals +import contextlib +import shutil import sys import os import tempfile +import time import gpg # known keys @@ -85,5 +88,24 @@ else: self.path = tempfile.mkdtemp() return self.path def __exit__(self, *args): - import shutil shutil.rmtree(self.path) + + at contextlib.contextmanager +def EphemeralContext(): + with TemporaryDirectory() as tmp: + home = os.environ['GNUPGHOME'] + shutil.copy(os.path.join(home, "gpg.conf"), tmp) + shutil.copy(os.path.join(home, "gpg-agent.conf"), tmp) + + with gpg.Context(home_dir=tmp) as ctx: + yield ctx + + # Ask the agent to quit. + agent_socket = os.path.join(tmp, "S.gpg-agent") + ctx.protocol = gpg.constants.protocol.ASSUAN + ctx.set_engine_info(ctx.protocol, file_name=agent_socket) + ctx.assuan_transact(["KILLAGENT"]) + + # Block until it is really gone. + while os.path.exists(agent_socket): + time.sleep(.01) diff --git a/lang/python/tests/t-quick-key-creation.py b/lang/python/tests/t-quick-key-creation.py index ea63dc3..c642c5b 100755 --- a/lang/python/tests/t-quick-key-creation.py +++ b/lang/python/tests/t-quick-key-creation.py @@ -22,42 +22,33 @@ del absolute_import, print_function, unicode_literals import gpg import itertools -import os -import shutil import time import support alpha = "Alpha " -def copy_configuration(destination): - home = os.environ['GNUPGHOME'] - shutil.copy(os.path.join(home, "gpg.conf"), destination) - shutil.copy(os.path.join(home, "gpg-agent.conf"), destination) +with support.EphemeralContext() as ctx: + res = ctx.create_key(alpha) -with support.TemporaryDirectory() as tmp: - copy_configuration(tmp) - with gpg.Context(home_dir=tmp) as ctx: - res = ctx.create_key(alpha) + keys = list(ctx.keylist()) + assert len(keys) == 1, "Weird number of keys created" - keys = list(ctx.keylist()) - assert len(keys) == 1, "Weird number of keys created" + key = keys[0] + assert key.fpr == res.fpr + assert len(key.subkeys) == 2, "Expected one primary key and one subkey" + assert key.subkeys[0].expires > 0, "Expected primary key to expire" - key = keys[0] - assert key.fpr == res.fpr - assert len(key.subkeys) == 2, "Expected one primary key and one subkey" - assert key.subkeys[0].expires > 0, "Expected primary key to expire" - - # Try to create a key with the same UID - try: - ctx.create_key(alpha) - assert False, "Expected an error but got none" - except gpg.errors.GpgError as e: - pass + # Try to create a key with the same UID + try: + ctx.create_key(alpha) + assert False, "Expected an error but got none" + except gpg.errors.GpgError as e: + pass - # Try to create a key with the same UID, now with force! - res2 = ctx.create_key(alpha, force=True) - assert res.fpr != res2.fpr + # Try to create a key with the same UID, now with force! + res2 = ctx.create_key(alpha, force=True) + assert res.fpr != res2.fpr # From here on, we use one context, and create unique UIDs @@ -67,85 +58,82 @@ def make_uid(): uid_counter += 1 return "user{0}@invalid.example.org".format(uid_counter) -with support.TemporaryDirectory() as tmp: - copy_configuration(tmp) - with gpg.Context(home_dir=tmp) as ctx: - - # Check gpg.constants.create.NOEXPIRE... - res = ctx.create_key(make_uid(), expires=False) - key = ctx.get_key(res.fpr, secret=True) - assert key.fpr == res.fpr - assert len(key.subkeys) == 2, "Expected one primary key and one subkey" - assert key.subkeys[0].expires == 0, "Expected primary key not to expire" - - t = 2 * 24 * 60 * 60 - slack = 5 * 60 - res = ctx.create_key(make_uid(), expires_in=t) - key = ctx.get_key(res.fpr, secret=True) - assert key.fpr == res.fpr - assert len(key.subkeys) == 2, "Expected one primary key and one subkey" - assert abs(time.time() + t - key.subkeys[0].expires) < slack, \ - "Primary keys expiration time is off" - - # Check capabilities - for sign, encrypt, certify, authenticate in itertools.product([False, True], - [False, True], - [False, True], - [False, True]): - # Filter some out - if not (sign or encrypt or certify or authenticate): - # This triggers the default capabilities tested before. - continue - if (sign or encrypt or authenticate) and not certify: - # The primary key always certifies. - continue - - res = ctx.create_key(make_uid(), algorithm="rsa", - sign=sign, encrypt=encrypt, certify=certify, - authenticate=authenticate) - key = ctx.get_key(res.fpr, secret=True) - assert key.fpr == res.fpr - assert len(key.subkeys) == 1, \ - "Expected no subkey for non-default capabilities" - - p = key.subkeys[0] - assert sign == p.can_sign - assert encrypt == p.can_encrypt - assert certify == p.can_certify - assert authenticate == p.can_authenticate - - # Check algorithm - res = ctx.create_key(make_uid(), algorithm="rsa") - key = ctx.get_key(res.fpr, secret=True) - assert key.fpr == res.fpr - for k in key.subkeys: - assert k.pubkey_algo == 1 - - # Check algorithm with size - res = ctx.create_key(make_uid(), algorithm="rsa1024") +with support.EphemeralContext() as ctx: + # Check gpg.constants.create.NOEXPIRE... + res = ctx.create_key(make_uid(), expires=False) + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + assert len(key.subkeys) == 2, "Expected one primary key and one subkey" + assert key.subkeys[0].expires == 0, "Expected primary key not to expire" + + t = 2 * 24 * 60 * 60 + slack = 5 * 60 + res = ctx.create_key(make_uid(), expires_in=t) + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + assert len(key.subkeys) == 2, "Expected one primary key and one subkey" + assert abs(time.time() + t - key.subkeys[0].expires) < slack, \ + "Primary keys expiration time is off" + + # Check capabilities + for sign, encrypt, certify, authenticate in itertools.product([False, True], + [False, True], + [False, True], + [False, True]): + # Filter some out + if not (sign or encrypt or certify or authenticate): + # This triggers the default capabilities tested before. + continue + if (sign or encrypt or authenticate) and not certify: + # The primary key always certifies. + continue + + res = ctx.create_key(make_uid(), algorithm="rsa", + sign=sign, encrypt=encrypt, certify=certify, + authenticate=authenticate) key = ctx.get_key(res.fpr, secret=True) assert key.fpr == res.fpr - for k in key.subkeys: - assert k.pubkey_algo == 1 - assert k.length == 1024 - - # Check algorithm future-default - ctx.create_key(make_uid(), algorithm="future-default") - - # Check passphrase protection - recipient = make_uid() - passphrase = "streng geheim" - res = ctx.create_key(recipient, passphrase=passphrase) - ciphertext, _, _ = ctx.encrypt(b"hello there", recipients=[ctx.get_key(res.fpr)]) - - cb_called = False - def cb(*args): - global cb_called - cb_called = True - return passphrase - ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK - ctx.set_passphrase_cb(cb) - - plaintext, _, _ = ctx.decrypt(ciphertext) - assert plaintext == b"hello there" - assert cb_called + assert len(key.subkeys) == 1, \ + "Expected no subkey for non-default capabilities" + + p = key.subkeys[0] + assert sign == p.can_sign + assert encrypt == p.can_encrypt + assert certify == p.can_certify + assert authenticate == p.can_authenticate + + # Check algorithm + res = ctx.create_key(make_uid(), algorithm="rsa") + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + for k in key.subkeys: + assert k.pubkey_algo == 1 + + # Check algorithm with size + res = ctx.create_key(make_uid(), algorithm="rsa1024") + key = ctx.get_key(res.fpr, secret=True) + assert key.fpr == res.fpr + for k in key.subkeys: + assert k.pubkey_algo == 1 + assert k.length == 1024 + + # Check algorithm future-default + ctx.create_key(make_uid(), algorithm="future-default") + + # Check passphrase protection + recipient = make_uid() + passphrase = "streng geheim" + res = ctx.create_key(recipient, passphrase=passphrase) + ciphertext, _, _ = ctx.encrypt(b"hello there", recipients=[ctx.get_key(res.fpr)]) + + cb_called = False + def cb(*args): + global cb_called + cb_called = True + return passphrase + ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK + ctx.set_passphrase_cb(cb) + + plaintext, _, _ = ctx.decrypt(ciphertext) + assert plaintext == b"hello there" + assert cb_called diff --git a/lang/python/tests/t-quick-key-manipulation.py b/lang/python/tests/t-quick-key-manipulation.py index 62c395a..12c18ce 100755 --- a/lang/python/tests/t-quick-key-manipulation.py +++ b/lang/python/tests/t-quick-key-manipulation.py @@ -21,83 +21,72 @@ from __future__ import absolute_import, print_function, unicode_literals del absolute_import, print_function, unicode_literals import gpg -import itertools -import os -import shutil -import time import support alpha = "Alpha " bravo = "Bravo " -def copy_configuration(destination): - home = os.environ['GNUPGHOME'] - shutil.copy(os.path.join(home, "gpg.conf"), destination) - shutil.copy(os.path.join(home, "gpg-agent.conf"), destination) +with support.EphemeralContext() as ctx: + res = ctx.create_key(alpha, certify=True) + key = ctx.get_key(res.fpr) + assert len(key.subkeys) == 1, "Expected one primary key and no subkeys" + assert len(key.uids) == 1, "Expected exactly one UID" -with support.TemporaryDirectory() as tmp: - copy_configuration(tmp) - with gpg.Context(home_dir=tmp) as ctx: - res = ctx.create_key(alpha, certify=True) + def get_uid(uid): key = ctx.get_key(res.fpr) - assert len(key.subkeys) == 1, "Expected one primary key and no subkeys" - assert len(key.uids) == 1, "Expected exactly one UID" + for u in key.uids: + if u.uid == uid: + return u + return None - def get_uid(uid): - key = ctx.get_key(res.fpr) - for u in key.uids: - if u.uid == uid: - return u - return None + # sanity check + uid = get_uid(alpha) + assert uid, "UID alpha not found" + assert uid.revoked == 0 - # sanity check - uid = get_uid(alpha) - assert uid, "UID alpha not found" - assert uid.revoked == 0 + # add bravo + ctx.key_add_uid(key, bravo) + uid = get_uid(bravo) + assert uid, "UID bravo not found" + assert uid.revoked == 0 - # add bravo - ctx.key_add_uid(key, bravo) - uid = get_uid(bravo) - assert uid, "UID bravo not found" - assert uid.revoked == 0 + # revoke alpha + ctx.key_revoke_uid(key, alpha) + uid = get_uid(alpha) + assert uid, "UID alpha not found" + assert uid.revoked == 1 + uid = get_uid(bravo) + assert uid, "UID bravo not found" + assert uid.revoked == 0 - # revoke alpha + # try to revoke the last UID + try: ctx.key_revoke_uid(key, alpha) - uid = get_uid(alpha) - assert uid, "UID alpha not found" - assert uid.revoked == 1 - uid = get_uid(bravo) - assert uid, "UID bravo not found" - assert uid.revoked == 0 - - # try to revoke the last UID - try: - ctx.key_revoke_uid(key, alpha) - # IMHO this should fail. issue2961. - # assert False, "Expected an error but got none" - except gpg.errors.GpgError: - pass + # IMHO this should fail. issue2961. + # assert False, "Expected an error but got none" + except gpg.errors.GpgError: + pass - # Everything should be the same - uid = get_uid(alpha) - assert uid, "UID alpha not found" - assert uid.revoked == 1 - uid = get_uid(bravo) - assert uid, "UID bravo not found" - assert uid.revoked == 0 + # Everything should be the same + uid = get_uid(alpha) + assert uid, "UID alpha not found" + assert uid.revoked == 1 + uid = get_uid(bravo) + assert uid, "UID bravo not found" + assert uid.revoked == 0 - # try to revoke a non-existent UID - try: - ctx.key_revoke_uid(key, "i dont exist") - # IMHO this should fail. issue2963. - # assert False, "Expected an error but got none" - except gpg.errors.GpgError: - pass + # try to revoke a non-existent UID + try: + ctx.key_revoke_uid(key, "i dont exist") + # IMHO this should fail. issue2963. + # assert False, "Expected an error but got none" + except gpg.errors.GpgError: + pass - # try to add an pre-existent UID - try: - ctx.key_add_uid(key, bravo) - assert False, "Expected an error but got none" - except gpg.errors.GpgError: - pass + # try to add an pre-existent UID + try: + ctx.key_add_uid(key, bravo) + assert False, "Expected an error but got none" + except gpg.errors.GpgError: + pass diff --git a/lang/python/tests/t-quick-subkey-creation.py b/lang/python/tests/t-quick-subkey-creation.py index 0d9f71f..ad4f35c 100755 --- a/lang/python/tests/t-quick-subkey-creation.py +++ b/lang/python/tests/t-quick-subkey-creation.py @@ -22,8 +22,6 @@ del absolute_import, print_function, unicode_literals import gpg import itertools -import os -import shutil import time import support @@ -31,91 +29,84 @@ import support alpha = "Alpha " bravo = "Bravo " -def copy_configuration(destination): - home = os.environ['GNUPGHOME'] - shutil.copy(os.path.join(home, "gpg.conf"), destination) - shutil.copy(os.path.join(home, "gpg-agent.conf"), destination) - -with support.TemporaryDirectory() as tmp: - copy_configuration(tmp) - with gpg.Context(home_dir=tmp) as ctx: - res = ctx.create_key(alpha, certify=True) - keys = list(ctx.keylist()) - assert len(keys) == 1, "Weird number of keys created" - key = keys[0] - assert key.fpr == res.fpr - assert len(key.subkeys) == 1, "Expected one primary key and no subkeys" - - def get_subkey(fpr): - k = ctx.get_key(fpr) - for sk in k.subkeys: - if sk.fpr == fpr: - return sk - return None - - # Check gpg.constants.create.NOEXPIRE... - res = ctx.create_subkey(key, expires=False) +with support.EphemeralContext() as ctx: + res = ctx.create_key(alpha, certify=True) + keys = list(ctx.keylist()) + assert len(keys) == 1, "Weird number of keys created" + key = keys[0] + assert key.fpr == res.fpr + assert len(key.subkeys) == 1, "Expected one primary key and no subkeys" + + def get_subkey(fpr): + k = ctx.get_key(fpr) + for sk in k.subkeys: + if sk.fpr == fpr: + return sk + return None + + # Check gpg.constants.create.NOEXPIRE... + res = ctx.create_subkey(key, expires=False) + subkey = get_subkey(res.fpr) + assert subkey.expires == 0, "Expected subkey not to expire" + assert subkey.can_encrypt, \ + "Default subkey capabilities do not include encryption" + + t = 2 * 24 * 60 * 60 + slack = 5 * 60 + res = ctx.create_subkey(key, expires_in=t) + subkey = get_subkey(res.fpr) + assert abs(time.time() + t - subkey.expires) < slack, \ + "subkeys expiration time is off" + + # Check capabilities + for sign, encrypt, authenticate in itertools.product([False, True], + [False, True], + [False, True]): + # Filter some out + if not (sign or encrypt or authenticate): + # This triggers the default capabilities tested before. + continue + + res = ctx.create_subkey(key, sign=sign, encrypt=encrypt, + authenticate=authenticate) subkey = get_subkey(res.fpr) - assert subkey.expires == 0, "Expected subkey not to expire" - assert subkey.can_encrypt, \ - "Default subkey capabilities do not include encryption" - - t = 2 * 24 * 60 * 60 - slack = 5 * 60 - res = ctx.create_subkey(key, expires_in=t) - subkey = get_subkey(res.fpr) - assert abs(time.time() + t - subkey.expires) < slack, \ - "subkeys expiration time is off" - - # Check capabilities - for sign, encrypt, authenticate in itertools.product([False, True], - [False, True], - [False, True]): - # Filter some out - if not (sign or encrypt or authenticate): - # This triggers the default capabilities tested before. - continue - - res = ctx.create_subkey(key, sign=sign, encrypt=encrypt, - authenticate=authenticate) - subkey = get_subkey(res.fpr) - assert sign == subkey.can_sign - assert encrypt == subkey.can_encrypt - assert authenticate == subkey.can_authenticate - - # Check algorithm - res = ctx.create_subkey(key, algorithm="rsa") - subkey = get_subkey(res.fpr) - assert subkey.pubkey_algo == 1 - - # Check algorithm with size - res = ctx.create_subkey(key, algorithm="rsa1024") - subkey = get_subkey(res.fpr) - assert subkey.pubkey_algo == 1 - assert subkey.length == 1024 - - # Check algorithm future-default - ctx.create_subkey(key, algorithm="future-default") - - # Check passphrase protection. For this we create a new key - # so that we have a key with just one encryption subkey. - bravo_res = ctx.create_key(bravo, certify=True) - bravo_key = ctx.get_key(bravo_res.fpr) - assert len(bravo_key.subkeys) == 1, "Expected one primary key and no subkeys" - - passphrase = "streng geheim" - res = ctx.create_subkey(bravo_key, passphrase=passphrase) - ciphertext, _, _ = ctx.encrypt(b"hello there", - recipients=[ctx.get_key(bravo_res.fpr)]) - - cb_called = False - def cb(*args): - global cb_called - cb_called = True - return passphrase - ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK - ctx.set_passphrase_cb(cb) - - plaintext, _, _ = ctx.decrypt(ciphertext) - assert plaintext == b"hello there" - assert cb_called + assert sign == subkey.can_sign + assert encrypt == subkey.can_encrypt + assert authenticate == subkey.can_authenticate + + # Check algorithm + res = ctx.create_subkey(key, algorithm="rsa") + subkey = get_subkey(res.fpr) + assert subkey.pubkey_algo == 1 + + # Check algorithm with size + res = ctx.create_subkey(key, algorithm="rsa1024") + subkey = get_subkey(res.fpr) + assert subkey.pubkey_algo == 1 + assert subkey.length == 1024 + + # Check algorithm future-default + ctx.create_subkey(key, algorithm="future-default") + + # Check passphrase protection. For this we create a new key + # so that we have a key with just one encryption subkey. + bravo_res = ctx.create_key(bravo, certify=True) + bravo_key = ctx.get_key(bravo_res.fpr) + assert len(bravo_key.subkeys) == 1, "Expected one primary key and no subkeys" + + passphrase = "streng geheim" + res = ctx.create_subkey(bravo_key, passphrase=passphrase) + ciphertext, _, _ = ctx.encrypt(b"hello there", + recipients=[ctx.get_key(bravo_res.fpr)]) + + cb_called = False + def cb(*args): + global cb_called + cb_called = True + return passphrase + ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK + ctx.set_passphrase_cb(cb) + + plaintext, _, _ = ctx.decrypt(ciphertext) + assert plaintext == b"hello there" + assert cb_called commit 9350168a1eed3f055040d7cc8a9bf4cdf745b23a Author: Justus Winter Date: Fri Feb 17 12:10:34 2017 +0100 python: Fix using strings as commands in the assuan protocol. * lang/python/gpg/core.py (Context.assuan_transact): Fix testing whether the command is a string on Python2. * lang/python/tests/t-protocol-assuan.py: Improve the test to detect this problem. Signed-off-by: Justus Winter diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index beaebda..28d4629 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -699,7 +699,7 @@ class Context(GpgmeWrapper): """ - if isinstance(command, (str, bytes)): + if util.is_a_string(command) or isinstance(command, bytes): cmd = command else: cmd = " ".join(util.percent_escape(f) for f in command) diff --git a/lang/python/tests/t-protocol-assuan.py b/lang/python/tests/t-protocol-assuan.py index 0084a6b..27b28c7 100755 --- a/lang/python/tests/t-protocol-assuan.py +++ b/lang/python/tests/t-protocol-assuan.py @@ -24,9 +24,12 @@ import gpg with gpg.Context(protocol=gpg.constants.protocol.ASSUAN) as c: # Do nothing. - c.assuan_transact('nop') - c.assuan_transact('NOP') - c.assuan_transact(['NOP']) + err = c.assuan_transact('nop') + assert err == None + err = c.assuan_transact(b'NOP') + assert err == None + err = c.assuan_transact(['NOP']) + assert err == None err = c.assuan_transact('idontexist') assert err.getsource() == gpg.errors.SOURCE_GPGAGENT ----------------------------------------------------------------------- Summary of changes: lang/python/gpg/core.py | 2 +- lang/python/tests/support.py | 24 +++- lang/python/tests/t-protocol-assuan.py | 9 +- lang/python/tests/t-quick-key-creation.py | 200 ++++++++++++-------------- lang/python/tests/t-quick-key-manipulation.py | 117 +++++++-------- lang/python/tests/t-quick-subkey-creation.py | 169 +++++++++++----------- 6 files changed, 257 insertions(+), 264 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 16:43:51 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 17 Feb 2017 16:43:51 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-98-g070211e Message-ID: This is an 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 070211eb990f5ea41271eba432b6a6b485cef7c7 (commit) via ed99af030d19305dd7cd41c41ac581306cb91fd5 (commit) from dea4b3c742acbd195d6ab12b279b4dda315f2582 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 070211eb990f5ea41271eba432b6a6b485cef7c7 Author: Werner Koch Date: Fri Feb 17 16:39:48 2017 +0100 dirmngr: Add options --tls and --systrust to the VALIDATE cmd. * dirmngr/certcache.h (certlist_s, certlist_t): New. * dirmngr/certcache.c (read_certlist_from_stream): New. (release_certlist): New. * dirmngr/server.c (MAX_CERTLIST_LENGTH): New. (cmd_validate): Add options --tls and --systrust. Implement them using a kludge for now. * dirmngr/validate.c (validate_cert_chain): Support systrust checking. Add kludge to disable the CRL checking for tls mode. -- This can now be used to test a list of certificates as returned by TLS. Put the certs PEM encoded into a a file certlist.pem with the target certificate being the first. Then run gpg-connect-agent --dirmngr \ '/definqfile CERTLIST wiki-gnupg-chain.pem' \ 'validate --systrust --tls' /bye CRLS check has been disabled becuase we can't yet pass the systrust flag to the CRL checking code. Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index cd026c2..ff86f61 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -225,6 +225,7 @@ cert_compute_fpr (ksba_cert_t cert, unsigned char *digest) } + /* Cleanup one slot. This releases all resourses but keeps the actual slot in the cache marked for reuse. */ static void @@ -1669,3 +1670,92 @@ find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert) return err; } + + + +/* Read a list of certificates in PEM format from stream FP and store + * them on success at R_CERTLIST. On error NULL is stored at R_CERT + * list and an error code returned. Note that even on success an + * empty list of certificates can be returned (i.e. NULL stored at + * R_CERTLIST) iff the input stream has no certificates. */ +gpg_error_t +read_certlist_from_stream (certlist_t *r_certlist, estream_t fp) +{ + gpg_error_t err; + gnupg_ksba_io_t ioctx = NULL; + ksba_reader_t reader; + ksba_cert_t cert = NULL; + certlist_t certlist = NULL; + certlist_t cl, *cltail; + + *r_certlist = NULL; + + err = gnupg_ksba_create_reader (&ioctx, + (GNUPG_KSBA_IO_PEM | GNUPG_KSBA_IO_MULTIPEM), + fp, &reader); + if (err) + goto leave; + + /* Loop to read all certificates from the stream. */ + cltail = &certlist; + do + { + ksba_cert_release (cert); + cert = NULL; + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_read_der (cert, reader); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_EOF) + err = 0; + goto leave; + } + + /* Append the certificate to the list. We also store the + * fingerprint and check whether we have a cached certificate; + * in that case the cached certificate is put into the list to + * take advantage of a validation result which might be stored + * in the cached certificate. */ + cl = xtrycalloc (1, sizeof *cl); + if (!cl) + { + err = gpg_error_from_syserror (); + goto leave; + } + cert_compute_fpr (cert, cl->fpr); + cl->cert = get_cert_byfpr (cl->fpr); + if (!cl->cert) + { + cl->cert = cert; + cert = NULL; + } + *cltail = cl; + cltail = &cl->next; + ksba_reader_clear (reader, NULL, NULL); + } + while (!gnupg_ksba_reader_eof_seen (ioctx)); + + leave: + ksba_cert_release (cert); + gnupg_ksba_destroy_reader (ioctx); + if (err) + release_certlist (certlist); + else + *r_certlist = certlist; + + return err; +} + + +/* Release the certificate list CL. */ +void +release_certlist (certlist_t cl) +{ + while (cl) + { + certlist_t next = cl->next; + ksba_cert_release (cl->cert); + cl = next; + } +} diff --git a/dirmngr/certcache.h b/dirmngr/certcache.h index ac93ee6..1f86706 100644 --- a/dirmngr/certcache.h +++ b/dirmngr/certcache.h @@ -46,7 +46,6 @@ gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer); * provided certificates are considered trusted. */ gpg_error_t is_trusted_cert (ksba_cert_t cert, int with_systrust); - /* Return a certificate object for the given fingerprint. FPR is expected to be a 20 byte binary SHA-1 fingerprint. If no matching certificate is available in the cache NULL is returned. The caller @@ -100,5 +99,18 @@ gpg_error_t find_issuing_cert (ctrl_t ctrl, +/* A simple list of certificates. */ +struct certlist_s +{ + struct certlist_s *next; + ksba_cert_t cert; + unsigned char fpr[20]; /* of the certificate. */ +}; +typedef struct certlist_s *certlist_t; + +gpg_error_t read_certlist_from_stream (certlist_t *r_certlist, estream_t fp); +void release_certlist (certlist_t cl); + + #endif /*CERTCACHE_H*/ diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 3724c00..19d2303 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -155,7 +155,8 @@ struct #define DBG_NETWORK (opt.debug & DBG_NETWORK_VALUE) #define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE) -/* A simple list of certificate references. */ +/* A simple list of certificate references. FIXME: Better use + certlist_t also for references (Store NULL at .cert) */ struct cert_ref_s { struct cert_ref_s *next; @@ -163,6 +164,7 @@ struct cert_ref_s }; typedef struct cert_ref_s *cert_ref_t; + /* Forward references; access only through server.c. */ struct server_local_s; diff --git a/dirmngr/server.c b/dirmngr/server.c index bc373f5..05ef439 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -60,6 +60,10 @@ Dirmngr was a system service and not a user service. */ #define MAX_CERT_LENGTH (16*1024) +/* The limit for the CERTLIST inquiry. We allow for up to 20 + * certificates but also take PEM encoding into account. */ +#define MAX_CERTLIST_LENGTH ((MAX_CERT_LENGTH * 20 * 4)/3) + /* The same goes for OpenPGP keyblocks, but here we need to allow for much longer blocks; a 200k keyblock is not too unusual for keys with a lot of signatures (e.g. 0x5b0358a2). 9C31503C6D866396 even @@ -1729,7 +1733,7 @@ cmd_cachecert (assuan_context_t ctx, char *line) static const char hlp_validate[] = - "VALIDATE\n" + "VALIDATE [--systrust] [--tls]\n" "\n" "Validate a certificate using the certificate validation function\n" "used internally by dirmngr. This command is only useful for\n" @@ -1739,20 +1743,38 @@ static const char hlp_validate[] = " INQUIRE TARGETCERT\n" "\n" "and the caller is expected to return the certificate for the\n" - "request as a binary blob."; + "request as a binary blob. The option --tls modifies this by asking\n" + "for list of certificates with\n" + "\n" + " INQUIRE CERTLIST\n" + "\n" + "Here the first certificate is the target certificate, the remaining\n" + "certificates are suggested intermediary certificates. All certifciates\n" + "need to be PEM encoded.\n" + "\n" + "The option --systrust changes the behaviour to include the system\n" + "provided root certificates as trust anchors."; static gpg_error_t cmd_validate (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; ksba_cert_t cert = NULL; + certlist_t certlist = NULL; unsigned char *value = NULL; size_t valuelen; + int systrust_mode, tls_mode; - (void)line; + systrust_mode = has_option (line, "--systrust"); + tls_mode = has_option (line, "--tls"); + line = skip_options (line); - err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT", - &value, &valuelen, MAX_CERT_LENGTH); + if (tls_mode) + err = assuan_inquire (ctrl->server_local->assuan_ctx, "CERTLIST", + &value, &valuelen, MAX_CERTLIST_LENGTH); + else + err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT", + &value, &valuelen, MAX_CERT_LENGTH); if (err) { log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err)); @@ -1761,6 +1783,27 @@ cmd_validate (assuan_context_t ctx, char *line) if (!valuelen) /* No data returned; return a comprehensible error. */ err = gpg_error (GPG_ERR_MISSING_CERT); + else if (tls_mode) + { + estream_t fp; + + fp = es_fopenmem_init (0, "rb", value, valuelen); + if (!fp) + err = gpg_error_from_syserror (); + else + { + err = read_certlist_from_stream (&certlist, fp); + es_fclose (fp); + if (!err && !certlist) + err = gpg_error (GPG_ERR_MISSING_CERT); + if (!err) + { + /* Extraxt the first certificate from the list. */ + cert = certlist->cert; + ksba_cert_ref (cert); + } + } + } else { err = ksba_cert_new (&cert); @@ -1771,26 +1814,47 @@ cmd_validate (assuan_context_t ctx, char *line) if(err) goto leave; - /* If we have this certificate already in our cache, use the cached - * version for validation because this will take care of any cached - * results. */ - { - unsigned char fpr[20]; - ksba_cert_t tmpcert; + if (!tls_mode) + { + /* If we have this certificate already in our cache, use the + * cached version for validation because this will take care of + * any cached results. We don't need to do this in tls mode + * because this has already been done for certificate in a + * certlist_t. */ + unsigned char fpr[20]; + ksba_cert_t tmpcert; + + cert_compute_fpr (cert, fpr); + tmpcert = get_cert_byfpr (fpr); + if (tmpcert) + { + ksba_cert_release (cert); + cert = tmpcert; + } + } + + /* Quick hack to make verification work by inserting the supplied + * certs into the cache. */ + if (tls_mode && certlist) + { + certlist_t cl; + + for (cl = certlist->next; cl; cl = cl->next) + cache_cert (cl->cert); + } - cert_compute_fpr (cert, fpr); - tmpcert = get_cert_byfpr (fpr); - if (tmpcert) - { - ksba_cert_release (cert); - cert = tmpcert; - } - } - err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL); + err = validate_cert_chain + (ctrl, cert, NULL, + tls_mode && systrust_mode ? VALIDATE_MODE_TLS_SYSTRUST : + tls_mode ? VALIDATE_MODE_TLS : + /**/ systrust_mode ? VALIDATE_MODE_CERT_SYSTRUST : + /**/ VALIDATE_MODE_CERT, + NULL); leave: ksba_cert_release (cert); + release_certlist (certlist); return leave_cmd (ctx, err); } diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 5081ae0..8fb2df2 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -233,8 +233,8 @@ check_revocations (ctrl_t ctrl, chain_item_t chain) int any_crl_too_old = 0; chain_item_t ci; - assert (ctrl->check_revocations_nest_level >= 0); - assert (chain); + log_assert (ctrl->check_revocations_nest_level >= 0); + log_assert (chain); if (ctrl->check_revocations_nest_level > 10) { @@ -551,7 +551,9 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (err) goto leave; /* No. */ - err = is_trusted_cert (subject_cert, 0); + err = is_trusted_cert (subject_cert, + (mode == VALIDATE_MODE_CERT_SYSTRUST + || mode == VALIDATE_MODE_TLS_SYSTRUST)); if (!err) ; /* Yes we trust this cert. */ else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) @@ -772,7 +774,9 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, * our validity results to avoid double work. Far worse a * catch-22 may happen for an improper setup hierarchy and we * need a way to break up such a deadlock. */ - err = check_revocations (ctrl, chain); + if (mode != VALIDATE_MODE_TLS_SYSTRUST) + err = check_revocations (ctrl, chain); +#warning fix the above } if (!err && opt.verbose) commit ed99af030d19305dd7cd41c41ac581306cb91fd5 Author: Werner Koch Date: Fri Feb 17 14:19:15 2017 +0100 dirmngr: Remove use of hardcoded numbers in validate. * dirmngr/validate.c (enum cert_usage_modes): New. (cert_usage_p): Change type of arg MODE. Use enums instead of hardwired values. Use a switch instead of tricky bit tests. (cert_use_cert_p, cert_use_ocsp_p, cert_use_crl_p): Adjust. * dirmngr/validate.c (cert_usage_p): Rename to check_cert_usage. (cert_use_cert_p): Rename to check_cert_use_cert. (cert_use_ocsp_p): Rename to check_cert_use_ocsp. (cert_use_crl_p): Rename to check_cert_use_crl. * dirmngr/validate.h (VALIDATE_MODE_CERT_SYSTRUST): New. (VALIDATE_MODE_TLS, VALIDATE_MODE_TLS_SYSTRUST): New. -- A function with a "_p" suffix return 0 for a True just looks weird. We now use names which better indicate that an error code is returned. Signed-off-by: Werner Koch diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 4139c22..5081ae0 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -1,6 +1,6 @@ /* validate.c - Validate a certificate chain. * Copyright (C) 2001, 2003, 2004, 2008 Free Software Foundation, Inc. - * Copyright (C) 2004, 2006, 2008 g10 Code GmbH + * Copyright (C) 2004, 2006, 2008, 2017 g10 Code GmbH * * This file is part of DirMngr. * @@ -33,6 +33,20 @@ #include "validate.h" #include "misc.h" + +/* Mode parameters for cert_check_usage(). */ +enum cert_usage_modes + { + CERT_USAGE_MODE_SIGN, /* Usable for encryption. */ + CERT_USAGE_MODE_ENCR, /* Usable for signing. */ + CERT_USAGE_MODE_VRFY, /* Usable for verification. */ + CERT_USAGE_MODE_DECR, /* Usable for decryption. */ + CERT_USAGE_MODE_CERT, /* Usable for cert signing. */ + CERT_USAGE_MODE_OCSP, /* Usable for OCSP respone signing. */ + CERT_USAGE_MODE_CRL /* Usable for CRL signing. */ + }; + + /* While running the validation function we need to keep track of the certificates and the validation outcome of each. We use this type for it. */ @@ -394,11 +408,11 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, switch (mode) { case VALIDATE_MODE_OCSP: - err = cert_use_ocsp_p (cert); + err = check_cert_use_ocsp (cert); break; case VALIDATE_MODE_CRL: case VALIDATE_MODE_CRL_RECURSIVE: - err = cert_use_crl_p (cert); + err = check_cert_use_crl (cert); break; default: err = 0; @@ -694,7 +708,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, } /* May that certificate be used for certification? */ - err = cert_use_cert_p (issuer_cert); + err = check_cert_use_cert (issuer_cert); if (err) goto leave; /* No. */ @@ -1001,13 +1015,9 @@ check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) -/* Return 0 if the cert is usable for encryption. A MODE of 0 checks - for signing, a MODE of 1 checks for encryption, a MODE of 2 checks - for verification and a MODE of 3 for decryption (just for - debugging). MODE 4 is for certificate signing, MODE 5 for OCSP - response signing, MODE 6 is for CRL signing. */ -static int -cert_usage_p (ksba_cert_t cert, int mode) +/* Return 0 if CERT is usable for MODE. */ +static gpg_error_t +check_cert_usage (ksba_cert_t cert, enum cert_usage_modes mode) { gpg_error_t err; unsigned int use; @@ -1077,7 +1087,8 @@ cert_usage_p (ksba_cert_t cert, int mode) if (gpg_err_code (err) == GPG_ERR_NO_DATA) { err = 0; - if (opt.verbose && mode < 2) + if (opt.verbose && (mode == CERT_USAGE_MODE_SIGN + || mode == CERT_USAGE_MODE_ENCR)) log_info (_("no key usage specified - assuming all usages\n")); use = ~0; } @@ -1094,17 +1105,36 @@ cert_usage_p (ksba_cert_t cert, int mode) return err; } - if (mode == 4) + switch (mode) { + case CERT_USAGE_MODE_SIGN: + case CERT_USAGE_MODE_VRFY: + if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE + | KSBA_KEYUSAGE_NON_REPUDIATION))) + return 0; + log_info (mode == CERT_USAGE_MODE_VRFY + ? _("certificate should not have been used for signing\n") + : _("certificate is not usable for signing\n")); + break; + + case CERT_USAGE_MODE_ENCR: + case CERT_USAGE_MODE_DECR: + if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT + | KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) + return 0; + log_info (mode == CERT_USAGE_MODE_DECR + ? _("certificate should not have been used for encryption\n") + : _("certificate is not usable for encryption\n")); + break; + + case CERT_USAGE_MODE_CERT: if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN))) return 0; log_info (_("certificate should not have " "been used for certification\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); - } + break; - if (mode == 5) - { + case CERT_USAGE_MODE_OCSP: if (use != ~0 && (have_ocsp_signing || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN @@ -1112,50 +1142,38 @@ cert_usage_p (ksba_cert_t cert, int mode) return 0; log_info (_("certificate should not have " "been used for OCSP response signing\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); - } + break; - if (mode == 6) - { + case CERT_USAGE_MODE_CRL: if ((use & (KSBA_KEYUSAGE_CRL_SIGN))) return 0; log_info (_("certificate should not have " "been used for CRL signing\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); + break; } - if ((use & ((mode&1)? - (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT): - (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - ) - return 0; - - log_info (mode==3? _("certificate should not have been used " - "for encryption\n"): - mode==2? _("certificate should not have been used for signing\n"): - mode==1? _("certificate is not usable for encryption\n"): - _("certificate is not usable for signing\n")); return gpg_error (GPG_ERR_WRONG_KEY_USAGE); } + /* Return 0 if the certificate CERT is usable for certification. */ gpg_error_t -cert_use_cert_p (ksba_cert_t cert) +check_cert_use_cert (ksba_cert_t cert) { - return cert_usage_p (cert, 4); + return check_cert_usage (cert, CERT_USAGE_MODE_CERT); } /* Return 0 if the certificate CERT is usable for signing OCSP responses. */ gpg_error_t -cert_use_ocsp_p (ksba_cert_t cert) +check_cert_use_ocsp (ksba_cert_t cert) { - return cert_usage_p (cert, 5); + return check_cert_usage (cert, CERT_USAGE_MODE_OCSP); } /* Return 0 if the certificate CERT is usable for signing CRLs. */ gpg_error_t -cert_use_crl_p (ksba_cert_t cert) +check_cert_use_crl (ksba_cert_t cert) { - return cert_usage_p (cert, 6); + return check_cert_usage (cert, CERT_USAGE_MODE_CRL); } diff --git a/dirmngr/validate.h b/dirmngr/validate.h index 0d9283c..376d99d 100644 --- a/dirmngr/validate.h +++ b/dirmngr/validate.h @@ -25,13 +25,27 @@ enum { /* Simple certificate validation mode. */ VALIDATE_MODE_CERT = 0, + + /* Same as MODE_CERT but using the system provided root + * certificates. */ + VALIDATE_MODE_CERT_SYSTRUST, + + /* Same as MODE_CERT but uses a provided list of certificates. */ + VALIDATE_MODE_TLS, + + /* Same as MODE_TLS but using the system provided root + * certificates. */ + VALIDATE_MODE_TLS_SYSTRUST, + /* Standard CRL issuer certificate validation; i.e. CRLs are not considered for CRL issuer certificates. */ - VALIDATE_MODE_CRL = 1, + VALIDATE_MODE_CRL, + /* Full CRL validation. */ - VALIDATE_MODE_CRL_RECURSIVE = 2, + VALIDATE_MODE_CRL_RECURSIVE, + /* Validation as used for OCSP. */ - VALIDATE_MODE_OCSP = 3 + VALIDATE_MODE_OCSP }; @@ -42,14 +56,14 @@ gpg_error_t validate_cert_chain (ctrl_t ctrl, int mode, char **r_trust_anchor); /* Return 0 if the certificate CERT is usable for certification. */ -gpg_error_t cert_use_cert_p (ksba_cert_t cert); +gpg_error_t check_cert_use_cert (ksba_cert_t cert); /* Return 0 if the certificate CERT is usable for signing OCSP responses. */ -gpg_error_t cert_use_ocsp_p (ksba_cert_t cert); +gpg_error_t check_cert_use_ocsp (ksba_cert_t cert); /* Return 0 if the certificate CERT is usable for signing CRLs. */ -gpg_error_t cert_use_crl_p (ksba_cert_t cert); +gpg_error_t check_cert_use_crl (ksba_cert_t cert); #endif /*VALIDATE_H*/ ----------------------------------------------------------------------- Summary of changes: dirmngr/certcache.c | 90 +++++++++++++++++++++++++++++++++++++++++++ dirmngr/certcache.h | 14 ++++++- dirmngr/dirmngr.h | 4 +- dirmngr/server.c | 104 ++++++++++++++++++++++++++++++++++++++++---------- dirmngr/validate.c | 108 +++++++++++++++++++++++++++++++--------------------- dirmngr/validate.h | 26 ++++++++++--- 6 files changed, 275 insertions(+), 71 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 17:09:57 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 17 Feb 2017 17:09:57 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-84-g15fbac9 Message-ID: This is an 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 15fbac9e72a4d1bff9a3b9e9822f9175b09fbcd5 (commit) via 48634e651fcd02431c0518d42ada1f3b402feb2c (commit) from de8494b16bc50c60a8438f2cae1f8c88e8949f7a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 15fbac9e72a4d1bff9a3b9e9822f9175b09fbcd5 Author: Justus Winter Date: Fri Feb 17 17:07:05 2017 +0100 python: Support manipulating the TOFU policy. * NEWS: Update. * doc/gpgme.texi: Fix typos. * lang/python/gpg/constants/__init__.py: Import new files. * lang/python/gpg/constants/tofu/__init__.py: New file. * lang/python/gpg/constants/tofu/policy.py: New file. * lang/python/gpg/core.py (Context.key_tofu_policy): New function. * lang/python/gpgme.i: Nice reprs for gpgme_tofu_info_t. * lang/python/setup.py.in: Install new package. * lang/python/tests/t-quick-key-manipulation.py: Extend test. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 617d1d3..d1042c6 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,7 @@ Noteworthy changes in version 1.8.1 (unreleased) py: Context.key_add_uid NEW. py: Context.key_revoke_uid NEW. py: Context.key_sign NEW. + py: Context.key_tofu_policy NEW. py: core.pubkey_algo_string NEW. py: core.addrspec_from_uid NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 78225d5..1e2cde7 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -4489,7 +4489,7 @@ could not be started. @cindex validity, TOFU The OpenPGP engine features a Trust-On-First-Use (TOFU) key validation -model. For resolving clonflics it is necessary to declare the policy +model. For resolving conflicts it is necessary to declare the policy for a key. See the GnuPG manual for details on the TOFU implementation. @@ -4502,7 +4502,7 @@ policy values that are supported by @acronym{GPGME}: @item GPGME_TOFU_POLICY_AUTO Set the policy to ``auto''. @item GPGME_TOFU_POLICY_GOOD -Set the policy to ``goog''. +Set the policy to ``good''. @item GPGME_TOFU_POLICY_BAD Set the policy to ``bad''. @item GPGME_TOFU_POLICY_ASK diff --git a/lang/python/gpg/constants/__init__.py b/lang/python/gpg/constants/__init__.py index 79d1fbc..484ffd2 100644 --- a/lang/python/gpg/constants/__init__.py +++ b/lang/python/gpg/constants/__init__.py @@ -25,7 +25,7 @@ util.process_constants('GPGME_', globals()) del util # For convenience, we import the modules here. -from . import data, keylist, sig # The subdirs. +from . import data, keylist, sig, tofu # The subdirs. from . import create, event, keysign, md, pk, protocol, sigsum, status, validity # A complication arises because 'import' is a reserved keyword. @@ -34,7 +34,7 @@ globals()['Import'] = getattr(__import__('', globals(), locals(), [str('import')], 1), "import") __all__ = ['data', 'event', 'import', 'keysign', 'keylist', 'md', 'pk', - 'protocol', 'sig', 'sigsum', 'status', 'validity', 'create'] + 'protocol', 'sig', 'sigsum', 'status', 'tofu', 'validity', 'create'] # GPGME 1.7 replaced gpgme_op_edit with gpgme_op_interact. We # implement gpg.Context.op_edit using gpgme_op_interact, so the diff --git a/lang/python/gpg/constants/tofu/__init__.py b/lang/python/gpg/constants/tofu/__init__.py new file mode 100644 index 0000000..819a58b --- /dev/null +++ b/lang/python/gpg/constants/tofu/__init__.py @@ -0,0 +1,24 @@ +# TOFU +# +# Copyright (C) 2017 g10 Code 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, see . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +from . import policy +__all__ = ['policy'] diff --git a/lang/python/gpg/constants/tofu/policy.py b/lang/python/gpg/constants/tofu/policy.py new file mode 100644 index 0000000..5a61f06 --- /dev/null +++ b/lang/python/gpg/constants/tofu/policy.py @@ -0,0 +1,25 @@ +# TOFU policies +# +# Copyright (C) 2017 g10 Code 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, see . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +from gpg import util +util.process_constants('GPGME_TOFU_POLICY_', globals()) +del util diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index cb4ccf7..fe0ba81 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -716,6 +716,18 @@ class Context(GpgmeWrapper): self.op_keysign(key, uids, expires_in, flags) + def key_tofu_policy(self, key, policy): + """Set a keys' TOFU policy + + Set the TOFU policy associated with KEY to POLICY. Calling + this function is only valid for the OpenPGP protocol. + + Raises: + GPGMEError -- as signaled by the underlying library + + """ + self.op_tofu_policy(key, policy) + def assuan_transact(self, command, data_cb=None, inquire_cb=None, status_cb=None): """Issue a raw assuan command diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index 3e89bb1..fa9caf6 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -687,3 +687,7 @@ _gpg_unwrap_gpgme_ctx_t(PyObject *wrapped) %extend _gpgme_user_id { genericrepr(UID) }; + +%extend _gpgme_tofu_info { + genericrepr(TofuInfo) +}; diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index e32237d..bf4efa3 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -172,7 +172,8 @@ setup(name="gpg", url='https://www.gnupg.org', ext_modules=[swige], packages = ['gpg', 'gpg.constants', 'gpg.constants.data', - 'gpg.constants.keylist', 'gpg.constants.sig'], + 'gpg.constants.keylist', 'gpg.constants.sig', + 'gpg.constants.tofu'], license="LGPL2.1+ (the library), GPL2+ (tests and examples)", classifiers=[ 'Development Status :: 4 - Beta', diff --git a/lang/python/tests/t-quick-key-manipulation.py b/lang/python/tests/t-quick-key-manipulation.py index 12c18ce..d7d2bd4 100755 --- a/lang/python/tests/t-quick-key-manipulation.py +++ b/lang/python/tests/t-quick-key-manipulation.py @@ -90,3 +90,34 @@ with support.EphemeralContext() as ctx: assert False, "Expected an error but got none" except gpg.errors.GpgError: pass + + # Check setting the TOFU policy. + with open("gpg.conf", "a") as handle: + handle.write("trust-model tofu+pgp\n") + + for name, policy in [(name, getattr(gpg.constants.tofu.policy, name)) + for name in filter(lambda x: not x.startswith('__'), + dir(gpg.constants.tofu.policy))]: + if policy == gpg.constants.tofu.policy.NONE: + # We must not set the policy to NONE. + continue + + ctx.key_tofu_policy(key, policy) + + keys = list(ctx.keylist(key.uids[0].uid, + mode=(gpg.constants.keylist.mode.LOCAL + |gpg.constants.keylist.mode.WITH_TOFU))) + assert len(keys) == 1 + + if policy == gpg.constants.tofu.policy.AUTO: + # We cannot check that it is set to AUTO. + continue + + for uid in keys[0].uids: + if uid.uid == alpha: + # TOFU information of revoked UIDs is not updated. + # XXX: Is that expected? + continue + assert uid.tofu[0].policy == policy, \ + "Expected policy {0} ({1}), got {2}".format(policy, name, + uid.tofu[0].policy) commit 48634e651fcd02431c0518d42ada1f3b402feb2c Author: Justus Winter Date: Fri Feb 17 15:44:35 2017 +0100 python: Support quick key signing. * NEWS: Update. * doc/gpgme.texi (gpgme_op_keysign): Fix the description of the 'expire' argument. * lang/python/gpg/constants/__init__.py: Import new file. * lang/python/gpg/constants/keysign.py: New file. * lang/python/gpg/core.py (Context.key_sign): New function. * lang/python/tests/Makefile.am (py_tests): Add new test. * lang/python/tests/t-quick-key-signing.py: New test. Signed-off-by: Justus Winter diff --git a/NEWS b/NEWS index 889a526..617d1d3 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ Noteworthy changes in version 1.8.1 (unreleased) py: Context.create_subkey NEW. py: Context.key_add_uid NEW. py: Context.key_revoke_uid NEW. + py: Context.key_sign NEW. py: core.pubkey_algo_string NEW. py: core.addrspec_from_uid NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index c088cfe..78225d5 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -4044,11 +4044,10 @@ object (@code{gpgme_user_id_t}) is to be used. To select more than one user ID put them all into one string separated by linefeeds characters (@code{\n}) and set the flag @code{GPGME_KEYSIGN_LFSEP}. - at var{expires} can be set to the number of seconds since Epoch of the -desired expiration date in UTC for the new signature. The common case -is to use 0 to not set an expiration date. However, if the -configuration of the engine defines a default expiration for key -signatures, that is still used unless the flag + at var{expires} specifies the expiration time of the new signature in +seconds. The common case is to use 0 to not set an expiration date. +However, if the configuration of the engine defines a default +expiration for key signatures, that is still used unless the flag @code{GPGME_KEYSIGN_NOEXPIRE} is used. Note that this parameter takes an unsigned long value and not a @code{time_t} to avoid problems on systems which use a signed 32 bit @code{time_t}. Note further that diff --git a/lang/python/gpg/constants/__init__.py b/lang/python/gpg/constants/__init__.py index 2bf180e..79d1fbc 100644 --- a/lang/python/gpg/constants/__init__.py +++ b/lang/python/gpg/constants/__init__.py @@ -26,14 +26,14 @@ del util # For convenience, we import the modules here. from . import data, keylist, sig # The subdirs. -from . import create, event, md, pk, protocol, sigsum, status, validity +from . import create, event, keysign, md, pk, protocol, sigsum, status, validity # A complication arises because 'import' is a reserved keyword. # Import it as 'Import' instead. globals()['Import'] = getattr(__import__('', globals(), locals(), [str('import')], 1), "import") -__all__ = ['data', 'event', 'import', 'keylist', 'md', 'pk', +__all__ = ['data', 'event', 'import', 'keysign', 'keylist', 'md', 'pk', 'protocol', 'sig', 'sigsum', 'status', 'validity', 'create'] # GPGME 1.7 replaced gpgme_op_edit with gpgme_op_interact. We diff --git a/lang/python/gpg/constants/keysign.py b/lang/python/gpg/constants/keysign.py new file mode 100644 index 0000000..fccdbc4 --- /dev/null +++ b/lang/python/gpg/constants/keysign.py @@ -0,0 +1,25 @@ +# Flags for key signing +# +# Copyright (C) 2017 g10 Code 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, see . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +from gpg import util +util.process_constants('GPGME_KEYSIGN_', globals()) +del util diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py index 28d4629..cb4ccf7 100644 --- a/lang/python/gpg/core.py +++ b/lang/python/gpg/core.py @@ -675,6 +675,47 @@ class Context(GpgmeWrapper): """ self.op_revuid(key, uid, 0) + def key_sign(self, key, uids=None, expires_in=False, local=False): + """Sign a key + + Sign a key with the current set of signing keys. Calling this + function is only valid for the OpenPGP protocol. + + If UIDS is None (the default), then all UIDs are signed. If + it is a string, then only the matching UID is signed. If it + is a list of strings, then all matching UIDs are signed. Note + that a case-sensitive exact string comparison is done. + + EXPIRES_IN specifies the expiration time of the signature in + seconds. If EXPIRES_IN is False, the signature does not + expire. + + Keyword arguments: + uids -- user ids to sign, see above (default: sign all) + expires_in -- validity period of the signature in seconds + (default: do not expire) + local -- create a local, non-exportable signature + (default: False) + + Raises: + GPGMEError -- as signaled by the underlying library + + """ + flags = 0 + if uids == None or util.is_a_string(uids): + pass#through unchanged + else: + flags |= constants.keysign.LFSEP + uids = "\n".join(uids) + + if not expires_in: + flags |= constants.keysign.NOEXPIRE + + if local: + flags |= constants.keysign.LOCAL + + self.op_keysign(key, uids, expires_in, flags) + 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/Makefile.am b/lang/python/tests/Makefile.am index 1d5e1db..7251cd3 100644 --- a/lang/python/tests/Makefile.am +++ b/lang/python/tests/Makefile.am @@ -53,7 +53,8 @@ py_tests = t-wrapper.py \ t-protocol-assuan.py \ t-quick-key-creation.py \ t-quick-subkey-creation.py \ - t-quick-key-manipulation.py + t-quick-key-manipulation.py \ + t-quick-key-signing.py XTESTS = initial.py $(py_tests) final.py EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \ diff --git a/lang/python/tests/t-quick-key-signing.py b/lang/python/tests/t-quick-key-signing.py new file mode 100755 index 0000000..f9778a3 --- /dev/null +++ b/lang/python/tests/t-quick-key-signing.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +# Copyright (C) 2017 g10 Code 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 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 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 . + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + +import gpg +import itertools +import time + +import support + +with support.EphemeralContext() as ctx: + uid_counter = 0 + def make_uid(): + global uid_counter + uid_counter += 1 + return "user{0}@invalid.example.org".format(uid_counter) + + def make_key(): + uids = [make_uid() for i in range(3)] + res = ctx.create_key(uids[0], certify=True) + key = ctx.get_key(res.fpr) + for u in uids[1:]: + ctx.key_add_uid(key, u) + return key, uids + + def check_sigs(key, expected_sigs): + keys = list(ctx.keylist(key.fpr, mode=(gpg.constants.keylist.mode.LOCAL + |gpg.constants.keylist.mode.SIGS))) + assert len(keys) == 1 + key_uids = {uid.uid: [s for s in uid.signatures] for uid in keys[0].uids} + expected = list(expected_sigs) + + while key_uids and expected: + uid, signing_key, func = expected[0] + match = False + for i, s in enumerate(key_uids[uid]): + if signing_key.fpr.endswith(s.keyid): + if func: + func(s) + match = True + break + if match: + expected.pop(0) + key_uids[uid].pop(i) + if not key_uids[uid]: + del key_uids[uid] + + assert not key_uids, "Superfluous signatures: {0}".format(key_uids) + assert not expected, "Missing signatures: {0}".format(expected) + + # Simplest case. Sign without any options. + key_a, uids_a = make_key() + key_b, uids_b = make_key() + ctx.signers = [key_a] + + def exportable_non_expiring(s): + assert s.exportable + assert s.expires == 0 + + check_sigs(key_b, itertools.product(uids_b, [key_b], [exportable_non_expiring])) + ctx.key_sign(key_b) + check_sigs(key_b, itertools.product(uids_b, [key_b, key_a], [exportable_non_expiring])) + + # Create a non-exportable signature, and explicitly name all uids. + key_c, uids_c = make_key() + ctx.signers = [key_a, key_b] + + def non_exportable_non_expiring(s): + assert s.exportable == 0 + assert s.expires == 0 + + ctx.key_sign(key_c, local=True, uids=uids_c) + check_sigs(key_c, + list(itertools.product(uids_c, [key_c], + [exportable_non_expiring])) + + list(itertools.product(uids_c, [key_b, key_a], + [non_exportable_non_expiring]))) + + # Create a non-exportable, expiring signature for a single uid. + key_d, uids_d = make_key() + ctx.signers = [key_c] + expires_in = 600 + slack = 10 + + def non_exportable_expiring(s): + assert s.exportable == 0 + assert abs(time.time() + expires_in - s.expires) < slack + + ctx.key_sign(key_d, local=True, expires_in=expires_in, uids=uids_d[0]) + check_sigs(key_d, + list(itertools.product(uids_d, [key_d], + [exportable_non_expiring])) + + list(itertools.product(uids_d[:1], [key_c], + [non_exportable_expiring]))) + + # Now sign the second in the same fashion, but use a singleton list. + ctx.key_sign(key_d, local=True, expires_in=expires_in, uids=uids_d[1:2]) + check_sigs(key_d, + list(itertools.product(uids_d, [key_d], + [exportable_non_expiring])) + + list(itertools.product(uids_d[:2], [key_c], + [non_exportable_expiring]))) ----------------------------------------------------------------------- Summary of changes: NEWS | 2 + doc/gpgme.texi | 13 ++- lang/python/gpg/constants/__init__.py | 8 +- .../python/gpg/constants/{create.py => keysign.py} | 4 +- .../gpg/constants/{create.py => tofu/__init__.py} | 7 +- .../gpg/constants/{create.py => tofu/policy.py} | 4 +- lang/python/gpg/core.py | 53 +++++++++ lang/python/gpgme.i | 4 + lang/python/setup.py.in | 3 +- lang/python/tests/Makefile.am | 3 +- lang/python/tests/t-quick-key-manipulation.py | 31 ++++++ lang/python/tests/t-quick-key-signing.py | 120 +++++++++++++++++++++ 12 files changed, 231 insertions(+), 21 deletions(-) copy lang/python/gpg/constants/{create.py => keysign.py} (91%) copy lang/python/gpg/constants/{create.py => tofu/__init__.py} (88%) copy lang/python/gpg/constants/{create.py => tofu/policy.py} (91%) create mode 100755 lang/python/tests/t-quick-key-signing.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 21:34:29 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 17 Feb 2017 21:34:29 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-99-gf07811e Message-ID: This is an 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 f07811ee2c0a8044551e2ec063eda61cff7f6e39 (commit) from 070211eb990f5ea41271eba432b6a6b485cef7c7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f07811ee2c0a8044551e2ec063eda61cff7f6e39 Author: Werner Koch Date: Fri Feb 17 21:31:33 2017 +0100 dirmngr: Add option --no-crl to the VALIDATE cmd. * dirmngr/validate.h: Remove enums VALIDATE_MODE_*. (VALIDATE_FLAG_SYSTRUST, VALIDATE_FLAG_EXTRATRUST) (VALIDATE_FLAG_CRL, VALIDATE_FLAG_RECURSIVE) (VALIDATE_FLAG_OCSP, VALIDATE_FLAG_TLS) (VALIDATE_FLAG_NOCRLCHECK): New constants. * dirmngr/validate.c (validate_cert_chain): Change arg 'mode' to 'flags'. Change code accordingly. Remove NO-CRL in TLS mode kludge. * dirmngr/crlcache.c (crl_parse_insert): Change to use flag values for the validate_cert_chain call. * dirmngr/server.c (cmd_validate): Ditto. Add new option --no-crl. Signed-off-by: Werner Koch diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 2e471cb..3cd8cf4 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -1851,7 +1851,8 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl, md = NULL; err = validate_cert_chain (ctrl, crlissuer_cert, NULL, - VALIDATE_MODE_CRL_RECURSIVE, + (VALIDATE_FLAG_CRL + | VALIDATE_FLAG_RECURSIVE), r_trust_anchor); if (err) { diff --git a/dirmngr/server.c b/dirmngr/server.c index 05ef439..1134ac0 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1733,7 +1733,7 @@ cmd_cachecert (assuan_context_t ctx, char *line) static const char hlp_validate[] = - "VALIDATE [--systrust] [--tls]\n" + "VALIDATE [--systrust] [--tls] [--no-crl]\n" "\n" "Validate a certificate using the certificate validation function\n" "used internally by dirmngr. This command is only useful for\n" @@ -1753,7 +1753,8 @@ static const char hlp_validate[] = "need to be PEM encoded.\n" "\n" "The option --systrust changes the behaviour to include the system\n" - "provided root certificates as trust anchors."; + "provided root certificates as trust anchors. The option --no-crl\n" + "skips CRL checks"; static gpg_error_t cmd_validate (assuan_context_t ctx, char *line) { @@ -1763,10 +1764,11 @@ cmd_validate (assuan_context_t ctx, char *line) certlist_t certlist = NULL; unsigned char *value = NULL; size_t valuelen; - int systrust_mode, tls_mode; + int systrust_mode, tls_mode, no_crl; systrust_mode = has_option (line, "--systrust"); tls_mode = has_option (line, "--tls"); + no_crl = has_option (line, "--no-crl"); line = skip_options (line); if (tls_mode) @@ -1843,14 +1845,11 @@ cmd_validate (assuan_context_t ctx, char *line) cache_cert (cl->cert); } - - err = validate_cert_chain - (ctrl, cert, NULL, - tls_mode && systrust_mode ? VALIDATE_MODE_TLS_SYSTRUST : - tls_mode ? VALIDATE_MODE_TLS : - /**/ systrust_mode ? VALIDATE_MODE_CERT_SYSTRUST : - /**/ VALIDATE_MODE_CERT, - NULL); + err = validate_cert_chain (ctrl, cert, NULL, + ((tls_mode ? VALIDATE_FLAG_TLS : 0) + | (systrust_mode ? VALIDATE_FLAG_SYSTRUST : 0) + | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)), + NULL); leave: ksba_cert_release (cert); diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 8fb2df2..1599a8d 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -379,7 +379,7 @@ is_root_cert (ksba_cert_t cert, const char *issuerdn, const char *subjectdn) R_TRUST_ANCHOR; in all other cases NULL is stored there. */ gpg_error_t validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, - int mode, char **r_trust_anchor) + unsigned int flags, char **r_trust_anchor) { gpg_error_t err = 0; int depth, maxdepth; @@ -405,20 +405,9 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, dump_cert ("subject", cert); /* May the target certificate be used for this purpose? */ - switch (mode) - { - case VALIDATE_MODE_OCSP: - err = check_cert_use_ocsp (cert); - break; - case VALIDATE_MODE_CRL: - case VALIDATE_MODE_CRL_RECURSIVE: - err = check_cert_use_crl (cert); - break; - default: - err = 0; - break; - } - if (err) + if ((flags & VALIDATE_FLAG_OCSP) && (err = check_cert_use_ocsp (cert))) + return err; + if ((flags & VALIDATE_FLAG_CRL) && (err = check_cert_use_crl (cert))) return err; /* If we already validated the certificate not too long ago, we can @@ -552,8 +541,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, goto leave; /* No. */ err = is_trusted_cert (subject_cert, - (mode == VALIDATE_MODE_CERT_SYSTRUST - || mode == VALIDATE_MODE_TLS_SYSTRUST)); + !!(flags & VALIDATE_FLAG_SYSTRUST)); if (!err) ; /* Yes we trust this cert. */ else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) @@ -759,7 +747,12 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, cert_log_name (" certificate", citem->cert); } - if (!err && mode != VALIDATE_MODE_CRL) + /* Now check for revocations unless CRL checks are disabled or we + * are non-recursive CRL mode. */ + if (!err + && !(flags & VALIDATE_FLAG_NOCRLCHECK) + && !((flags & VALIDATE_FLAG_CRL) + && !(flags & VALIDATE_FLAG_RECURSIVE))) { /* Now that everything is fine, walk the chain and check each * certificate for revocations. * @@ -774,9 +767,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, * our validity results to avoid double work. Far worse a * catch-22 may happen for an improper setup hierarchy and we * need a way to break up such a deadlock. */ - if (mode != VALIDATE_MODE_TLS_SYSTRUST) - err = check_revocations (ctrl, chain); -#warning fix the above + err = check_revocations (ctrl, chain); } if (!err && opt.verbose) diff --git a/dirmngr/validate.h b/dirmngr/validate.h index 376d99d..b6222b5 100644 --- a/dirmngr/validate.h +++ b/dirmngr/validate.h @@ -22,38 +22,35 @@ #define VALIDATE_H -enum { - /* Simple certificate validation mode. */ - VALIDATE_MODE_CERT = 0, +/* Make use of the system provided root certificates. */ +#define VALIDATE_FLAG_SYSTRUST 1 - /* Same as MODE_CERT but using the system provided root - * certificates. */ - VALIDATE_MODE_CERT_SYSTRUST, +/* Make use of extra provided root certificates. */ +#define VALIDATE_FLAG_EXTRATRUST 2 - /* Same as MODE_CERT but uses a provided list of certificates. */ - VALIDATE_MODE_TLS, +/* Standard CRL issuer certificate validation; i.e. CRLs are not + * considered for CRL issuer certificates. */ +#define VALIDATE_FLAG_CRL 4 - /* Same as MODE_TLS but using the system provided root - * certificates. */ - VALIDATE_MODE_TLS_SYSTRUST, +/* If this flag is set along with VALIDATE_FLAG_CRL a full CRL + * verification is done. */ +#define VALIDATE_FLAG_RECURSIVE 8 - /* Standard CRL issuer certificate validation; i.e. CRLs are not - considered for CRL issuer certificates. */ - VALIDATE_MODE_CRL, +/* Validation mode as used for OCSP. */ +#define VALIDATE_FLAG_OCSP 16 - /* Full CRL validation. */ - VALIDATE_MODE_CRL_RECURSIVE, +/* Validation mode as used with TLS. */ +#define VALIDATE_FLAG_TLS 32 - /* Validation as used for OCSP. */ - VALIDATE_MODE_OCSP -}; +/* Don't do CRL checks. */ +#define VALIDATE_FLAG_NOCRLCHECK 64 /* Validate the certificate CHAIN up to the trust anchor. Optionally return the closest expiration time in R_EXPTIME. */ gpg_error_t validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, - int mode, char **r_trust_anchor); + unsigned int flags, char **r_trust_anchor); /* Return 0 if the certificate CERT is usable for certification. */ gpg_error_t check_cert_use_cert (ksba_cert_t cert); ----------------------------------------------------------------------- Summary of changes: dirmngr/crlcache.c | 3 ++- dirmngr/server.c | 21 ++++++++++----------- dirmngr/validate.c | 33 ++++++++++++--------------------- dirmngr/validate.h | 37 +++++++++++++++++-------------------- 4 files changed, 41 insertions(+), 53 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 17 22:02:43 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 17 Feb 2017 22:02:43 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-100-gcd32ebd Message-ID: This is an 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 cd32ebd152a522e362469ab969d91f8d49f28a60 (commit) from f07811ee2c0a8044551e2ec063eda61cff7f6e39 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cd32ebd152a522e362469ab969d91f8d49f28a60 Author: Werner Koch Date: Fri Feb 17 21:59:45 2017 +0100 dirmngr: Strip the default https port from the Host: header. * dirmngr/http.c (send_request): Strip the default https port. -- GnuPG-bug-id: 2965 Signed-off-by: Werner Koch diff --git a/dirmngr/http.c b/dirmngr/http.c index 0889cb1..0f6cac6 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -1942,7 +1942,7 @@ send_request (http_t hd, const char *httphost, const char *auth, { char portstr[35]; - if (port == 80) + if (port == (hd->uri->use_tls? 443 : 80)) *portstr = 0; else snprintf (portstr, sizeof portstr, ":%u", port); ----------------------------------------------------------------------- Summary of changes: dirmngr/http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 19 10:30:52 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 19 Feb 2017 10:30:52 +0100 Subject: [git] NTBTLS - branch, master, updated. f9552b3c9f2c9705b2715f8a90479bfc600c61d6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via f9552b3c9f2c9705b2715f8a90479bfc600c61d6 (commit) from b5cbe683800f431737fa47d96edd9e5bdbeb374b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f9552b3c9f2c9705b2715f8a90479bfc600c61d6 Author: Werner Koch Date: Sun Feb 19 10:26:49 2017 +0100 Change verification API to use a callback. * src/ntbtls.h.in: Include ksba.h. (ntbtls_verify_cb_t): New type. (ntbtls_set_ca_chain): Remove prototype. (ntbtls_set_verify_cb): New. (ntbtls_x509_get_peer_cert): New. * src/visibility.c (ntbtls_set_ca_chain): Remove. (ntbtls_set_verify_cb): New. (ntbtls_x509_get_peer_cert): New. * src/visibility.h (ntbtls_set_ca_chain): Remove (ntbtls_set_verify_cb): Mark visible. (ntbtls_x509_get_peer_cert): Ditto. * src/libntbtls.def (ntbtls_set_ca_chain): Remove. (ntbtls_set_verify_cb, ntbtls_x509_get_peer_cert): New. * src/libntbtls.vers (ntbtls_set_ca_chain): Remove. (ntbtls_set_verify_cb, ntbtls_x509_get_peer_cert): New. * src/context.h (_ntbtls_context_s: Remove 'ca_chain' and 'crl_chain'. Add 'verify_cb' and 'verify_cb_value'. * src/protocol.c (_ntbtls_read_certificate): Call verify callback. (session_deinit): Remove superfluous conditional. (_ntbtls_set_ca_chain): Remove. (_ntbtls_set_verify_cb): New. * src/x509.c (x)509_cert_s): Remove fields 'fpr', 'is_self_signed', and 'is_valid'. (_ntbtls_x509_verify): Remove (_ntbtls_x509_get_cert): Fix use of IDX. (_ntbtls_x509_get_peer_cert): New. Signed-off-by: Werner Koch diff --git a/src/context.h b/src/context.h index 3a644c7..61616bc 100644 --- a/src/context.h +++ b/src/context.h @@ -370,8 +370,8 @@ struct _ntbtls_context_s */ key_cert_t key_cert; /*!< own certificate(s)/key(s) */ - x509_cert_t ca_chain; /*!< own trusted CA chain */ - x509_crl_t ca_crl; /*!< trusted CA CRLs */ + ntbtls_verify_cb_t verify_cb; /*!< the verify callback */ + void *verify_cb_value;; /*!< the first arg passed to this cb */ /* * Support for generating and checking session tickets diff --git a/src/libntbtls.def b/src/libntbtls.def index 065287c..c0b9eb8 100644 --- a/src/libntbtls.def +++ b/src/libntbtls.def @@ -32,8 +32,11 @@ EXPORTS ntbtls_handshake @8 - ntbtls_set_ca_chain @9 + ntbtls_set_verify_cb @9 + ntbtls_x509_cert_new @10 ntbtls_x509_cert_release @11 ntbtls_x509_append_cert @12 + + ntbtls_x509_get_peer_cert @13 ; END diff --git a/src/libntbtls.vers b/src/libntbtls.vers index 41c7eb5..8909c19 100644 --- a/src/libntbtls.vers +++ b/src/libntbtls.vers @@ -32,10 +32,12 @@ NTBTLS_1.0 { ntbtls_handshake; - ntbtls_set_ca_chain; + ntbtls_set_verify_cb; + ntbtls_x509_cert_new; ntbtls_x509_cert_release; ntbtls_x509_append_cert; + ntbtls_x509_get_peer_cert; local: *; diff --git a/src/ntbtls-int.h b/src/ntbtls-int.h index cfc5e72..a059115 100644 --- a/src/ntbtls-int.h +++ b/src/ntbtls-int.h @@ -324,8 +324,8 @@ gpg_error_t _ntbtls_get_stream (ntbtls_t tls, gpgrt_stream_t *r_readfp, gpgrt_stream_t *r_writefp); -gpg_error_t _ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain, - x509_crl_t ca_crl); +gpg_error_t _ntbtls_set_verify_cb (ntbtls_t tls, + ntbtls_verify_cb_t cb, void *cb_value); gpg_error_t _ntbtls_set_hostname (ntbtls_t tls, const char *hostname); @@ -375,13 +375,10 @@ gpg_error_t _ntbtls_x509_append_cert (x509_cert_t cert, void _ntbtls_x509_log_cert (const char *text, x509_cert_t chain, int full); const unsigned char *_ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen); +ksba_cert_t _ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx); gpg_error_t _ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk); -gpg_error_t _ntbtls_x509_verify (x509_cert_t cert, x509_cert_t trust_ca, - x509_crl_t ca_crl, - const char *cn, int *r_flags); - int _ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pkalgo); diff --git a/src/ntbtls.h.in b/src/ntbtls.h.in index 864c40f..ce713e4 100644 --- a/src/ntbtls.h.in +++ b/src/ntbtls.h.in @@ -23,6 +23,7 @@ #define _NTBTLS_H #include +#include #ifdef __cplusplus extern "C" { @@ -54,7 +55,7 @@ struct _ntbtls_context_s; typedef struct _ntbtls_context_s *ntbtls_t; /* - * Object to hold X.509 certifciates. + * Object to hold X.509 certificates. */ struct x509_cert_s; typedef struct x509_cert_s *x509_cert_t; @@ -65,6 +66,17 @@ typedef struct x509_cert_s *x509_cert_t; struct x509_crl_s; typedef struct x509_crl_s *x509_crl_t; +/* + * The type of the verification callback. This must be registered + * prior to the handshake and will be called by ntbltls when a peer's + * certificate needs to be verified. OPAQUE is the vale set when the + * callback has been set. TLS is the respective TLS context. + * VERIFY_FLAGS are not yet defined flags. + */ +typedef gpg_error_t (*ntbtls_verify_cb_t) (void *opaque, + ntbtls_t tls, + unsigned int verify_flags); + /* Check that the library fulfills the version requirement. */ const char *ntbtls_check_version (const char *req_version); @@ -96,8 +108,8 @@ gpg_error_t ntbtls_get_stream (ntbtls_t tls, gpgrt_stream_t *r_writefp); /* Set the data required to verify peer certificate. */ -gpg_error_t ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain, - x509_crl_t ca_crl); +gpg_error_t ntbtls_set_verify_cb (ntbtls_t tls, + ntbtls_verify_cb_t cb, void *cb_value); /* Set the hostname to check against the received server certificate. It is used for SNI, too. */ @@ -107,6 +119,8 @@ gpg_error_t ntbtls_set_hostname (ntbtls_t tls, const char *hostname); connected before starting this handshake. */ gpg_error_t ntbtls_handshake (ntbtls_t tls); +/* Return the peer's certificate. */ +ksba_cert_t ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx); /* diff --git a/src/protocol.c b/src/protocol.c index d46238d..dbbc259 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1994,22 +1994,18 @@ _ntbtls_read_certificate (ntbtls_t tls) if (tls->authmode != TLS_VERIFY_NONE) { - if (!tls->ca_chain) - { - debug_msg (1, "got no CA chain"); - return gpg_error (GPG_ERR_NO_CERT_CHAIN); - } - /* * Main check: verify certificate */ - err = _ntbtls_x509_verify (tls->session_negotiate->peer_chain, - tls->ca_chain, tls->ca_crl, - tls->hostname, - &tls->session_negotiate->verify_result); + if (!tls->verify_cb) + { + debug_msg (1, "verify callback not set"); + return gpg_error (GPG_ERR_NOT_INITIALIZED); + } + err = tls->verify_cb (tls->verify_cb_value, tls, 0); if (err) { - debug_ret (1, "x509_verify", err); + debug_ret (1, "error from the verify callback", err); } /* @@ -2455,8 +2451,7 @@ session_deinit (session_t session) if (!session) return; - if (session->peer_chain) - _ntbtls_x509_cert_release (session->peer_chain); + _ntbtls_x509_cert_release (session->peer_chain); free (session->ticket); wipememory (session, sizeof *session); @@ -2792,10 +2787,6 @@ _ntbtls_release (ntbtls_t tls) tls->psk_identity_len = 0; } - if (tls->ca_chain) - { - _ntbtls_x509_cert_release (tls->ca_chain); - } //FIXME: /* ssl_key_cert_free (tls->key_cert); */ @@ -3038,14 +3029,20 @@ _ntbtls_set_session (ntbtls_t tls, const session_t session) /* } */ +/* Set a certificate verify callback for the session TLS. */ gpg_error_t -_ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain, x509_crl_t ca_crl) +_ntbtls_set_verify_cb (ntbtls_t tls, ntbtls_verify_cb_t cb, void *cb_value) { if (!tls) return gpg_error (GPG_ERR_INV_ARG); - tls->ca_chain = ca_chain; - tls->ca_crl = ca_crl; + tls->verify_cb = cb; + tls->verify_cb_value = cb_value; + + /* Make sure we have an authmode set. Right now, there is no API to + * change thye authmode. */ + tls->authmode = cb ? TLS_VERIFY_REQUIRED : TLS_VERIFY_NONE; + return 0; } diff --git a/src/visibility.c b/src/visibility.c index f79ef0c..37a67ae 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -83,9 +83,9 @@ ntbtls_handshake (ntbtls_t tls) gpg_error_t -ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain, x509_crl_t ca_crl) +ntbtls_set_verify_cb (ntbtls_t tls, ntbtls_verify_cb_t cb, void *cb_value) { - return _ntbtls_set_ca_chain (tls, ca_chain, ca_crl); + return _ntbtls_set_verify_cb (tls, cb, cb_value); } @@ -108,3 +108,9 @@ ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen) { return _ntbtls_x509_append_cert (cert, der, derlen); } + +ksba_cert_t +ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx) +{ + return _ntbtls_x509_get_peer_cert (tls, idx); +} diff --git a/src/visibility.h b/src/visibility.h index 69249d3..b3f973d 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -50,10 +50,12 @@ MARK_VISIBLE (ntbtls_get_stream) MARK_VISIBLE (ntbtls_set_hostname) MARK_VISIBLE (ntbtls_handshake) -MARK_VISIBLE (ntbtls_set_ca_chain) +MARK_VISIBLE (ntbtls_set_verify_cb) + MARK_VISIBLE (ntbtls_x509_cert_new) MARK_VISIBLE (ntbtls_x509_cert_release) MARK_VISIBLE (ntbtls_x509_append_cert) +MARK_VISIBLE (ntbtls_x509_get_peer_cert) #undef MARK_VISIBLE @@ -72,10 +74,11 @@ MARK_VISIBLE (ntbtls_x509_append_cert) #define ntbtls_set_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_handshake _ntbtls_USE_THE_UNDERSCORED_FUNCTION -#define ntbtls_set_ca_chain _ntbtls_USE_THE_UNDERSCORED_FUNCTION +#define ntbtls_set_verify_cb _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_x509_cert_new _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_x509_cert_release _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_x509_append_cert _ntbtls_USE_THE_UNDERSCORED_FUNCTION +#define ntbtls_x509_get_peer_cert _ntbtls_USE_THE_UNDERSCORED_FUNCTION #endif /*!_NTBTLS_INCLUDED_BY_VISIBILITY_C*/ #endif /*NTBTLS_VISIBILITY_H*/ diff --git a/src/x509.c b/src/x509.c index 6cf8f57..6ad7655 100644 --- a/src/x509.c +++ b/src/x509.c @@ -33,9 +33,6 @@ struct x509_cert_s { x509_cert_t next; ksba_cert_t crt; /* The actual certificate object. */ - unsigned char fpr[20]; /* Fingerprint of the certificate. */ - int is_self_signed:1; /* This certificate is self-signed. */ - int is_valid:1; /* The certifiate is valid except for revocations. */ }; @@ -90,7 +87,7 @@ _ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen) if (!cert) return gpg_error (GPG_ERR_INV_ARG); - /* Walk to the last certifciate of the chain. */ + /* Walk to the last certificate of the chain. */ while (cert->next) cert = cert->next; @@ -227,7 +224,9 @@ _ntbtls_x509_log_cert (const char *text, x509_cert_t chain_arg, int full) const unsigned char * _ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen) { - for (; cert && idx >= 0; cert = cert->next, idx--) + if (idx < 0) + return NULL; + for (; cert && idx; cert = cert->next, idx--) ; if (!cert) return NULL; @@ -236,6 +235,32 @@ _ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen) } +/* Return the peer's certificates. A value of 0 for IDX returns the + * host's certificate. To enumerate all other certificates IDX needs + * to be incremented until the function returns NULL. The caller + * must release the returned certificate. */ +ksba_cert_t +_ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx) +{ + x509_cert_t cert; + + debug_crt (1, "peer certs A", tls->session_negotiate->peer_chain); + + if (!tls || !tls->session_negotiate || idx < 0) + return NULL; + for (cert = tls->session_negotiate->peer_chain; + cert && idx; + cert = cert->next, idx--) + ; + if (!cert || !cert->crt) + return NULL; + + ksba_cert_ref (cert->crt); + debug_crt (1, "peer certs B", tls->session_negotiate->peer_chain); + return cert->crt; +} + + /* Return the public key from the certificate with index IDX in CERT and store it as an S-expression at R_PK. On error return an error code and store NULL at R_PK. */ @@ -279,17 +304,6 @@ _ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk) } - -gpg_error_t -_ntbtls_x509_verify (x509_cert_t chain, x509_cert_t trust_ca, x509_crl_t ca_crl, - const char *cn, int *r_flags) -{ - //FIXME: - - return 0; -} - - /* Return true if PRIVKEY can do an operation using the public key algorithm PKALGO. */ int ----------------------------------------------------------------------- Summary of changes: src/context.h | 4 ++-- src/libntbtls.def | 5 ++++- src/libntbtls.vers | 4 +++- src/ntbtls-int.h | 9 +++------ src/ntbtls.h.in | 20 +++++++++++++++++--- src/protocol.c | 37 +++++++++++++++++-------------------- src/visibility.c | 10 ++++++++-- src/visibility.h | 7 +++++-- src/x509.c | 46 ++++++++++++++++++++++++++++++---------------- 9 files changed, 89 insertions(+), 53 deletions(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 19 10:41:18 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 19 Feb 2017 10:41:18 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-102-g64fffd0 Message-ID: This is an 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 64fffd0ce2a4fd9cba152cf07497b585410cc652 (commit) via a74902cccde539ee2bd216caec0da6eb54b67c1b (commit) from cd32ebd152a522e362469ab969d91f8d49f28a60 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 64fffd0ce2a4fd9cba152cf07497b585410cc652 Author: Werner Koch Date: Sun Feb 19 10:36:43 2017 +0100 dirmngr: First take on ntbtls cert verification. * dirmngr/http-ntbtls.c: New. * dirmngr/Makefile.am (dirmngr_SOURCES): Add file. * dirmngr/dirmngr.h (SERVER_CONTROL_MAGIC): New. (server_conrol_s): Add field 'magic', * dirmngr/dirmngr.c (dirmngr_init_default_ctrl): Set MAGIC. (dirmngr_deinit_default_ctrl): Set MAGIC to deadbeef. * dirmngr/http.c (my_ntbtls_verify_cb): New. (http_session_new) [HTTP_USE_NTBTLS]: Remove all CA setting code. (send_request) [HTTP_USE_NTBTLS]: Set the verify callback. Do not call the verify callback after the handshake. * dirmngr/ks-engine-hkp.c (send_request): Pass gnupg_http_tls_verify_cb to http_session_new. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/t-http.c (my_http_tls_verify_cb): New. (main): Rename option --gnutls-debug to --tls-debug. (main) [HTTP_USE_NTBTLS]: Create a session. Signed-off-by: Werner Koch diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index d3f89bc..7fa4282 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -62,6 +62,7 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ ocsp.c ocsp.h validate.c validate.h \ dns-stuff.c dns-stuff.h \ http.c http.h \ + http-ntbtls.c \ ks-action.c ks-action.h ks-engine.h \ ks-engine-hkp.c ks-engine-http.c ks-engine-finger.c ks-engine-kdns.c diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index bb07656..718296d 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -1468,6 +1468,7 @@ dirmngr_exit (int rc) void dirmngr_init_default_ctrl (ctrl_t ctrl) { + ctrl->magic = SERVER_CONTROL_MAGIC; if (opt.http_proxy) ctrl->http_proxy = xstrdup (opt.http_proxy); } @@ -1478,6 +1479,8 @@ dirmngr_deinit_default_ctrl (ctrl_t ctrl) { if (!ctrl) return; + ctrl->magic = 0xdeadbeef; + xfree (ctrl->http_proxy); ctrl->http_proxy = NULL; } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 19d2303..57e3372 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -168,12 +168,19 @@ typedef struct cert_ref_s *cert_ref_t; /* Forward references; access only through server.c. */ struct server_local_s; +#if SIZEOF_UNSIGNED_LONG == 8 +# define SERVER_CONTROL_MAGIC 0x6469726d6e677220 +#else +# define SERVER_CONTROL_MAGIC 0x6469726d +#endif + /* Connection control structure. */ struct server_control_s { - int refcount; /* Count additional references to this object. */ - int no_server; /* We are not running under server control. */ - int status_fd; /* Only for non-server mode. */ + unsigned long magic;/* Always has SERVER_CONTROL_MAGIC. */ + int refcount; /* Count additional references to this object. */ + int no_server; /* We are not running under server control. */ + int status_fd; /* Only for non-server mode. */ struct server_local_s *server_local; int force_crl_refresh; /* Always load a fresh CRL. */ @@ -213,6 +220,15 @@ gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...); gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text); gpg_error_t dirmngr_tick (ctrl_t ctrl); +/*-- http-ntbtls.c --*/ +/* Note that we don't use a callback for gnutls. */ + +gpg_error_t gnupg_http_tls_verify_cb (void *opaque, + http_t http, + http_session_t session, + unsigned int flags, + void *tls_context); + /*-- loadswdb.c --*/ gpg_error_t dirmngr_load_swdb (ctrl_t ctrl, int force); diff --git a/dirmngr/http-ntbtls.c b/dirmngr/http-ntbtls.c new file mode 100644 index 0000000..5686877 --- /dev/null +++ b/dirmngr/http-ntbtls.c @@ -0,0 +1,109 @@ +/* http-ntbtls.c - Support for using NTBTLS with http.c + * Copyright (C) 2017 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include + +#include +#include +#include + +#include "dirmngr.h" +#include "certcache.h" +#include "validate.h" + +#ifdef HTTP_USE_NTBTLS +# include + + + +/* The callback used to verify the peer's certificate. */ +gpg_error_t +gnupg_http_tls_verify_cb (void *opaque, + http_t http, + http_session_t session, + unsigned int http_flags, + void *tls_context) +{ + ctrl_t ctrl = opaque; + gpg_error_t err; + int idx; + ksba_cert_t cert; + ksba_cert_t hostcert = NULL; + unsigned int validate_flags; + + (void)http; + (void)session; + + log_assert (ctrl && ctrl->magic == SERVER_CONTROL_MAGIC); + + /* Get the peer's certs fron ntbtls. */ + for (idx = 0; + (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++) + { + if (!idx) + hostcert = cert; + else + { + /* Quick hack to make verification work by inserting the supplied + * certs into the cache. FIXME! */ + cache_cert (cert); + ksba_cert_release (cert); + } + } + if (!idx) + { + err = gpg_error (GPG_ERR_MISSING_CERT); + goto leave; + } + + validate_flags = VALIDATE_FLAG_TLS; + /* if ((http_flags & HTTP_FLAG_TRUST_DEF)) */ + /* validate_flags |= VALIDATE_FLAG_??; */ + if ((http_flags & HTTP_FLAG_TRUST_SYS)) + validate_flags |= VALIDATE_FLAG_SYSTRUST; + + /* FIXME: For now we don't use CRLs. */ + validate_flags |= VALIDATE_FLAG_NOCRLCHECK; + + err = validate_cert_chain (ctrl, hostcert, NULL, validate_flags, NULL); + + leave: + ksba_cert_release (hostcert); + return err; +} + + +#else /*!HTTP_USE_NTBTLS*/ + +/* Dummy function used when not build without ntbtls support. */ +gpg_error_t +gnupg_http_tls_verify_cb (void *opaque, + http_t http, + http_session_t session, + unsigned int flags, + void *tls_context) +{ + (void)opaque; + (void)http; + (void)session; + (void)flags; + (void)tls_context; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} +#endif /*!HTTP_USE_NTBTLS*/ diff --git a/dirmngr/http.c b/dirmngr/http.c index 51aec7e..e7c6d42 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -413,6 +413,21 @@ my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size) #endif /*HTTP_USE_GNUTLS*/ +#ifdef HTTP_USE_NTBTLS +/* Connect the ntbls callback to our generic callback. */ +static gpg_error_t +my_ntbtls_verify_cb (void *opaque, ntbtls_t tls, unsigned int verify_flags) +{ + http_t hd = opaque; + log_assert (hd && hd->session && hd->session->verify_cb); + return hd->session->verify_cb (hd->session->verify_cb_value, + hd, hd->session, + (hd->flags | hd->session->flags), + tls); +} +#endif /*HTTP_USE_NTBTLS*/ + + /* This notification function is called by estream whenever stream is @@ -632,91 +647,16 @@ http_session_new (http_session_t *r_session, #if HTTP_USE_NTBTLS { - x509_cert_t ca_chain; - char line[256]; - estream_t fp, mem_p; - size_t nread, nbytes; - struct b64state state; - void *buf; - size_t buflen; - char *pemname; - - pemname = make_filename_try (gnupg_datadir (), - "sks-keyservers.netCA.pem", NULL); - if (!pemname) - { - err = gpg_error_from_syserror (); - log_error ("setting CA from file '%s' failed: %s\n", - pemname, gpg_strerror (err)); - goto leave; - } - - fp = es_fopen (pemname, "r"); - if (!fp) - { - err = gpg_error_from_syserror (); - log_error ("can't open '%s': %s\n", pemname, gpg_strerror (err)); - xfree (pemname); - goto leave; - } - xfree (pemname); - - mem_p = es_fopenmem (0, "r+b"); - err = b64dec_start (&state, "CERTIFICATE"); - if (err) - { - log_error ("b64dec failure: %s\n", gpg_strerror (err)); - goto leave; - } - - while ( (nread = es_fread (line, 1, DIM (line), fp)) ) - { - err = b64dec_proc (&state, line, nread, &nbytes); - if (err) - { - if (gpg_err_code (err) == GPG_ERR_EOF) - break; - - log_error ("b64dec failure: %s\n", gpg_strerror (err)); - es_fclose (fp); - es_fclose (mem_p); - goto leave; - } - else if (nbytes) - es_fwrite (line, 1, nbytes, mem_p); - } - err = b64dec_finish (&state); - if (err) - { - log_error ("b64dec failure: %s\n", gpg_strerror (err)); - es_fclose (fp); - es_fclose (mem_p); - goto leave; - } - - es_fclose_snatch (mem_p, &buf, &buflen); - es_fclose (fp); - - err = ntbtls_x509_cert_new (&ca_chain); - if (err) - { - log_error ("ntbtls_x509_new failed: %s\n", gpg_strerror (err)); - xfree (buf); - goto leave; - } - - err = ntbtls_x509_append_cert (ca_chain, buf, buflen); - xfree (buf); + (void)intended_hostname; /* Not needed because we do not preload + * certificates. */ err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT); if (err) { log_error ("ntbtls_new failed: %s\n", gpg_strerror (err)); - ntbtls_x509_cert_release (ca_chain); goto leave; } - err = ntbtls_set_ca_chain (sess->tls_session, ca_chain, NULL); } #elif HTTP_USE_GNUTLS { @@ -1819,6 +1759,21 @@ send_request (http_t hd, const char *httphost, const char *auth, return err; } +#ifdef HTTP_USE_NTBTLS + if (hd->session->verify_cb) + { + err = ntbtls_set_verify_cb (hd->session->tls_session, + my_ntbtls_verify_cb, hd); + if (err) + { + log_error ("ntbtls_set_verify_cb failed: %s\n", + gpg_strerror (err)); + xfree (proxy_authstr); + return err; + } + } +#endif /*HTTP_USE_NTBTLS*/ + while ((err = ntbtls_handshake (hd->session->tls_session))) { switch (err) @@ -1833,12 +1788,18 @@ send_request (http_t hd, const char *httphost, const char *auth, hd->session->verify.done = 0; - /* Try the available verify callbacks until one returns success - * or a real error. */ + * or a real error. Note that NTBTLS does the verification + * during the handshake via */ +#ifdef HTTP_USE_NTBTLS + err = 0; /* Fixme check that the CB has been called. */ +#else err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); +#endif - if (hd->session->verify_cb) + if (hd->session->verify_cb + && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR + && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) err = hd->session->verify_cb (hd->session->verify_cb_value, hd, hd->session, (hd->flags | hd->session->flags), diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index b342f09..4ca1e00 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1124,7 +1124,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, *r_fp = NULL; err = http_session_new (&session, httphost, HTTP_FLAG_TRUST_DEF, - NULL, ctrl); + gnupg_http_tls_verify_cb, ctrl); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index f070019..9352a0f 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -77,7 +77,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) /* Note that we only use the system provided certificates with the * fetch command. */ err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_SYS, - NULL, ctrl); + gnupg_http_tls_verify_cb, ctrl); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 8b1d89a..4641121 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -42,7 +42,6 @@ #include "logging.h" #include "http.h" - #if HTTP_USE_NTBTLS # include #elif HTTP_USE_GNUTLS @@ -118,6 +117,56 @@ my_gnutls_log (int level, const char *text) } #endif + +static gpg_error_t +my_http_tls_verify_cb (void *opaque, + http_t http, + http_session_t session, + unsigned int http_flags, + void *tls_context) +{ + gpg_error_t err; + int idx; + ksba_cert_t cert; + ksba_cert_t hostcert = NULL; + + (void)opaque; + (void)http; + (void)session; + + + /* Get the peer's certs fron ntbtls. */ + for (idx = 0; + (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++) + { + if (!idx) + { + log_info ("Received host certificate\n"); + hostcert = cert; + } + else + { + + log_info ("Received additional certificate\n"); + ksba_cert_release (cert); + } + } + if (!idx) + { + err = gpg_error (GPG_ERR_MISSING_CERT); + goto leave; + } + + err = 0; + + leave: + ksba_cert_release (hostcert); + log_info ("my_http_tls_verify_cb returns: %s\n", gpg_strerror (err)); + return err; +} + + + /* Prepend FNAME with the srcdir environment variable's value and return an allocated filename. */ static char * @@ -142,8 +191,7 @@ main (int argc, char **argv) { int last_argc = -1; gpg_error_t err; - int rc; - parsed_uri_t uri; + int rc; parsed_uri_t uri; uri_tuple_t r; http_t hd; int c; @@ -171,7 +219,7 @@ main (int argc, char **argv) "Options:\n" " --verbose print timings etc.\n" " --debug flyswatter\n" - " --gnutls-debug N use GNUTLS debug level N\n" + " --tls-debug N use TLS debug level N\n" " --cacert FNAME expect CA certificate in file FNAME\n" " --no-verify do not verify the certificate\n" " --force-tls use HTTP_FLAG_FORCE_TLS\n" @@ -191,7 +239,7 @@ main (int argc, char **argv) debug++; argc--; argv++; } - else if (!strcmp (*argv, "--gnutls-debug")) + else if (!strcmp (*argv, "--tls-debug")) { argc--; argv++; if (argc) @@ -248,9 +296,11 @@ main (int argc, char **argv) assuan_sock_init (); #if HTTP_USE_NTBTLS - - (void)err; - + log_info ("new session.\n"); + err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_DEF, + my_http_tls_verify_cb, NULL); + if (err) + log_error ("http_session_new failed: %s\n", gpg_strerror (err)); ntbtls_set_debug (tls_dbg, NULL, NULL); #elif HTTP_USE_GNUTLS commit a74902cccde539ee2bd216caec0da6eb54b67c1b Author: Werner Koch Date: Sat Feb 18 16:09:16 2017 +0100 dirmngr: Add per-session verify callback to http.c * dirmngr/http.h (http_verify_cb_t): New type. * dirmngr/http.c (http_session_s): Add fields flags, verify_cb, and verify_cb_value. (http_session_new): Remove arg tls_priority. Add args verify_cb and verify-cb_value. Store them in the session object. (send_request): Use per-session verify callback. (http_verify_server_credentials) [HTTP_USE_NTBTLS]: Return GPG_ERR_NOT_IMPLEMENTED. * dirmngr/ks-engine-hkp.c (send_request): Adjust for changed http_session_new. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/t-http.c (main): Ditto. * dirmngr/server.c (do_get_cert_local): Replace xmalloc by malloc. Signed-off-by: Werner Koch diff --git a/dirmngr/http.c b/dirmngr/http.c index 0f6cac6..51aec7e 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -221,6 +221,13 @@ struct http_session_s /* A callback function to log details of TLS certifciates. */ void (*cert_log_cb) (http_session_t, gpg_error_t, const char *, const void **, size_t *); + + /* The flags passed to the session object. */ + unsigned int flags; + + /* A per-session TLS verification callback. */ + http_verify_cb_t verify_cb; + void *verify_cb_value; }; @@ -606,8 +613,9 @@ http_session_release (http_session_t sess) * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system */ gpg_error_t -http_session_new (http_session_t *r_session, const char *tls_priority, - const char *intended_hostname, unsigned int flags) +http_session_new (http_session_t *r_session, + const char *intended_hostname, unsigned int flags, + http_verify_cb_t verify_cb, void *verify_cb_value) { gpg_error_t err; http_session_t sess; @@ -618,6 +626,9 @@ http_session_new (http_session_t *r_session, const char *tls_priority, if (!sess) return gpg_error_from_syserror (); sess->refcount = 1; + sess->flags = flags; + sess->verify_cb = verify_cb; + sess->verify_cb_value = verify_cb_value; #if HTTP_USE_NTBTLS { @@ -630,8 +641,6 @@ http_session_new (http_session_t *r_session, const char *tls_priority, size_t buflen; char *pemname; - (void)tls_priority; - pemname = make_filename_try (gnupg_datadir (), "sks-keyservers.netCA.pem", NULL); if (!pemname) @@ -799,7 +808,7 @@ http_session_new (http_session_t *r_session, const char *tls_priority, gnutls_transport_set_ptr (sess->tls_session, NULL); rc = gnutls_priority_set_direct (sess->tls_session, - tls_priority? tls_priority : "NORMAL", + "NORMAL", &errpos); if (rc < 0) { @@ -1823,10 +1832,27 @@ send_request (http_t hd, const char *httphost, const char *auth, } hd->session->verify.done = 0; - if (tls_callback) + + + /* Try the available verify callbacks until one returns success + * or a real error. */ + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + if (hd->session->verify_cb) + err = hd->session->verify_cb (hd->session->verify_cb_value, + hd, hd->session, + (hd->flags | hd->session->flags), + hd->session->tls_session); + + if (tls_callback + && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR + && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) err = tls_callback (hd, hd->session, 0); - else + + if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR + && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) err = http_verify_server_credentials (hd->session); + if (err) { log_info ("TLS connection authentication failed: %s <%s>\n", @@ -1834,6 +1860,7 @@ send_request (http_t hd, const char *httphost, const char *auth, xfree (proxy_authstr); return err; } + } #elif HTTP_USE_GNUTLS if (hd->uri->use_tls) @@ -2910,10 +2937,7 @@ cookie_close (void *cookie) gpg_error_t http_verify_server_credentials (http_session_t sess) { -#if HTTP_USE_NTBTLS - (void)sess; - return 0; /* FIXME!! */ -#elif HTTP_USE_GNUTLS +#if HTTP_USE_GNUTLS static const char const errprefix[] = "TLS verification of peer failed"; int rc; unsigned int status; diff --git a/dirmngr/http.h b/dirmngr/http.h index 0b581fe..98ac4a3 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -97,6 +97,13 @@ typedef struct http_session_s *http_session_t; struct http_context_s; typedef struct http_context_s *http_t; +/* A TLS verify callback function. */ +typedef gpg_error_t (*http_verify_cb_t) (void *opaque, + http_t http, + http_session_t session, + unsigned int flags, + void *tls_context); + void http_set_verbose (int verbose, int debug); void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int)); @@ -105,9 +112,10 @@ void http_register_netactivity_cb (void (*cb)(void)); gpg_error_t http_session_new (http_session_t *r_session, - const char *tls_priority, const char *intended_hostname, - unsigned int flags); + unsigned int flags, + http_verify_cb_t cb, + void *cb_value); http_session_t http_session_ref (http_session_t sess); void http_session_release (http_session_t sess); diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index e39d60e..b342f09 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1123,7 +1123,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, *r_fp = NULL; - err = http_session_new (&session, NULL, httphost, HTTP_FLAG_TRUST_DEF); + err = http_session_new (&session, httphost, HTTP_FLAG_TRUST_DEF, + NULL, ctrl); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 69642ff..f070019 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -76,7 +76,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) once_more: /* Note that we only use the system provided certificates with the * fetch command. */ - err = http_session_new (&session, NULL, NULL, HTTP_FLAG_TRUST_SYS); + err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_SYS, + NULL, ctrl); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); diff --git a/dirmngr/server.c b/dirmngr/server.c index 1134ac0..92bbc16 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -370,14 +370,15 @@ do_get_cert_local (ctrl_t ctrl, const char *name, const char *command) char *buf; ksba_cert_t cert; - if (name) - buf = xstrconcat (command, " ", name, NULL); + buf = name? strconcat (command, " ", name, NULL) : xtrystrdup (command); + if (!buf) + rc = gpg_error_from_syserror (); else - buf = xstrdup (command); - - rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf, - &value, &valuelen, MAX_CERT_LENGTH); - xfree (buf); + { + rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf, + &value, &valuelen, MAX_CERT_LENGTH); + xfree (buf); + } if (rc) { log_error (_("assuan_inquire(%s) failed: %s\n"), diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index a87382a..8b1d89a 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -262,7 +262,7 @@ main (int argc, char **argv) http_register_tls_callback (verify_callback); http_register_tls_ca (cafile); - err = http_session_new (&session, NULL, NULL, HTTP_FLAG_TRUST_DEF); + err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_DEF, NULL, NULL); if (err) log_error ("http_session_new failed: %s\n", gpg_strerror (err)); ----------------------------------------------------------------------- Summary of changes: dirmngr/Makefile.am | 1 + dirmngr/dirmngr.c | 3 + dirmngr/dirmngr.h | 22 ++++++- dirmngr/http-ntbtls.c | 109 ++++++++++++++++++++++++++++++++ dirmngr/http.c | 161 +++++++++++++++++++++-------------------------- dirmngr/http.h | 12 +++- dirmngr/ks-engine-hkp.c | 3 +- dirmngr/ks-engine-http.c | 3 +- dirmngr/server.c | 15 ++--- dirmngr/t-http.c | 68 +++++++++++++++++--- 10 files changed, 286 insertions(+), 111 deletions(-) create mode 100644 dirmngr/http-ntbtls.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 19 13:12:05 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 19 Feb 2017 13:12:05 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-11-g3a2ee6d Message-ID: This is an 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 3a2ee6df5911728938a2fb56237b08f790841a0c (commit) from 67e51f9957f875ca854f25f4a9a63aeb831c55c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3a2ee6df5911728938a2fb56237b08f790841a0c Author: Werner Koch Date: Sun Feb 19 13:08:06 2017 +0100 New error code GPG_ERR_INV_NAME. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 912dd0c..4901d99 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,11 @@ Noteworthy changes in version 1.27 (unreleased) [C2_/A2_/R_] gpgrt_b64dec_finish NEW. + * Interface changes relative to the 1.26 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPG_ERR_WRONG_NAME NEW. + + Noteworthy changes in version 1.26 (2016-12-21) [C21/A21/R0] ----------------------------------------------- diff --git a/doc/errorref.txt b/doc/errorref.txt index 6cea1b7..4bc0ebb 100644 --- a/doc/errorref.txt +++ b/doc/errorref.txt @@ -301,7 +301,7 @@ GPG_ERR_INTERNAL Internal error GPG_ERR_EOF_GCRYPT EOF (gcrypt) -GPG_ERR_INV_OBJ Invalid object +GPG_ERR_INV_OBJ Invalid object GPG_ERR_TOO_SHORT Provided object is too short @@ -564,7 +564,7 @@ GPG_ERR_INV_STATE Invalid state The state (of a protocol) is not possible or not defined at all. NTBTLS: - Data received in an unexpected state. - + - A function is called while not being in the right state. GPG_ERR_DUP_VALUE Duplicated value @@ -575,7 +575,7 @@ GPG_ERR_MISSING_ACTION Missing action use of the command "OPEN". others: - The libassuan ce-server test program uses this to - indicate that the client did not conncted to the server + indicate that the client did not connect to the server as requested. GPG_ERR_MODULE_NOT_FOUND ASN.1 module not found @@ -648,6 +648,14 @@ GPG_ERR_NO_ENGINE No crypto engine GPG_ERR_MISSING_KEY Missing key + GNUPG: - gpg-agent returns this error on import or export if a key + wrapping transport key has not been specified. + - It is used when the name "Key" is not found while looking + up name value pairs of the extended private key format + + GCRYPT: - A key has not been set when calling a symmetric + encryption function. + GPG_ERR_TOO_MANY Too many objects GPG: - Dirmngr KS_GET called with too many pattern so that the @@ -802,7 +810,7 @@ GPG_ERR_REQUEST_TOO_LONG Request too long GPG_ERR_OBJ_TERM_STATE Object is in termination state For cards this is the ISO status word 0x6285 (file is in - termnation state). + termination state). GPG_ERR_NO_CERT_CHAIN No certificate chain @@ -1039,6 +1047,10 @@ GPG_ERR_TRY_LATER Try again later different from EAGAIN which is used by the local system. This code is for example used instead of h_error's TRY_AGAIN. +GPG_ERR_WRONG_NAME Wrong name + + NTBTLS: - Hostname does not match the certificate + GPG_ERR_SYSTEM_BUG System bug detected The underlying operating system misbehaved. For example it wrote diff --git a/src/err-codes.h.in b/src/err-codes.h.in index 1c46948..2667d71 100644 --- a/src/err-codes.h.in +++ b/src/err-codes.h.in @@ -332,6 +332,7 @@ 310 GPG_ERR_INV_ORDER Invalid execution order 311 GPG_ERR_ALREADY_FETCHED Already fetched 312 GPG_ERR_TRY_LATER Try again later +313 GPG_ERR_WRONG_NAME Wrong name # This range is free for use. 666 GPG_ERR_SYSTEM_BUG System bug detected ----------------------------------------------------------------------- Summary of changes: NEWS | 5 +++++ doc/errorref.txt | 20 ++++++++++++++++---- src/err-codes.h.in | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 20 09:43:22 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 09:43:22 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-103-g74c04fc Message-ID: This is an 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 74c04fcf2b5713e4001e27ca0989a81cbae0744b (commit) from 64fffd0ce2a4fd9cba152cf07497b585410cc652 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 74c04fcf2b5713e4001e27ca0989a81cbae0744b Author: Werner Koch Date: Mon Feb 20 09:33:45 2017 +0100 Adjust copyright years for sm/certdump.c -- These are the years actual code changes happened. The changes were all done by g10 Code employees. Signed-off-by: Werner Koch diff --git a/sm/certdump.c b/sm/certdump.c index e47251e..bd7c6c3 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -1,5 +1,5 @@ /* certdump.c - Dump a certificate for debugging - * Copyright (C) 2001, 2004, 2007 Free Software Foundation, Inc. + * Copyright (C) 2001-2010, 2014-2015 g10 Code GmbH * * This file is part of GnuPG. * ----------------------------------------------------------------------- Summary of changes: sm/certdump.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 Mon Feb 20 09:51:13 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 09:51:13 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-104-gf923873 Message-ID: This is an 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 f923873863fd863d71349f20f5568f80aecc020b (commit) from 74c04fcf2b5713e4001e27ca0989a81cbae0744b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f923873863fd863d71349f20f5568f80aecc020b Author: Werner Koch Date: Mon Feb 20 09:48:37 2017 +0100 dirmngr: Make t-http.c work again with gnutls. * dirmngr/Makefile.am (t_http_CFLAGS, t_http_LDADD): Add KSBA flags and libs. Signed-off-by: Werner Koch diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 7fa4282..8d22cc4 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -139,12 +139,14 @@ endif # http tests +# We need to add the KSBA flags in case we are building against GNUTLS. +# In that case NTBTLS flags are empty, but we need ksba anyway. t_http_SOURCES = $(t_common_src) t-http.c http.c dns-stuff.c t_http_CFLAGS = -DWITHOUT_NPTH=1 $(USE_C99_CFLAGS) \ $(LIBGCRYPT_CFLAGS) $(NTBTLS_CFLAGS) $(LIBGNUTLS_CFLAGS) \ - $(GPG_ERROR_CFLAGS) + $(GPG_ERROR_CFLAGS) $(KSBA_CFLAGS) t_http_LDADD = $(t_common_ldadd) \ - $(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) $(DNSLIBS) + $(NTBTLS_LIBS) $(KSBA_LIBS) $(LIBGNUTLS_LIBS) $(DNSLIBS) t_ldap_parse_uri_SOURCES = \ t-ldap-parse-uri.c ldap-parse-uri.c ldap-parse-uri.h \ ----------------------------------------------------------------------- Summary of changes: dirmngr/Makefile.am | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 20 09:56:37 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 09:56:37 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-105-g81ea24b Message-ID: This is an 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 81ea24b8637ac08e44e9e44816689413c2ae7e08 (commit) from f923873863fd863d71349f20f5568f80aecc020b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 81ea24b8637ac08e44e9e44816689413c2ae7e08 Author: Werner Koch Date: Mon Feb 20 09:53:31 2017 +0100 dirmngr: Make t-http.c work again with gnutls - second try * dirmngr/t-http.c: Always include ksba.h. Signed-off-by: Werner Koch diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 4641121..37b3e53 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -42,6 +42,7 @@ #include "logging.h" #include "http.h" +#include #if HTTP_USE_NTBTLS # include #elif HTTP_USE_GNUTLS ----------------------------------------------------------------------- Summary of changes: dirmngr/t-http.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 Feb 20 10:05:22 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 10:05:22 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-106-ge174893 Message-ID: This is an 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 e174893262d8de0f52faa8abe4fc0402719a35d8 (commit) from 81ea24b8637ac08e44e9e44816689413c2ae7e08 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e174893262d8de0f52faa8abe4fc0402719a35d8 Author: Werner Koch Date: Mon Feb 20 10:02:25 2017 +0100 dirmngr.c: Make http.c build without any TLS support. * dirmngr/http.c (http_session_new): Remove used of tls_prority. Signed-off-by: Werner Koch diff --git a/dirmngr/http.c b/dirmngr/http.c index e7c6d42..cb90540 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -767,11 +767,12 @@ http_session_new (http_session_t *r_session, goto leave; } } -#else /*!HTTP_USE_GNUTLS*/ +#else /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/ { - (void)tls_priority; + (void)intended_hostname; + (void)flags; } -#endif /*!HTTP_USE_GNUTLS*/ +#endif /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/ if (opt_debug > 1) log_debug ("http.c:session_new: sess %p created\n", sess); ----------------------------------------------------------------------- Summary of changes: dirmngr/http.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 20 10:32:31 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 20 Feb 2017 10:32:31 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-85-ga7c6353 Message-ID: This is an 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 a7c6353edab57b67180aa127ec77d9353c2366fb (commit) from 15fbac9e72a4d1bff9a3b9e9822f9175b09fbcd5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a7c6353edab57b67180aa127ec77d9353c2366fb Author: Justus Winter Date: Mon Feb 20 10:23:41 2017 +0100 python: Fix test. * lang/python/tests/t-quick-key-manipulation.py: Modify the configuration file in the ephemeral home directory, not the one used by all the tests. Fixes-commit: 15fbac9e72a4d1bff9a3b9e9822f9175b09fbcd5 Signed-off-by: Justus Winter diff --git a/lang/python/tests/t-quick-key-manipulation.py b/lang/python/tests/t-quick-key-manipulation.py index d7d2bd4..45e4c0e 100755 --- a/lang/python/tests/t-quick-key-manipulation.py +++ b/lang/python/tests/t-quick-key-manipulation.py @@ -20,6 +20,7 @@ from __future__ import absolute_import, print_function, unicode_literals del absolute_import, print_function, unicode_literals +import os import gpg import support @@ -92,7 +93,7 @@ with support.EphemeralContext() as ctx: pass # Check setting the TOFU policy. - with open("gpg.conf", "a") as handle: + with open(os.path.join(ctx.home_dir, "gpg.conf"), "a") as handle: handle.write("trust-model tofu+pgp\n") for name, policy in [(name, getattr(gpg.constants.tofu.policy, name)) ----------------------------------------------------------------------- Summary of changes: lang/python/tests/t-quick-key-manipulation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 20 17:24:03 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 17:24:03 +0100 Subject: [git] NTBTLS - branch, master, updated. 379c449b6fa539f188fc1d7666ceae17c40a645a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via 379c449b6fa539f188fc1d7666ceae17c40a645a (commit) via 204627b9fd5d67a87a8bee9e2ac3345c06f4c0d8 (commit) from f9552b3c9f2c9705b2715f8a90479bfc600c61d6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 379c449b6fa539f188fc1d7666ceae17c40a645a Author: Werner Koch Date: Mon Feb 20 17:21:10 2017 +0100 Implement hostname checking. * src/x509.c (struct dn_array_s): New. (release_dn_array): New. (parse_dn_part): New. (parse_dn): New. (check_hostname): New. (_ntbtls_x509_check_hostname): New. * src/protocol.c (_ntbtls_read_certificate): Add hostname check. -- The functions parse_dn and parse_dn_part are taken from current gnupg/sm/certdump.c. Signed-off-by: Werner Koch diff --git a/src/ntbtls-int.h b/src/ntbtls-int.h index 882c90d..7a17323 100644 --- a/src/ntbtls-int.h +++ b/src/ntbtls-int.h @@ -383,6 +383,9 @@ gpg_error_t _ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk); int _ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pkalgo); +gpg_error_t _ntbtls_x509_check_hostname (x509_cert_t cert, + const char *hostname); + /*-- dhm.c --*/ gpg_error_t _ntbtls_dhm_new (dhm_context_t *r_dhm); diff --git a/src/protocol.c b/src/protocol.c index dbbc259..4f3ee4a 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1995,46 +1995,43 @@ _ntbtls_read_certificate (ntbtls_t tls) if (tls->authmode != TLS_VERIFY_NONE) { /* - * Main check: verify certificate + * Verify hostname */ - if (!tls->verify_cb) + if (tls->hostname) { - debug_msg (1, "verify callback not set"); - return gpg_error (GPG_ERR_NOT_INITIALIZED); - } - err = tls->verify_cb (tls->verify_cb_value, tls, 0); - if (err) - { - debug_ret (1, "error from the verify callback", err); + if (!tls->session_negotiate) + err = gpg_error (GPG_ERR_MISSING_CERT); + else + err = _ntbtls_x509_check_hostname + (tls->session_negotiate->peer_chain, tls->hostname); + if (err) + { + debug_ret (1, "x509_check_hostname", err); + } } + else + err = 0; /* - * Secondary checks: always done, but change 'ret' only if it was 0 + * Verify certificate. We don't do this if the hostname check + * already failed. */ - //FIXME: - /* { */ - /* pk_context *pk = &tls->session_negotiate->peer_chain->pk; */ - - /* /\* If certificate uses an EC key, make sure the curve is OK *\/ */ - /* if (pk_can_do (pk, POLARSSL_PK_ECKEY) && */ - /* !ssl_curve_is_acceptable (tls, pk_ec (*pk)->grp.id)) */ - /* { */ - /* debug_msg (1, "bad certificate (EC key curve)"); */ - /* if (ret == 0) */ - /* ret = gpg_error (GPG_ERR_BAD_HS_CERT); */ - /* } */ - /* } */ - /* */ - /* if (ssl_check_cert_usage (tls->session_negotiate->peer_chain, */ - /* suite, tls->is_client)) */ - /* { */ - /* debug_msg (1, "bad certificate (usage extensions)"); */ - /* if (!err) */ - /* err = gpg_error (GPG_ERR_BAD_HS_CERT); */ - /* } */ + if (!err) + { + if (!tls->verify_cb) + { + debug_msg (1, "verify callback not set"); + return gpg_error (GPG_ERR_NOT_INITIALIZED); + } + err = tls->verify_cb (tls->verify_cb_value, tls, 0); + if (err) + { + debug_ret (1, "error from the verify callback", err); + } - if (tls->authmode != TLS_VERIFY_REQUIRED) - err = 0; + if (tls->authmode != TLS_VERIFY_REQUIRED) + err = 0; + } } return err; diff --git a/src/x509.c b/src/x509.c index 6ad7655..651624a 100644 --- a/src/x509.c +++ b/src/x509.c @@ -1,5 +1,5 @@ /* x509.c - X.509 functions - * Copyright (C) 2014 g10 Code GmbH + * Copyright (C) 2001-2010, 2014-2015 g10 Code GmbH * * This file is part of NTBTLS * @@ -43,6 +43,224 @@ struct x509_privkey_s }; +/* Object to hold a parsed DN. */ +struct dn_array_s +{ + char *key; + char *value; + int multivalued; + int done; +}; + + +static void +release_dn_array (struct dn_array_s *dnparts) +{ + int i; + + if (!dnparts) + return; + for (i=0; dnparts[i].key; i++) + { + free (dnparts[i].key); + free (dnparts[i].value); + } + free (dnparts); +} + + +/* Helper for parse_dn. */ +static const unsigned char * +parse_dn_part (struct dn_array_s *array, const unsigned char *string) +{ + static struct { + const char *label; + const char *oid; + } label_map[] = { + /* Warning: When adding new labels, make sure that the buffer + below we be allocated large enough. */ + {"EMail", "1.2.840.113549.1.9.1" }, + {"T", "2.5.4.12" }, + {"GN", "2.5.4.42" }, + {"SN", "2.5.4.4" }, + {"NameDistinguisher", "0.2.262.1.10.7.20"}, + {"ADDR", "2.5.4.16" }, + {"BC", "2.5.4.15" }, + {"D", "2.5.4.13" }, + {"PostalCode", "2.5.4.17" }, + {"Pseudo", "2.5.4.65" }, + {"SerialNumber", "2.5.4.5" }, + {NULL, NULL} + }; + const unsigned char *s, *s1; + size_t n; + char *p; + int i; + + /* Parse attributeType */ + for (s = string+1; *s && *s != '='; s++) + ; + if (!*s) + return NULL; /* error */ + n = s - string; + if (!n) + return NULL; /* empty key */ + + /* We need to allocate a few bytes more due to the possible mapping + from the shorter OID to the longer label. */ + array->key = p = malloc (n+10); + if (!array->key) + return NULL; + memcpy (p, string, n); + p[n] = 0; + _ntbtls_trim_trailing_spaces (p); + + if (digitp (p)) + { + for (i=0; label_map[i].label; i++ ) + if ( !strcmp (p, label_map[i].oid) ) + { + strcpy (p, label_map[i].label); + break; + } + } + string = s + 1; + + if (*string == '#') + { /* hexstring */ + string++; + for (s=string; hexdigitp (s); s++) + s++; + n = s - string; + if (!n || (n & 1)) + return NULL; /* Empty or odd number of digits. */ + n /= 2; + array->value = p = malloc (n+1); + if (!p) + return NULL; + for (s1=string; n; s1 += 2, n--, p++) + { + *(unsigned char *)p = xtoi_2 (s1); + if (!*p) + *p = 0x01; /* Better print a wrong value than truncating + the string. */ + } + *p = 0; + } + else + { /* regular v3 quoted string */ + for (n=0, s=string; *s; s++) + { + if (*s == '\\') + { /* pair */ + s++; + if (*s == ',' || *s == '=' || *s == '+' + || *s == '<' || *s == '>' || *s == '#' || *s == ';' + || *s == '\\' || *s == '\"' || *s == ' ') + n++; + else if (hexdigitp (s) && hexdigitp (s+1)) + { + s++; + n++; + } + else + return NULL; /* invalid escape sequence */ + } + else if (*s == '\"') + return NULL; /* invalid encoding */ + else if (*s == ',' || *s == '=' || *s == '+' + || *s == '<' || *s == '>' || *s == ';' ) + break; + else + n++; + } + + array->value = p = malloc (n+1); + if (!p) + return NULL; + for (s=string; n; s++, n--) + { + if (*s == '\\') + { + s++; + if (hexdigitp (s)) + { + *(unsigned char *)p++ = xtoi_2 (s); + s++; + } + else + *p++ = *s; + } + else + *p++ = *s; + } + *p = 0; + } + return s; +} + + +/* Parse a DN and return an array-ized one. This is not a validating + * parser and it does not support any old-stylish syntax; KSBA is + * expected to return only rfc2253 compatible strings. Returns NULL + * on error. */ +static struct dn_array_s * +parse_dn (const unsigned char *string) +{ + struct dn_array_s *array; + size_t arrayidx, arraysize; + int i; + + arraysize = 7; /* C,ST,L,O,OU,CN,email */ + arrayidx = 0; + array = malloc ((arraysize+1) * sizeof *array); + if (!array) + return NULL; + while (*string) + { + while (*string == ' ') + string++; + if (!*string) + break; /* ready */ + if (arrayidx >= arraysize) + { + struct dn_array_s *a2; + + arraysize += 5; + a2 = realloc (array, (arraysize+1) * sizeof *array); + if (!a2) + goto failure; + array = a2; + } + array[arrayidx].key = NULL; + array[arrayidx].value = NULL; + string = parse_dn_part (array+arrayidx, string); + if (!string) + goto failure; + while (*string == ' ') + string++; + array[arrayidx].multivalued = (*string == '+'); + array[arrayidx].done = 0; + arrayidx++; + if (*string && *string != ',' && *string != ';' && *string != '+') + goto failure; /* invalid delimiter */ + if (*string) + string++; + } + array[arrayidx].key = NULL; + array[arrayidx].value = NULL; + return array; + + failure: + for (i=0; i < arrayidx; i++) + { + free (array[i].key); + free (array[i].value); + } + free (array); + return NULL; +} + /* Create a new X.509 certificate chain object and store it at R_CERT. Returns an error code and stores NULL at R_CERT on error. */ @@ -165,7 +383,6 @@ x509_log_time (const char *text, ksba_isotime_t t) void _ntbtls_x509_log_cert (const char *text, x509_cert_t chain_arg, int full) { - gpg_error_t err; x509_cert_t chain; ksba_cert_t cert; ksba_sexp_t sexp; @@ -244,8 +461,6 @@ _ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx) { x509_cert_t cert; - debug_crt (1, "peer certs A", tls->session_negotiate->peer_chain); - if (!tls || !tls->session_negotiate || idx < 0) return NULL; for (cert = tls->session_negotiate->peer_chain; @@ -256,7 +471,6 @@ _ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx) return NULL; ksba_cert_ref (cert->crt); - debug_crt (1, "peer certs B", tls->session_negotiate->peer_chain); return cert->crt; } @@ -315,3 +529,124 @@ _ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pk_alg) /* FIXME: Check that PRIVKEY matches PKALGO. */ return 1; } + + +/* Check that CERT_NAME matches the hostname WANT_NAME. Returns 0 if + * they match, GPG_ERR_WRONG_NAME if they don't match, or an other + * error code for a bad CERT_NAME. */ +static gpg_err_code_t +check_hostname (const char *cert_name, const char *want_name) +{ + const char *s; + + _ntbtls_debug_msg (2, "comparing hostname '%s' to '%s'\n", + cert_name, want_name); + + /* Check that CERT_NAME looks like a valid hostname. We check the + * LDH rule, no empty label, and no leading or trailing hyphen. We + * do not check digit-only names. */ + if (!*cert_name || *cert_name == '-') + return GPG_ERR_INV_NAME; + + for (s = cert_name; *s; s++) + { + if (!(alnump (s) || strchr ("-.", *s))) + return GPG_ERR_INV_NAME; + else if (*s == '.' && s[1] == '.') + return GPG_ERR_INV_NAME; + } + + if (s[-1] == '-') + return GPG_ERR_INV_NAME; + + if (strstr (cert_name, "..")) + return GPG_ERR_INV_NAME; + + /* Now do the actual strcmp. */ + if (_ntbtls_ascii_strcasecmp (cert_name, want_name)) + return GPG_ERR_WRONG_NAME; + + return 0; /* Match. */ +} + + +/* Check that HOSTNAME is in CERT. */ +gpg_error_t +_ntbtls_x509_check_hostname (x509_cert_t cert, const char *hostname) +{ + gpg_err_code_t ec; + gpg_error_t err; + int idx; + struct dn_array_s *dnparts = NULL; + char *dn = NULL; + char *endp, *name; + char *p; + int n, cn_count; + + if (!cert || !cert->crt) + return gpg_error (GPG_ERR_MISSING_CERT); + + /* First we look at the subjectAltNames. */ + for (idx=1; (dn = ksba_cert_get_subject (cert->crt, idx)); idx++) + { + if (!strncmp (dn, "(8:dns-name", 11)) + { + n = strtol (dn + 11, &endp, 10); + if (n < 1 || *endp != ':' || endp[1+n] != ')') + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto leave; + } + name = endp+1; + /* Make sure that thare is no embedded nul and trun it into + * a string. */ + for (p = name; n; p++, n--) + if (!*p) + *p = '\x01'; /* Replace by invalid DNS character. */ + *p = 0; /* Replace the final ')'. */ + ec = check_hostname (name, hostname); + if (ec != GPG_ERR_WRONG_NAME) + { + err = gpg_error (ec); + goto leave; + } + } + ksba_free (dn); + } + + /* Then we look at the CN of the subject. */ + dn = ksba_cert_get_subject (cert->crt, 0); + if (!dn) + { + err = gpg_error (GPG_ERR_BAD_CERT); + goto leave; + } + + dnparts = parse_dn (dn); + if (!dnparts) + { + err = gpg_error (GPG_ERR_BAD_CERT); /* Or out of mem. */ + goto leave; + } + + for (idx=cn_count=0; dnparts[idx].key; idx++) + if (!strcmp (dnparts[idx].key, "CN") + && ++cn_count > 1) + { + err = gpg_error (GPG_ERR_BAD_CERT); + goto leave; + } + + for (idx=0; dnparts[idx].key; idx++) + if (!strcmp (dnparts[idx].key, "CN")) + break; + if (dnparts[idx].key) + err = gpg_error (check_hostname (dnparts[idx].value, hostname)); + else + err = gpg_error (GPG_ERR_WRONG_NAME); + + leave: + release_dn_array (dnparts); + ksba_free (dn); + return err; +} commit 204627b9fd5d67a87a8bee9e2ac3345c06f4c0d8 Author: Werner Koch Date: Mon Feb 20 17:16:43 2017 +0100 New function ntbtls_set_log_handler * src/ntbtls.h.in (ntbtls_log_handler_t): New type. (ntbtls_set_log_handler): New. * src/visibility.c (ntbtls_set_log_handler): New. * src/visibility.h (ntbtls_set_log_handler): Mark visible. * src/libntbtls.def: Add ntbtls_set_log_handler. * src/libntbtls.vers: Add ntbtls_set_log_handler. * src/debug.c (log_handler, log_handler_value): New vars. (_ntbtls_set_log_handler): New. (_ntbtls_set_debug): Do not re-set the prefix. (_ntbtls_debug_msg): Divert to a log handler. * src/util.c (_ntbtls_trim_trailing_spaces): New. (ascii_toupper): New. (_ntbtls_ascii_strcasecmp): New. * src/util.h (spacep, digitp, alphap, alnump, hexdigitp): New macros. (ascii_isspace): New macro. (atoi_1, atoi_2, atoi_4, xtoi_1, xtoi_2, xtoi_4): New macros. Signed-off-by: Werner Koch diff --git a/src/debug.c b/src/debug.c index 7772eda..d2b7c59 100644 --- a/src/debug.c +++ b/src/debug.c @@ -27,14 +27,24 @@ static int debug_level; static const char *debug_prefix; static estream_t debug_stream; +static ntbtls_log_handler_t log_handler; +static void *log_handler_value; +/* Set the Debug level up to which debug messages are shown. 0 + * disables debug messages except for those which will always be + * shown. PREFIX is prefix to prefix all output; the default is + * "ntbtls". STREAM is the output stream; the default is es_stderr. + * Changing STREAM and PREFIX is not thread-safe and their values are + * ignored if a log handler has been set. */ void _ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream) { static char *debug_prefix_buffer; - debug_prefix = "ntbtls"; + if (!debug_prefix) + debug_prefix = "ntbtls"; + if (prefix) { free (debug_prefix_buffer); @@ -49,9 +59,18 @@ _ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream) } +/* Set a dedicated log handler. See the description of + * ntbtls_log_handler_t for details. This is not thread-safe. */ +void +_ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value) +{ + log_handler = cb; + log_handler_value = cb_value; +} + -/* FIXME: For now we print to stderr. Note that a LEVEL of -1 will - * always print even when debugging has not been enabled. */ +/* Note that a LEVEL of -1 will always print even when debugging has + * not been enabled. */ void _ntbtls_debug_msg (int level, const char *format, ...) { @@ -62,20 +81,27 @@ _ntbtls_debug_msg (int level, const char *format, ...) if (level != -1 && (!debug_level || level > debug_level)) return; - if ((no_lf = (*format == '\b'))) - format++; - - saved_errno = errno; va_start (arg_ptr, format); - gpgrt_fputs ("ntbtls: ", es_stderr); - gpgrt_vfprintf (es_stderr, format, arg_ptr); - if (no_lf) - gpgrt_fflush (es_stderr); /* To sync with stderr. */ - else if (*format && format[strlen(format)-1] != '\n') - gpgrt_fputc ('\n', es_stderr); + saved_errno = errno; + if (log_handler) + { + log_handler (log_handler_value, level, format, arg_ptr); + } + else + { + if ((no_lf = (*format == '\b'))) + format++; + + gpgrt_fputs ("ntbtls: ", es_stderr); + gpgrt_vfprintf (es_stderr, format, arg_ptr); + if (no_lf) + gpgrt_fflush (es_stderr); /* To sync with stderr. */ + else if (*format && format[strlen(format)-1] != '\n') + gpgrt_fputc ('\n', es_stderr); + } + va_end (arg_ptr); gpg_err_set_errno (saved_errno); - } diff --git a/src/libntbtls.def b/src/libntbtls.def index c0b9eb8..637de78 100644 --- a/src/libntbtls.def +++ b/src/libntbtls.def @@ -39,4 +39,5 @@ EXPORTS ntbtls_x509_append_cert @12 ntbtls_x509_get_peer_cert @13 + ntbtls_set_log_handler @14 ; END diff --git a/src/libntbtls.vers b/src/libntbtls.vers index 8909c19..47f3c69 100644 --- a/src/libntbtls.vers +++ b/src/libntbtls.vers @@ -23,6 +23,7 @@ NTBTLS_1.0 { global: ntbtls_check_version; ntbtls_set_debug; + ntbtls_set_log_handler; ntbtls_new; ntbtls_release; diff --git a/src/ntbtls-int.h b/src/ntbtls-int.h index a059115..882c90d 100644 --- a/src/ntbtls-int.h +++ b/src/ntbtls-int.h @@ -280,6 +280,8 @@ tls_own_cert (ntbtls_t tls) /*-- util.c --*/ const char *_ntbtls_check_version (const char *req_version); +char *_ntbtls_trim_trailing_spaces (char *string); +int _ntbtls_ascii_strcasecmp (const char *a, const char *b); /*-- protocol.c --*/ const char *_ntbtls_state2str (tls_state_t state); diff --git a/src/ntbtls.h.in b/src/ntbtls.h.in index ce713e4..b887b0a 100644 --- a/src/ntbtls.h.in +++ b/src/ntbtls.h.in @@ -78,6 +78,20 @@ typedef gpg_error_t (*ntbtls_verify_cb_t) (void *opaque, unsigned int verify_flags); +/* + * The type of an optional log handler. + * + * OPAQUE is the value supplied to the set function. LEVEL is the + * debug level for that message; it might be -1 for always log or any + * value less than the limit set with ntbtls_set_debug. FMT is the + * format string. Unless FMT starts with a '\b' the log function is + * expected to append a missing final linefeed. + */ +typedef void (*ntbtls_log_handler_t)(void *opaque, + int level, + const char *fmt, + va_list argv); + /* Check that the library fulfills the version requirement. */ const char *ntbtls_check_version (const char *req_version); @@ -128,11 +142,15 @@ ksba_cert_t ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx); */ /* Enable debugging at LEVEL (> 0) using an optional PREFIX (default: - "ntbtls") and an optional debug stream STREAM (default: es_stderr). - This function is not thread-safe and shall thus be called only once - before any extra threads have been started. */ + * "ntbtls") and an optional debug stream STREAM (default: es_stderr). + * This function is not thread-safe and shall thus be called only once + * before any extra threads have been started. */ void ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream); +/* Set a dedicated log handler. See the description of + * ntbtls_log_handler_t for details. This is not thread-safe. */ +void ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value); + #if 0 /* (Keep Emacsens' auto-indent happy.) */ { diff --git a/src/util.c b/src/util.c index d36ae79..80d5903 100644 --- a/src/util.c +++ b/src/util.c @@ -34,7 +34,7 @@ compat_identification (void) static const char blurb[] = "\n\n" "This is NTBTLS " PACKAGE_VERSION " - Not Too Bad TLS\n" - "Copyright (C) 2014 g10 Code GmbH\n" + "Copyright (C) 2014-2017 g10 Code GmbH\n" "Copyright (C) 2006-2014 Brainspark B.V.\n" "\n" "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" @@ -138,3 +138,51 @@ _ntbtls_check_version (const char *req_version) return NULL; /* Not sufficent. */ } + + +/* + * Remove trailing white spaces from STRING. Returns STRING. + */ +char * +_ntbtls_trim_trailing_spaces (char *string) +{ + char *p, *mark; + + for (mark = NULL, p = string; *p; p++ ) + { + if (isspace (*(unsigned char*)p)) + { + if (!mark) + mark = p; + } + else + mark = NULL; + } + if (mark) + *mark = 0; + + return string; +} + + +static inline int +ascii_toupper (int c) +{ + if (c >= 'a' && c <= 'z') + c &= ~0x20; + return c; +} + +int +_ntbtls_ascii_strcasecmp (const char *a, const char *b) +{ + if (a == b) + return 0; + + for (; *a && *b; a++, b++) + { + if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b)) + break; + } + return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); +} diff --git a/src/util.h b/src/util.h index 9e49111..98a8392 100644 --- a/src/util.h +++ b/src/util.h @@ -30,9 +30,31 @@ #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) +/* Macros to replace ctype macros so o avoid locale problems. */ +#define spacep(p) (*(p) == ' ' || *(p) == '\t') +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define alphap(p) ((*(p) >= 'A' && *(p) <= 'Z') \ + || (*(p) >= 'a' && *(p) <= 'z')) +#define alnump(p) (alphap (p) || digitp (p)) +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) + /* Note this isn't identical to a C locale isspace() without \f and + \v, but works for the purposes used here. */ +#define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') + +/* The atoi macros assume that the buffer has only valid digits. */ +#define atoi_1(p) (*(p) - '0' ) +#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) +#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +#define xtoi_4(p) ((xtoi_2(p) * 256) + xtoi_2((p)+2)) + /* Return the size of a OID string without the nul. */ -//FIXME: Do we use it? +/* FIXME: Do we use it? */ #define OID_SIZE(x) (sizeof(x) - 1) @@ -94,6 +116,7 @@ buf32_to_u32 (const void *buffer) /*-- debug.c --*/ void _ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream); +void _ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value); void _ntbtls_debug_msg (int level, const char *format, ...) GPGRT_ATTR_PRINTF(2,0); @@ -121,6 +144,9 @@ void _ntbtls_debug_crt (int level, const char *text, x509_cert_t chain); # define GPG_ERR_REQUEST_TOO_SHORT 223 # define GPG_ERR_REQUEST_TOO_LONG 224 #endif +#if GPG_ERROR_VERSION_NUMBER < 0x011b00 /* 1.27 */ +# define GPG_ERR_WRONG_NAME 313 +#endif diff --git a/src/visibility.c b/src/visibility.c index 37a67ae..73f2452 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -38,6 +38,13 @@ ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream) } +void +ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value) +{ + _ntbtls_set_log_handler (cb, cb_value); +} + + gpg_error_t ntbtls_new (ntbtls_t *r_tls, unsigned int flags) { diff --git a/src/visibility.h b/src/visibility.h index b3f973d..7f6db83 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -43,6 +43,7 @@ MARK_VISIBLE (ntbtls_check_version) MARK_VISIBLE (ntbtls_set_debug) +MARK_VISIBLE (ntbtls_set_log_handler) MARK_VISIBLE (ntbtls_new) MARK_VISIBLE (ntbtls_release) MARK_VISIBLE (ntbtls_set_transport) @@ -67,6 +68,7 @@ MARK_VISIBLE (ntbtls_x509_get_peer_cert) #define ntbtls_check_version _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_set_debug _ntbtls_USE_THE_UNDERSCORED_FUNCTION +#define ntbtls_set_log_handler _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_new _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_released _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_set_transport _ntbtls_USE_THE_UNDERSCORED_FUNCTION ----------------------------------------------------------------------- Summary of changes: src/debug.c | 54 ++++++--- src/libntbtls.def | 1 + src/libntbtls.vers | 1 + src/ntbtls-int.h | 5 + src/ntbtls.h.in | 24 +++- src/protocol.c | 63 +++++----- src/util.c | 50 +++++++- src/util.h | 28 ++++- src/visibility.c | 7 ++ src/visibility.h | 2 + src/x509.c | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 11 files changed, 523 insertions(+), 57 deletions(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 20 17:28:04 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 17:28:04 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-108-ga022baa Message-ID: This is an 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 a022baa4a487eec769411255a64088450c4c8a49 (commit) via 3e9512e557d95c7dc36835365b127b25f6a5cdd9 (commit) from e174893262d8de0f52faa8abe4fc0402719a35d8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a022baa4a487eec769411255a64088450c4c8a49 Author: Werner Koch Date: Mon Feb 20 17:24:00 2017 +0100 dirmngr: Setup a log handler for ntbtls. * dirmngr/dirmngr.c (my_ntbtls_log_handler) [HTTP_USE_NTBTLS]: New. (main) [HTTP_USE_NTBTLS]: Register log handler. Signed-off-by: Werner Koch diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 718296d..5e6d983 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -715,6 +715,23 @@ pid_suffix_callback (unsigned long *r_suffix) } #endif /*!HAVE_W32_SYSTEM*/ +#if HTTP_USE_NTBTLS +static void +my_ntbtls_log_handler (void *opaque, int level, const char *fmt, va_list argv) +{ + (void)opaque; + + if (level == -1) + log_logv_with_prefix (GPGRT_LOG_INFO, "ntbtls: ", fmt, argv); + else + { + char prefix[10+20]; + snprintf (prefix, sizeof prefix, "ntbtls(%d): ", level); + log_logv_with_prefix (GPGRT_LOG_DEBUG, prefix, fmt, argv); + } +} +#endif + static void thread_init (void) @@ -801,6 +818,10 @@ main (int argc, char **argv) setup_libgcrypt_logging (); +#if HTTP_USE_NTBTLS + ntbtls_set_log_handler (my_ntbtls_log_handler, NULL); +#endif + /* Setup defaults. */ shell = getenv ("SHELL"); if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) commit 3e9512e557d95c7dc36835365b127b25f6a5cdd9 Author: Werner Koch Date: Mon Feb 20 17:22:59 2017 +0100 common: New function log_logv_with_prefix. * common/logging.c (do_logv): Add arg 'prefmt' and print it. Chnage call callers to pass NULL. (log_logv_with_prefix): New. -- Signed-off-by: Werner Koch diff --git a/common/logging.c b/common/logging.c index 670affb..97f0813 100644 --- a/common/logging.c +++ b/common/logging.c @@ -727,7 +727,7 @@ print_prefix (int level, int leading_backspace) static void do_logv (int level, int ignore_arg_ptr, const char *extrastring, - const char *fmt, va_list arg_ptr) + const char *prefmt, const char *fmt, va_list arg_ptr) { int leading_backspace = (fmt && *fmt == '\b'); @@ -759,6 +759,9 @@ do_logv (int level, int ignore_arg_ptr, const char *extrastring, if (fmt) { + if (prefmt) + es_fputs_unlocked (prefmt, logstream); + if (ignore_arg_ptr) { /* This is used by log_string and comes with the extra * feature that after a LF the next line is indent at the @@ -861,7 +864,7 @@ log_log (int level, const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt) ; - do_logv (level, 0, NULL, fmt, arg_ptr); + do_logv (level, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -869,7 +872,18 @@ log_log (int level, const char *fmt, ...) void log_logv (int level, const char *fmt, va_list arg_ptr) { - do_logv (level, 0, NULL, fmt, arg_ptr); + do_logv (level, 0, NULL, NULL, fmt, arg_ptr); +} + + +/* Same as log_logv but PREFIX is printed immediately before FMT. + * Note that PREFIX is an additional string and independent of the + * prefix set by log_set_prefix. */ +void +log_logv_with_prefix (int level, const char *prefix, + const char *fmt, va_list arg_ptr) +{ + do_logv (level, 0, NULL, prefix, fmt, arg_ptr); } @@ -878,7 +892,7 @@ do_log_ignore_arg (int level, const char *str, ...) { va_list arg_ptr; va_start (arg_ptr, str); - do_logv (level, 1, NULL, str, arg_ptr); + do_logv (level, 1, NULL, NULL, str, arg_ptr); va_end (arg_ptr); } @@ -900,7 +914,7 @@ log_info (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_INFO, 0, NULL, fmt, arg_ptr); + do_logv (GPGRT_LOG_INFO, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -911,7 +925,7 @@ log_error (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_ERROR, 0, NULL, fmt, arg_ptr); + do_logv (GPGRT_LOG_ERROR, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); /* Protect against counter overflow. */ if (errorcount < 30000) @@ -925,7 +939,7 @@ log_fatal (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_FATAL, 0, NULL, fmt, arg_ptr); + do_logv (GPGRT_LOG_FATAL, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); abort (); /* Never called; just to make the compiler happy. */ } @@ -937,7 +951,7 @@ log_bug (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_BUG, 0, NULL, fmt, arg_ptr); + do_logv (GPGRT_LOG_BUG, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); abort (); /* Never called; just to make the compiler happy. */ } @@ -949,7 +963,7 @@ log_debug (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, NULL, fmt, arg_ptr); + do_logv (GPGRT_LOG_DEBUG, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -963,7 +977,7 @@ log_debug_with_string (const char *string, const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, string, fmt, arg_ptr); + do_logv (GPGRT_LOG_DEBUG, 0, string, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -974,7 +988,7 @@ log_printf (const char *fmt, ...) va_list arg_ptr; va_start (arg_ptr, fmt); - do_logv (fmt ? GPGRT_LOG_CONT : GPGRT_LOG_BEGIN, 0, NULL, fmt, arg_ptr); + do_logv (fmt ? GPGRT_LOG_CONT : GPGRT_LOG_BEGIN, 0, NULL, NULL, fmt, arg_ptr); va_end (arg_ptr); } diff --git a/common/logging.h b/common/logging.h index ed1d3b9..515d850 100644 --- a/common/logging.h +++ b/common/logging.h @@ -90,6 +90,8 @@ enum jnlib_log_levels { }; void log_log (int level, const char *fmt, ...) GPGRT_ATTR_PRINTF(2,3); void log_logv (int level, const char *fmt, va_list arg_ptr); +void log_logv_with_prefix (int level, const char *prefix, + const char *fmt, va_list arg_ptr); void log_string (int level, const char *string); void log_bug (const char *fmt, ...) GPGRT_ATTR_NR_PRINTF(1,2); void log_fatal (const char *fmt, ...) GPGRT_ATTR_NR_PRINTF(1,2); ----------------------------------------------------------------------- Summary of changes: common/logging.c | 36 +++++++++++++++++++++++++----------- common/logging.h | 2 ++ dirmngr/dirmngr.c | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 20 20:40:00 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 20 Feb 2017 20:40:00 +0100 Subject: [git] NTBTLS - branch, master, updated. 19d9776ac40e7ff9fcfed7838ff8261ba8d61fac Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via 19d9776ac40e7ff9fcfed7838ff8261ba8d61fac (commit) via cd1bbb3182178fa1db487d8a1bcbc1647201ba97 (commit) from 379c449b6fa539f188fc1d7666ceae17c40a645a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 19d9776ac40e7ff9fcfed7838ff8261ba8d61fac Author: Werner Koch Date: Mon Feb 20 20:37:11 2017 +0100 Implement wildcards for hostname checking. * src/x509.c (count_labels): New. (check_hostname): Implement wildcards. -- We support wildcards in the CN and subjectAltNames. The wildcard must be the first label and macthes only one label. *.org - bad *.example.org - good *.foo.example.org - good *x.example.org - bad foo.*.example.org - bad *.foo.example.org - good The name *.example.org mactes for example example.org www.example.org ftp.example.org but not for example ftp.foo.example.org In general wildcard certifcates are a bad idea and should be avoided. Signed-off-by: Werner Koch diff --git a/src/x509.c b/src/x509.c index 651624a..f948b9c 100644 --- a/src/x509.c +++ b/src/x509.c @@ -531,6 +531,31 @@ _ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pk_alg) } +/* Return the number of labels in the DNS NAME. NAME is invalid 0 is + * returned. */ +static int +count_labels (const char *name) +{ + const char *s; + int count = 0; + + if (*name == '.') + name++; /* Skip a leading dot. */ + if (*name == '.') + return 0; /* Zero length labels at the start - invalid. */ + for (s = name; *s; s++) + { + if (*s == '.' && s[1] == '.') + return 0; /* Zero length label - invalid. */ + else if (*s == '.') + count++; + } + if (s > name && s[-1] == '.') + return 0; /* Trailing dot - invalid. */ + + return count + 1; /* (NB. We are counting dots). */ +} + /* Check that CERT_NAME matches the hostname WANT_NAME. Returns 0 if * they match, GPG_ERR_WRONG_NAME if they don't match, or an other * error code for a bad CERT_NAME. */ @@ -538,13 +563,29 @@ static gpg_err_code_t check_hostname (const char *cert_name, const char *want_name) { const char *s; + int wildcard = 0; + int n_cert = 0; + int n_want = 0; - _ntbtls_debug_msg (2, "comparing hostname '%s' to '%s'\n", + _ntbtls_debug_msg (1, "comparing hostname '%s' to '%s'\n", cert_name, want_name); + if (*cert_name == '*' && cert_name[1] == '.') + { + wildcard = 1; + cert_name += 2; /* Skip over the wildcard. */ + + n_cert = count_labels (cert_name); + n_want = count_labels (want_name); + + if (n_cert < 2 || n_want < 2) + return GPG_ERR_WRONG_NAME; /* Less than 2 labels - no wildcards. */ + } + /* Check that CERT_NAME looks like a valid hostname. We check the * LDH rule, no empty label, and no leading or trailing hyphen. We - * do not check digit-only names. */ + * do not check digit-only names. We also check that the hostname + * does not end in a dot. */ if (!*cert_name || *cert_name == '-') return GPG_ERR_INV_NAME; @@ -556,12 +597,29 @@ check_hostname (const char *cert_name, const char *want_name) return GPG_ERR_INV_NAME; } - if (s[-1] == '-') + if (s[-1] == '-' || s[-1] == '.') return GPG_ERR_INV_NAME; if (strstr (cert_name, "..")) return GPG_ERR_INV_NAME; + /* In case of wildcards prepare our name for the strcmp. */ + if (wildcard) + { + if (n_cert == n_want) + ; /* Compare direct. */ + else if (n_cert + 1 == n_want) + { + /* We know that n_want has at least one dot. */ + want_name = strchr (want_name, '.'); + if (!want_name) + return GPG_ERR_BUG; + want_name++; + } + else + return GPG_ERR_WRONG_NAME; /* max one label may be wild - no match. */ + } + /* Now do the actual strcmp. */ if (_ntbtls_ascii_strcasecmp (cert_name, want_name)) return GPG_ERR_WRONG_NAME; commit cd1bbb3182178fa1db487d8a1bcbc1647201ba97 Author: Werner Koch Date: Mon Feb 20 20:30:18 2017 +0100 ntbtls-cli: New option --head and use a default SNI. * src/ntbtls-cli.c (opt_head): New var. (simple_client): Request "HEAD". (main): Add option --head. Use default SNI value. Signed-off-by: Werner Koch diff --git a/src/ntbtls-cli.c b/src/ntbtls-cli.c index 29b2784..1656376 100644 --- a/src/ntbtls-cli.c +++ b/src/ntbtls-cli.c @@ -45,6 +45,8 @@ static int verbose; static int errorcount; static char *opt_hostname; +static int opt_head; + /* @@ -247,7 +249,7 @@ simple_client (const char *server, int port) do { - es_fputs ("GET / HTTP/1.0\r\n", writefp); + es_fprintf (writefp, "%s / HTTP/1.0\r\n", opt_head? "HEAD":"GET"); if (opt_hostname) es_fprintf (writefp, "Host: %s\r\n", opt_hostname); es_fprintf (writefp, "X-ntbtls: %s\r\n", @@ -272,6 +274,7 @@ main (int argc, char **argv) int last_argc = -1; int debug_level = 0; int port = 443; + char *host; if (argc) { argc--; argv++; } @@ -292,7 +295,8 @@ main (int argc, char **argv) " --verbose show more diagnostics\n" " --debug LEVEL enable debugging at LEVEL\n" " --port N connect to port N (default is 443)\n" - " --hostname NAME use NAME for SNI\n" + " --hostname NAME use NAME instead of HOST for SNI\n" + " --head send a HEAD and not a GET request\n" "\n", stdout); return 0; } @@ -339,10 +343,21 @@ main (int argc, char **argv) opt_hostname = *argv; argc--; argv++; } + else if (!strcmp (*argv, "--head")) + { + opt_head = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2) && (*argv)[2]) die ("Invalid option '%s'\n", *argv); } + host = argc? *argv : "localhost"; + if (!opt_hostname) + opt_hostname = host; + if (!*opt_hostname) + opt_hostname = NULL; + if (!ntbtls_check_version (PACKAGE_VERSION)) die ("NTBTLS library too old (need %s, have %s)\n", PACKAGE_VERSION, ntbtls_check_version (NULL)); @@ -350,6 +365,6 @@ main (int argc, char **argv) if (debug_level) ntbtls_set_debug (debug_level, NULL, NULL); - simple_client (argc? *argv : "localhost", port); + simple_client (host, port); return 0; } ----------------------------------------------------------------------- Summary of changes: src/ntbtls-cli.c | 21 ++++++++++++++++--- src/x509.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 6 deletions(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 00:34:08 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 21 Feb 2017 00:34:08 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-109-g3fc6922 Message-ID: This is an 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 3fc69224b7b22ad1df1395ebcb21549384839cd1 (commit) from a022baa4a487eec769411255a64088450c4c8a49 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3fc69224b7b22ad1df1395ebcb21549384839cd1 Author: NIIBE Yutaka Date: Tue Feb 21 08:27:23 2017 +0900 g10: Support primary key generation by keygrip. * g10/keygen.c (para_name): Add pKEYGRIP. (generate_keypair): Use pKEYGRIP for key generation. (do_generate_keypair): Call do_create_from_keygrip with pKEYGRIP. -- https://lists.gnupg.org/pipermail/gnupg-devel/2017-February/032591.html Reported-by: Alon Bar-Lev Suggested-by: Peter Lebbing Signed-off-by: NIIBE Yutaka diff --git a/g10/keygen.c b/g10/keygen.c index 98ef29e..e2bdfc1 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -89,7 +89,8 @@ enum para_name { pSERIALNO, pCARDBACKUPKEY, pHANDLE, - pKEYSERVER + pKEYSERVER, + pKEYGRIP }; struct para_data_s { @@ -3653,8 +3654,9 @@ read_parameter_file (ctrl_t ctrl, const char *fname ) { "Preferences", pPREFERENCES }, { "Revoker", pREVOKER }, { "Handle", pHANDLE }, - { "Keyserver", pKEYSERVER }, - { NULL, 0 } + { "Keyserver", pKEYSERVER }, + { "Keygrip", pKEYGRIP }, + { NULL, 0 } }; IOBUF fp; byte *line; @@ -4175,137 +4177,166 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, else if (full) /* Full featured key generation. */ { int subkey_algo; - char *curve = NULL; - - /* Fixme: To support creating a primary key by keygrip we better - also define the keyword for the parameter file. Note that - the subkey case will never be asserted if a keygrip has been - given. */ - algo = ask_algo (ctrl, 0, &subkey_algo, &use, NULL); - if (subkey_algo) + char *key_from_hexgrip = NULL; + + algo = ask_algo (ctrl, 0, &subkey_algo, &use, &key_from_hexgrip); + if (key_from_hexgrip) { - /* Create primary and subkey at once. */ - both = 1; - if (algo == PUBKEY_ALGO_ECDSA - || algo == PUBKEY_ALGO_EDDSA - || algo == PUBKEY_ALGO_ECDH) + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pKEYTYPE; + sprintf( r->u.value, "%d", algo); + r->next = para; + para = r; + + if (use) { - curve = ask_curve (&algo, &subkey_algo); - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo); - r->next = para; - para = r; - nbits = 0; - r = xmalloc_clear (sizeof *r + strlen (curve)); - r->key = pKEYCURVE; - strcpy (r->u.value, curve); + r = xmalloc_clear( sizeof *r + 25 ); + r->key = pKEYUSAGE; + sprintf( r->u.value, "%s%s%s", + (use & PUBKEY_USAGE_SIG)? "sign ":"", + (use & PUBKEY_USAGE_ENC)? "encrypt ":"", + (use & PUBKEY_USAGE_AUTH)? "auth":"" ); r->next = para; para = r; } - else + + r = xmalloc_clear( sizeof *r + 40 ); + r->key = pKEYGRIP; + strcpy (r->u.value, key_from_hexgrip); + r->next = para; + para = r; + + xfree (key_from_hexgrip); + } + else + { + char *curve = NULL; + + if (subkey_algo) { + /* Create primary and subkey at once. */ + both = 1; + if (algo == PUBKEY_ALGO_ECDSA + || algo == PUBKEY_ALGO_EDDSA + || algo == PUBKEY_ALGO_ECDH) + { + curve = ask_curve (&algo, &subkey_algo); + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pKEYTYPE; + sprintf( r->u.value, "%d", algo); + r->next = para; + para = r; + nbits = 0; + r = xmalloc_clear (sizeof *r + strlen (curve)); + r->key = pKEYCURVE; + strcpy (r->u.value, curve); + r->next = para; + para = r; + } + else + { + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pKEYTYPE; + sprintf( r->u.value, "%d", algo); + r->next = para; + para = r; + nbits = ask_keysize (algo, 0); + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pKEYLENGTH; + sprintf( r->u.value, "%u", nbits); + r->next = para; + para = r; + } r = xmalloc_clear( sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo); + r->key = pKEYUSAGE; + strcpy( r->u.value, "sign" ); r->next = para; para = r; - nbits = ask_keysize (algo, 0); + r = xmalloc_clear( sizeof *r + 20 ); - r->key = pKEYLENGTH; - sprintf( r->u.value, "%u", nbits); + r->key = pSUBKEYTYPE; + sprintf( r->u.value, "%d", subkey_algo); + r->next = para; + para = r; + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pSUBKEYUSAGE; + strcpy( r->u.value, "encrypt" ); r->next = para; para = r; - } - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pKEYUSAGE; - strcpy( r->u.value, "sign" ); - r->next = para; - para = r; - - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", subkey_algo); - r->next = para; - para = r; - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pSUBKEYUSAGE; - strcpy( r->u.value, "encrypt" ); - r->next = para; - para = r; - if (algo == PUBKEY_ALGO_ECDSA - || algo == PUBKEY_ALGO_EDDSA - || algo == PUBKEY_ALGO_ECDH) + if (algo == PUBKEY_ALGO_ECDSA + || algo == PUBKEY_ALGO_EDDSA + || algo == PUBKEY_ALGO_ECDH) + { + if (algo == PUBKEY_ALGO_EDDSA + && subkey_algo == PUBKEY_ALGO_ECDH) + { + /* Need to switch to a different curve for the + encryption key. */ + xfree (curve); + curve = xstrdup ("Curve25519"); + } + r = xmalloc_clear (sizeof *r + strlen (curve)); + r->key = pSUBKEYCURVE; + strcpy (r->u.value, curve); + r->next = para; + para = r; + } + } + else /* Create only a single key. */ { - if (algo == PUBKEY_ALGO_EDDSA - && subkey_algo == PUBKEY_ALGO_ECDH) + /* For ECC we need to ask for the curve before storing the + algo because ask_curve may change the algo. */ + if (algo == PUBKEY_ALGO_ECDSA + || algo == PUBKEY_ALGO_EDDSA + || algo == PUBKEY_ALGO_ECDH) { - /* Need to switch to a different curve for the - encryption key. */ - xfree (curve); - curve = xstrdup ("Curve25519"); + curve = ask_curve (&algo, NULL); + r = xmalloc_clear (sizeof *r + strlen (curve)); + r->key = pKEYCURVE; + strcpy (r->u.value, curve); + r->next = para; + para = r; } - r = xmalloc_clear (sizeof *r + strlen (curve)); - r->key = pSUBKEYCURVE; - strcpy (r->u.value, curve); + + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pKEYTYPE; + sprintf( r->u.value, "%d", algo ); r->next = para; para = r; + + if (use) + { + r = xmalloc_clear( sizeof *r + 25 ); + r->key = pKEYUSAGE; + sprintf( r->u.value, "%s%s%s", + (use & PUBKEY_USAGE_SIG)? "sign ":"", + (use & PUBKEY_USAGE_ENC)? "encrypt ":"", + (use & PUBKEY_USAGE_AUTH)? "auth":"" ); + r->next = para; + para = r; + } + nbits = 0; } - } - else /* Create only a single key. */ - { - /* For ECC we need to ask for the curve before storing the - algo because ask_curve may change the algo. */ + if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) { - curve = ask_curve (&algo, NULL); - r = xmalloc_clear (sizeof *r + strlen (curve)); - r->key = pKEYCURVE; - strcpy (r->u.value, curve); - r->next = para; - para = r; + /* The curve has already been set. */ } - - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - - if (use) + else { - r = xmalloc_clear( sizeof *r + 25 ); - r->key = pKEYUSAGE; - sprintf( r->u.value, "%s%s%s", - (use & PUBKEY_USAGE_SIG)? "sign ":"", - (use & PUBKEY_USAGE_ENC)? "encrypt ":"", - (use & PUBKEY_USAGE_AUTH)? "auth":"" ); + nbits = ask_keysize (both? subkey_algo : algo, nbits); + r = xmalloc_clear( sizeof *r + 20 ); + r->key = both? pSUBKEYLENGTH : pKEYLENGTH; + sprintf( r->u.value, "%u", nbits); r->next = para; para = r; } - nbits = 0; - } - if (algo == PUBKEY_ALGO_ECDSA - || algo == PUBKEY_ALGO_EDDSA - || algo == PUBKEY_ALGO_ECDH) - { - /* The curve has already been set. */ - } - else - { - nbits = ask_keysize (both? subkey_algo : algo, nbits); - r = xmalloc_clear( sizeof *r + 20 ); - r->key = both? pSUBKEYLENGTH : pKEYLENGTH; - sprintf( r->u.value, "%u", nbits); - r->next = para; - para = r; + xfree (curve); } - - xfree (curve); } else /* Default key generation. */ { @@ -4547,6 +4578,9 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, int did_sub = 0; u32 timestamp; char *cache_nonce = NULL; + int algo; + u32 expire; + const char *key_from_hexgrip = NULL; if (outctrl->dryrun) { @@ -4612,20 +4646,26 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, node of the subkey but that is more work than just to pass the current timestamp. */ - if (!card) - err = do_create (get_parameter_algo( para, pKEYTYPE, NULL ), + algo = get_parameter_algo( para, pKEYTYPE, NULL ); + expire = get_parameter_u32( para, pKEYEXPIRE ); + key_from_hexgrip = get_parameter_value (para, pKEYGRIP); + if (key_from_hexgrip) + err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip, + pub_root, timestamp, expire, 0); + else if (!card) + err = do_create (algo, get_parameter_uint( para, pKEYLENGTH ), get_parameter_value (para, pKEYCURVE), pub_root, timestamp, - get_parameter_u32( para, pKEYEXPIRE ), 0, + expire, 0, outctrl->keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL); else - err = gen_card_key (1, get_parameter_algo( para, pKEYTYPE, NULL ), + err = gen_card_key (1, algo, 1, pub_root, ×tamp, - get_parameter_u32 (para, pKEYEXPIRE)); + expire); /* Get the pointer to the generated public key packet. */ if (!err) ----------------------------------------------------------------------- Summary of changes: g10/keygen.c | 258 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 149 insertions(+), 109 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 09:15:43 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 09:15:43 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-110-g39c7450 Message-ID: This is an 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 39c745038181edd097e188434b3f9c971ed3987f (commit) from 3fc69224b7b22ad1df1395ebcb21549384839cd1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 39c745038181edd097e188434b3f9c971ed3987f Author: Werner Koch Date: Tue Feb 21 09:12:00 2017 +0100 dirmngr: Add a magic field to the http structs. * dirmngr/http.c (HTTP_SESSION_MAGIC): New. (http_session_s): New field 'magic'. (HTTP_CONTEXT_MAGIC): New. (http_context_s): New field 'magic'. (my_ntbtls_verify_cb): Assert MAGIC. (fp_onclose_notification): Ditto. (session_unref): Ditto. Reset MAGIC. (http_session_new): Set MAGIC. (http_open): Ditto. (http_raw_connect): Ditto. (http_close): Assert MAGIC. Reset MAGIC. * dirmngr/t-http.c (my_http_tls_verify_cb): MArk HTTP_FLAGS unused. -- We pass those handles through opaque pointers. The magic numbers will help to detect wrong use. Signed-off-by: Werner Koch diff --git a/dirmngr/http.c b/dirmngr/http.c index cb90540..89e46ca 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -202,9 +202,18 @@ struct cookie_s }; typedef struct cookie_s *cookie_t; + +#if SIZEOF_UNSIGNED_LONG == 8 +# define HTTP_SESSION_MAGIC 0x0068545470534553 /* "hTTpSES" */ +#else +# define HTTP_SESSION_MAGIC 0x68547365 /* "hTse" */ +#endif + /* The session object. */ struct http_session_s { + unsigned long magic; + int refcount; /* Number of references to this object. */ #ifdef HTTP_USE_GNUTLS gnutls_certificate_credentials_t certcred; @@ -241,9 +250,17 @@ struct header_s typedef struct header_s *header_t; +#if SIZEOF_UNSIGNED_LONG == 8 +# define HTTP_CONTEXT_MAGIC 0x0068545470435458 /* "hTTpCTX" */ +#else +# define HTTP_CONTEXT_MAGIC 0x68546378 /* "hTcx" */ +#endif + + /* Our handle context. */ struct http_context_s { + unsigned long magic; unsigned int status_code; my_socket_t sock; unsigned int in_data:1; @@ -419,7 +436,13 @@ static gpg_error_t my_ntbtls_verify_cb (void *opaque, ntbtls_t tls, unsigned int verify_flags) { http_t hd = opaque; + + (void)verify_flags; + log_assert (hd && hd->session && hd->session->verify_cb); + log_assert (hd->magic == HTTP_CONTEXT_MAGIC); + log_assert (hd->session->magic == HTTP_SESSION_MAGIC); + return hd->session->verify_cb (hd->session->verify_cb_value, hd, hd->session, (hd->flags | hd->session->flags), @@ -440,6 +463,7 @@ fp_onclose_notification (estream_t stream, void *opaque) { http_t hd = opaque; + log_assert (hd->magic == HTTP_CONTEXT_MAGIC); if (hd->fp_read && hd->fp_read == stream) hd->fp_read = NULL; else if (hd->fp_write && hd->fp_write == stream) @@ -599,6 +623,8 @@ session_unref (int lnr, http_session_t sess) if (!sess) return; + log_assert (sess->magic == HTTP_SESSION_MAGIC); + sess->refcount--; if (opt_debug > 1) log_debug ("http.c:%d:session_unref: sess %p ref now %d\n", @@ -610,6 +636,7 @@ session_unref (int lnr, http_session_t sess) close_tls_session (sess); #endif /*USE_TLS*/ + sess->magic = 0xdeadbeef; xfree (sess); } #define http_session_unref(a) session_unref (__LINE__, (a)) @@ -640,6 +667,7 @@ http_session_new (http_session_t *r_session, sess = xtrycalloc (1, sizeof *sess); if (!sess) return gpg_error_from_syserror (); + sess->magic = HTTP_SESSION_MAGIC; sess->refcount = 1; sess->flags = flags; sess->verify_cb = verify_cb; @@ -840,6 +868,7 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url, hd = xtrycalloc (1, sizeof *hd); if (!hd) return gpg_error_from_syserror (); + hd->magic = HTTP_CONTEXT_MAGIC; hd->req_type = reqtype; hd->flags = flags; hd->session = http_session_ref (session); @@ -892,6 +921,7 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port, hd = xtrycalloc (1, sizeof *hd); if (!hd) return gpg_error_from_syserror (); + hd->magic = HTTP_CONTEXT_MAGIC; hd->req_type = HTTP_REQ_OPAQUE; hd->flags = flags; @@ -1076,6 +1106,8 @@ http_close (http_t hd, int keep_read_stream) if (!hd) return; + log_assert (hd->magic == HTTP_CONTEXT_MAGIC); + /* First remove the close notifications for the streams. */ if (hd->fp_read) es_onclose (hd->fp_read, 0, fp_onclose_notification, hd); @@ -1089,6 +1121,7 @@ http_close (http_t hd, int keep_read_stream) if (hd->fp_write) es_fclose (hd->fp_write); http_session_unref (hd->session); + hd->magic = 0xdeadbeef; http_release_parsed_uri (hd->uri); while (hd->headers) { diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 37b3e53..c5bec89 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -134,7 +134,7 @@ my_http_tls_verify_cb (void *opaque, (void)opaque; (void)http; (void)session; - + (void)http_flags; /* Get the peer's certs fron ntbtls. */ for (idx = 0; ----------------------------------------------------------------------- Summary of changes: dirmngr/http.c | 33 +++++++++++++++++++++++++++++++++ dirmngr/t-http.c | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 11:07:54 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 11:07:54 +0100 Subject: [git] NTBTLS - branch, master, updated. 4e4d5a4c436ecf2d2ae96b61b2c0cfc177f585b7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via 4e4d5a4c436ecf2d2ae96b61b2c0cfc177f585b7 (commit) via 59b779b8c0f7bb22c48527f8ed8d1d28acc8bad3 (commit) from 19d9776ac40e7ff9fcfed7838ff8261ba8d61fac (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4e4d5a4c436ecf2d2ae96b61b2c0cfc177f585b7 Author: Werner Koch Date: Tue Feb 21 11:05:15 2017 +0100 New macro ntbtls_check_context. * src/ntbtls.h.in (ntbtls_check_context): New macro. * src/visibility.c (_ntbtls_check_context): New function. * src/libntbtls.def, src/libntbtls.vers: Add _ntbtls_check_context. * configure.ac (SIZEOF_UNSIGNED_LONG): Define. * src/context.h (NTBTLS_CONTEXT_MAGIC): New constant. (_ntbtls_context_s): New field 'magic'. * src/debug.c (_ntbtls_debug_bug): Always print a message. * src/protocol.c (_ntbtls_new): Set MAGIC. (_ntbtls_release): Test MAGIC. -- This macro allows to assert that a TLS context, which might have been conveyed using an opaque pointer, is valid. The function does not abort but merely logs and returns error. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index fec870a..6cb2bd5 100644 --- a/configure.ac +++ b/configure.ac @@ -316,6 +316,7 @@ AC_MSG_NOTICE([checking for system characteristics]) AC_C_CONST AC_C_INLINE AC_C_VOLATILE +AC_CHECK_SIZEOF(unsigned long) AC_TYPE_SIZE_T AC_TYPE_MODE_T AC_TYPE_SIGNAL diff --git a/src/context.h b/src/context.h index 61616bc..4934c6e 100644 --- a/src/context.h +++ b/src/context.h @@ -259,11 +259,20 @@ typedef struct _ntbtls_ticket_keys_s *ticket_keys_t; + +#if SIZEOF_UNSIGNED_LONG == 8 +# define NTBTLS_CONTEXT_MAGIC 0x6e7462746c736378 /* "ntbtlscx" */ +#else +# define NTBTLS_CONTEXT_MAGIC 0x6e746243 /* "ntbC" */ +#endif + /* * The TLS context object. */ struct _ntbtls_context_s { + unsigned long magic; + /* * Miscellaneous */ diff --git a/src/debug.c b/src/debug.c index d2b7c59..385953b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -110,13 +110,10 @@ _ntbtls_debug_bug (const char *file, int line) { const char *s; - if (!debug_level) - return; - s = strrchr (file, '/'); if (s) file = s + 1; - _ntbtls_debug_msg (0, "bug detected at %s:%d\n", file, line); + _ntbtls_debug_msg (-1, "bug detected at %s:%d\n", file, line); } diff --git a/src/libntbtls.def b/src/libntbtls.def index 69b3f1d..8526d10 100644 --- a/src/libntbtls.def +++ b/src/libntbtls.def @@ -41,4 +41,5 @@ EXPORTS ntbtls_x509_get_peer_cert @13 ntbtls_set_log_handler @14 ntbtls_get_hostname @15 + _ntbtls_check_context @16 ; END diff --git a/src/libntbtls.vers b/src/libntbtls.vers index 0359cec..fa0b175 100644 --- a/src/libntbtls.vers +++ b/src/libntbtls.vers @@ -26,6 +26,7 @@ NTBTLS_1.0 { ntbtls_set_log_handler; ntbtls_new; + _ntbtls_check_context; ntbtls_release; ntbtls_set_transport; ntbtls_get_stream; diff --git a/src/ntbtls.h.in b/src/ntbtls.h.in index 1d2486d..f628698 100644 --- a/src/ntbtls.h.in +++ b/src/ntbtls.h.in @@ -101,6 +101,10 @@ gpg_error_t ntbtls_new (ntbtls_t *r_tls, unsigned int flags); /* Destroy a TLS context. */ void ntbtls_release (ntbtls_t tls); +/* Check that TLS is not NULL and valid. (Use only the macro). */ +gpg_error_t _ntbtls_check_context (ntbtls_t tls, const char *file, int line); +#define ntbtls_check_context(t) _ntbtls_check_context ((t), __FILE__, __LINE__) + /* Create a new X509 certificate chain. */ gpg_error_t ntbtls_x509_cert_new (x509_cert_t *r_cert); diff --git a/src/protocol.c b/src/protocol.c index b5dbb51..a931cd0 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -2627,6 +2627,8 @@ _ntbtls_new (ntbtls_t *r_tls, unsigned int flags) if (!tls) return gpg_error_from_syserror (); /* Return immediately. */ + tls->magic = NTBTLS_CONTEXT_MAGIC; + tls->min_major_ver = TLS_MIN_MAJOR_VERSION; tls->min_minor_ver = TLS_MIN_MINOR_VERSION; tls->max_major_ver = TLS_MAX_MAJOR_VERSION; @@ -2719,6 +2721,8 @@ _ntbtls_release (ntbtls_t tls) return; debug_msg (2, "release"); + if (tls->magic != NTBTLS_CONTEXT_MAGIC) + debug_bug (); if (tls->out_ctr) { diff --git a/src/visibility.c b/src/visibility.c index 0ab8b4a..40cb3ee 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -52,6 +52,21 @@ ntbtls_new (ntbtls_t *r_tls, unsigned int flags) } +/* Check that TLS is valid. FILE and LINE are printed in case of a + * failure. Returns True on failure. This should be called using the + * corresponding macro. */ +gpg_error_t +_ntbtls_check_context (ntbtls_t tls, const char *file, int line) +{ + if (!tls || tls->magic != NTBTLS_CONTEXT_MAGIC) + { + _ntbtls_debug_bug (file, line); + return gpg_error (GPG_ERR_BUG); + } + return 0; +} + + void ntbtls_release (ntbtls_t tls) { diff --git a/src/visibility.h b/src/visibility.h index 249d9d2..8ac6c9e 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -45,6 +45,7 @@ MARK_VISIBLE (ntbtls_check_version) MARK_VISIBLE (ntbtls_set_debug) MARK_VISIBLE (ntbtls_set_log_handler) MARK_VISIBLE (ntbtls_new) +MARK_VISIBLE (_ntbtls_check_context) MARK_VISIBLE (ntbtls_release) MARK_VISIBLE (ntbtls_set_transport) MARK_VISIBLE (ntbtls_get_stream) commit 59b779b8c0f7bb22c48527f8ed8d1d28acc8bad3 Author: Werner Koch Date: Tue Feb 21 09:47:39 2017 +0100 New function ntbtls_get_hostname. * src/ntbtls.h.in (ntbtls_get_hostname): New. * src/protocol.c (_ntbtls_get_hostname): New. * src/visibility.c, src/visibility.h: Export ntbtls_get_hostname. * src/libntbtls.def, src/libntbtls.vers: Ditto. Signed-off-by: Werner Koch diff --git a/src/ciphersuites.c b/src/ciphersuites.c index a93c347..68c4108 100644 --- a/src/ciphersuites.c +++ b/src/ciphersuites.c @@ -1390,7 +1390,7 @@ _ntbtls_ciphersuite_get_sig_pk_alg (ciphersuite_t suite) return GCRY_PK_RSA; case KEY_EXCHANGE_ECDHE_ECDSA: - return GCRY_PK_ECC; /* Actuall ECDSA */ + return GCRY_PK_ECC; /* Actually ECDSA */ case KEY_EXCHANGE_ECDH_RSA: case KEY_EXCHANGE_ECDH_ECDSA: diff --git a/src/libntbtls.def b/src/libntbtls.def index 637de78..69b3f1d 100644 --- a/src/libntbtls.def +++ b/src/libntbtls.def @@ -40,4 +40,5 @@ EXPORTS ntbtls_x509_get_peer_cert @13 ntbtls_set_log_handler @14 + ntbtls_get_hostname @15 ; END diff --git a/src/libntbtls.vers b/src/libntbtls.vers index 47f3c69..0359cec 100644 --- a/src/libntbtls.vers +++ b/src/libntbtls.vers @@ -30,6 +30,7 @@ NTBTLS_1.0 { ntbtls_set_transport; ntbtls_get_stream; ntbtls_set_hostname; + ntbtls_get_hostname; ntbtls_handshake; diff --git a/src/ntbtls-int.h b/src/ntbtls-int.h index 7a17323..e12f592 100644 --- a/src/ntbtls-int.h +++ b/src/ntbtls-int.h @@ -330,6 +330,7 @@ gpg_error_t _ntbtls_set_verify_cb (ntbtls_t tls, ntbtls_verify_cb_t cb, void *cb_value); gpg_error_t _ntbtls_set_hostname (ntbtls_t tls, const char *hostname); +const char *_ntbtls_get_hostname (ntbtls_t tls); gpg_error_t _ntbtls_handshake (ntbtls_t tls); diff --git a/src/ntbtls.h.in b/src/ntbtls.h.in index b887b0a..1d2486d 100644 --- a/src/ntbtls.h.in +++ b/src/ntbtls.h.in @@ -129,6 +129,11 @@ gpg_error_t ntbtls_set_verify_cb (ntbtls_t tls, It is used for SNI, too. */ gpg_error_t ntbtls_set_hostname (ntbtls_t tls, const char *hostname); +/* Return the hostname which has been set with ntbtls_set_hostname. + * The returned value is valid as long as TLS is valid and + * ntbtls_set_hostname has not been used again. */ +const char *ntbtls_get_hostname (ntbtls_t tls); + /* Perform the handshake with the peer. The transport streams must be connected before starting this handshake. */ gpg_error_t ntbtls_handshake (ntbtls_t tls); diff --git a/src/protocol.c b/src/protocol.c index 4f3ee4a..b5dbb51 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -3254,6 +3254,16 @@ _ntbtls_set_hostname (ntbtls_t tls, const char *hostname) } +/* Return the hostname which has been set with ntbtls_set_hostname. + * The returned value is valid as long as TLS is valid and + * ntbtls_set_hostname has not been used again. */ +const char * +_ntbtls_get_hostname (ntbtls_t tls) +{ + return tls ? tls->hostname : NULL; +} + + /* void */ /* ssl_set_sni (ntbtls_t ssl, */ /* int (*f_sni) (void *, ntbtls_t, */ diff --git a/src/visibility.c b/src/visibility.c index 73f2452..0ab8b4a 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -82,6 +82,13 @@ ntbtls_set_hostname (ntbtls_t tls, const char *hostname) } +const char * +ntbtls_get_hostname (ntbtls_t tls) +{ + return _ntbtls_get_hostname (tls); +} + + gpg_error_t ntbtls_handshake (ntbtls_t tls) { diff --git a/src/visibility.h b/src/visibility.h index 7f6db83..249d9d2 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -49,6 +49,7 @@ MARK_VISIBLE (ntbtls_release) MARK_VISIBLE (ntbtls_set_transport) MARK_VISIBLE (ntbtls_get_stream) MARK_VISIBLE (ntbtls_set_hostname) +MARK_VISIBLE (ntbtls_get_hostname) MARK_VISIBLE (ntbtls_handshake) MARK_VISIBLE (ntbtls_set_verify_cb) @@ -74,6 +75,7 @@ MARK_VISIBLE (ntbtls_x509_get_peer_cert) #define ntbtls_set_transport _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_get_stream _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_set_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION +#define ntbtls_get_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_handshake _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_set_verify_cb _ntbtls_USE_THE_UNDERSCORED_FUNCTION ----------------------------------------------------------------------- Summary of changes: configure.ac | 1 + src/ciphersuites.c | 2 +- src/context.h | 9 +++++++++ src/debug.c | 5 +---- src/libntbtls.def | 2 ++ src/libntbtls.vers | 2 ++ src/ntbtls-int.h | 1 + src/ntbtls.h.in | 9 +++++++++ src/protocol.c | 14 ++++++++++++++ src/visibility.c | 22 ++++++++++++++++++++++ src/visibility.h | 3 +++ 11 files changed, 65 insertions(+), 5 deletions(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 12:46:23 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 12:46:23 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-113-g9741aa2 Message-ID: This is an 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 9741aa24d9056b56cd5366ff5379bd8a3e6118df (commit) via 50b9828eacc39c1ca75cb8313db896e4bdc8b270 (commit) via 493c142e582ff5ef1b5fdfcb9653715ef43e83e9 (commit) from 39c745038181edd097e188434b3f9c971ed3987f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9741aa24d9056b56cd5366ff5379bd8a3e6118df Author: Werner Koch Date: Tue Feb 21 12:41:43 2017 +0100 dirmngr: Load "sks-keyservers.netCA.pem" into the cache. * dirmngr/certcache.c (load_certs_from_file): Always build this function. Add args 'trustclasses' and 'no_error'. Pass TRUSTCLASSES to put_cert. (load_certs_from_system): Pass CERTTRUST_CLASS_SYSTEM to load_certs_from_file. (cert_cache_init): Try to load "sks-keyservers.netCA.pem". Don't make function fail in an out-of-core condition. Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 0e4071d..61be57e 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -352,7 +352,7 @@ put_cert (ksba_cert_t cert, int permanent, unsigned int trustclass, /* Load certificates from the directory DIRNAME. All certificates matching the pattern "*.crt" or "*.der" are loaded. We assume that - certificates are DER encoded and not PEM encapsulated. The cache + certificates are DER encoded and not PEM encapsulated. The cache should be in a locked state when calling this function. */ static gpg_error_t load_certs_from_dir (const char *dirname, unsigned int trustclass) @@ -443,14 +443,15 @@ load_certs_from_dir (const char *dirname, unsigned int trustclass) } -#ifndef HAVE_W32_SYSTEM -/* Load certificates from FILE. The certifciates are expected to be +/* Load certificates from FILE. The certificates are expected to be * PEM encoded so that it is possible to load several certificates. - * All certificates are considered to be system provided trusted - * certificates. The cache should be in a locked state when calling - * this function. */ + * TRUSTCLASSES is used to mark the certificates as trusted. The + * cache should be in a locked state when calling this function. + * NO_ERROR repalces an error message when FNAME was not found by an + * information message. */ static gpg_error_t -load_certs_from_file (const char *fname) +load_certs_from_file (const char *fname, unsigned int trustclasses, + int no_error) { gpg_error_t err; estream_t fp = NULL; @@ -462,7 +463,10 @@ load_certs_from_file (const char *fname) if (!fp) { err = gpg_error_from_syserror (); - log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); + if (gpg_err_code (err) == GPG_ERR_ENONET && no_error) + log_info (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); + else + log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); goto leave; } @@ -493,7 +497,7 @@ load_certs_from_file (const char *fname) goto leave; } - err = put_cert (cert, 1, CERTTRUST_CLASS_SYSTEM, NULL); + err = put_cert (cert, 1, trustclasses, NULL); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate '%s' already cached\n"), fname); else if (err) @@ -523,7 +527,7 @@ load_certs_from_file (const char *fname) return err; } -#endif /*!HAVE_W32_SYSTEM*/ + #ifdef HAVE_W32_SYSTEM /* Load all certificates from the Windows store named STORENAME. All @@ -671,7 +675,7 @@ load_certs_from_system (void) if (!access (table[idx].name, F_OK)) { /* Take the first available bundle. */ - err = load_certs_from_file (table[idx].name); + err = load_certs_from_file (table[idx].name, CERTTRUST_CLASS_SYSTEM, 0); break; } @@ -684,7 +688,7 @@ load_certs_from_system (void) void cert_cache_init (void) { - char *dname; + char *fname; if (initialization_done) return; @@ -693,13 +697,21 @@ cert_cache_init (void) load_certs_from_system (); - dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL); - load_certs_from_dir (dname, CERTTRUST_CLASS_CONFIG); - xfree (dname); + fname = make_filename_try (gnupg_sysconfdir (), "trusted-certs", NULL); + if (fname) + load_certs_from_dir (fname, CERTTRUST_CLASS_CONFIG); + xfree (fname); + + fname = make_filename_try (gnupg_sysconfdir (), "extra-certs", NULL); + if (fname) + load_certs_from_dir (fname, 0); + xfree (fname); - dname = make_filename (gnupg_sysconfdir (), "extra-certs", NULL); - load_certs_from_dir (dname, 0); - xfree (dname); + fname = make_filename_try (gnupg_datadir (), + "sks-keyservers.netCA.pem", NULL); + if (fname) + load_certs_from_file (fname, CERTTRUST_CLASS_HKPSPOOL, 1); + xfree (fname); initialization_done = 1; release_cache_lock (); commit 50b9828eacc39c1ca75cb8313db896e4bdc8b270 Author: Werner Koch Date: Tue Feb 21 12:23:20 2017 +0100 dirmngr: Implement trust classes for the cert cache. * dirmngr/certcache.h (CERTTRUST_CLASS_SYSTEM): New. (CERTTRUST_CLASS_CONFIG): New. (CERTTRUST_CLASS_HKP): New. (CERTTRUST_CLASS_HKPSPOOL): New. * dirmngr/certcache.c (MAX_EXTRA_CACHED_CERTS): Rename to ... (MAX_NONPERM_CACHED_CERTS): this. (total_extra_certificates): Rename to ... (total_nonperm_certificates): this. (total_config_certificates): Remove. (total_trusted_certificates): Remove. (total_system_trusted_certificates): Remove. (cert_item_s): Remove field 'flags'. Add fields 'permanent' and 'trustclasses'. (clean_cache_slot): Clear new fields. (put_cert): Change for new cert_item_t structure. (load_certs_from_dir): Rename arg 'are_trusted' to 'trustclass' (load_certs_from_file): Use CERTTRUST_CLASS_ value for put_cert. (load_certs_from_w32_store): Ditto. (cert_cache_init): Ditto. (cert_cache_print_stats): Rewrite. (is_trusted_cert): Replace arg 'with_systrust' by 'trustclasses'. Chnage the test. * dirmngr/validate.c (allowed_ca): Pass CERTTRUST_CLASS_CONFIG to is_trusted_cert. (validate_cert_chain): Pass CERTTRUST_CLASS_ values to is_trusted_cert. -- These trust classes make it easier to select certain sets of root certificates. Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index ff86f61..0e4071d 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -33,7 +33,7 @@ #include "crlfetch.h" #include "certcache.h" -#define MAX_EXTRA_CACHED_CERTS 1000 +#define MAX_NONPERM_CACHED_CERTS 1000 /* Constants used to classify search patterns. */ enum pattern_class @@ -66,15 +66,14 @@ struct cert_item_s char *issuer_dn; /* The malloced issuer DN. */ ksba_sexp_t sn; /* The malloced serial number */ char *subject_dn; /* The malloced subject DN - maybe NULL. */ - struct - { - unsigned int config:1; /* This has been loaded from the configuration. */ - unsigned int trusted:1; /* This is a trusted root certificate. */ - unsigned int systrust:1;/* The certifciate is trusted because it - * is in the system's store of trusted - * certificates (i.e. not configured using - * GnuPG mechanisms. */ - } flags; + + /* If this field is set the certificate has been taken from some + * configuration and shall not be flushed from the cache. */ + unsigned int permanent:1; + + /* If this field is set the certificate is trusted. The actual + * value is a (possible) combination of CERTTRUST_CLASS values. */ + unsigned int trustclasses:4; }; typedef struct cert_item_s *cert_item_t; @@ -92,13 +91,8 @@ static npth_rwlock_t cert_cache_lock; /* Flag to track whether the cache has been initialized. */ static int initialization_done; -/* Total number of certificates loaded during initialization - * (ie. configured), extra certificates cached during operation, - * number of trusted and system trusted certificates. */ -static unsigned int total_config_certificates; -static unsigned int total_extra_certificates; -static unsigned int total_trusted_certificates; -static unsigned int total_system_trusted_certificates; +/* Total number of non-permanent certificates. */ +static unsigned int total_nonperm_certificates; #ifdef HAVE_W32_SYSTEM @@ -245,6 +239,9 @@ clean_cache_slot (cert_item_t ci) cert = ci->cert; ci->cert = NULL; + ci->permanent = 0; + ci->trustclasses = 0; + ksba_cert_release (cert); } @@ -263,7 +260,8 @@ clean_cache_slot (cert_item_t ci) * will be stored on success or when the function returns * GPG_ERR_DUP_VALUE. */ static gpg_error_t -put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) +put_cert (ksba_cert_t cert, int permanent, unsigned int trustclass, + void *fpr_buffer) { unsigned char help_fpr_buffer[20], *fpr; cert_item_t ci; @@ -281,14 +279,14 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) * implementation is not very efficient but compared to the long * time it takes to retrieve a certificate from an external resource * it seems to be reasonable. */ - if (!from_config && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS) + if (!permanent && total_nonperm_certificates >= MAX_NONPERM_CACHED_CERTS) { static int idx; cert_item_t ci_mark; int i; unsigned int drop_count; - drop_count = MAX_EXTRA_CACHED_CERTS / 20; + drop_count = MAX_NONPERM_CACHED_CERTS / 20; if (drop_count < 2) drop_count = 2; @@ -298,17 +296,13 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) { ci_mark = NULL; for (ci = cert_cache[i]; ci; ci = ci->next) - if (ci->cert && !ci->flags.config) + if (ci->cert && !ci->permanent) ci_mark = ci; if (ci_mark) { clean_cache_slot (ci_mark); drop_count--; - total_extra_certificates--; - if (ci->flags.trusted) - total_trusted_certificates--; - if (ci->flags.systrust) - total_system_trusted_certificates--; + total_nonperm_certificates--; } } if (i==idx) @@ -334,8 +328,6 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) ci->next = cert_cache[*fpr]; cert_cache[*fpr] = ci; } - else - memset (&ci->flags, 0, sizeof ci->flags); ksba_cert_ref (cert); ci->cert = cert; @@ -348,19 +340,11 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) return gpg_error (GPG_ERR_INV_CERT_OBJ); } ci->subject_dn = ksba_cert_get_subject (cert, 0); - ci->flags.config = !!from_config; - ci->flags.trusted = !!is_trusted; - ci->flags.systrust = (is_trusted && is_trusted == 2); + ci->permanent = !!permanent; + ci->trustclasses = trustclass; - if (ci->flags.trusted) - total_trusted_certificates++; - if (ci->flags.systrust) - total_system_trusted_certificates++; - - if (from_config) - total_config_certificates++; - else - total_extra_certificates++; + if (!permanent) + total_nonperm_certificates++; return 0; } @@ -371,7 +355,7 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer) certificates are DER encoded and not PEM encapsulated. The cache should be in a locked state when calling this function. */ static gpg_error_t -load_certs_from_dir (const char *dirname, int are_trusted) +load_certs_from_dir (const char *dirname, unsigned int trustclass) { gpg_error_t err; DIR *dir; @@ -428,12 +412,12 @@ load_certs_from_dir (const char *dirname, int are_trusted) continue; } - err = put_cert (cert, 1, !!are_trusted, NULL); + err = put_cert (cert, 1, trustclass, NULL); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate '%s' already cached\n"), fname); else if (!err) { - if (are_trusted) + if (trustclass) log_info (_("trusted certificate '%s' loaded\n"), fname); else log_info (_("certificate '%s' loaded\n"), fname); @@ -509,7 +493,7 @@ load_certs_from_file (const char *fname) goto leave; } - err = put_cert (cert, 1, 2, NULL); + err = put_cert (cert, 1, CERTTRUST_CLASS_SYSTEM, NULL); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate '%s' already cached\n"), fname); else if (err) @@ -619,7 +603,7 @@ load_certs_from_w32_store (const char *storename) break; } - err = put_cert (cert, 1, 2, NULL); + err = put_cert (cert, 1, CERTTRUST_CLASS_SYSTEM, NULL); if (!err) count++; if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) @@ -710,7 +694,7 @@ cert_cache_init (void) load_certs_from_system (); dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL); - load_certs_from_dir (dname, 1); + load_certs_from_dir (dname, CERTTRUST_CLASS_CONFIG); xfree (dname); dname = make_filename (gnupg_sysconfdir (), "extra-certs", NULL); @@ -753,10 +737,7 @@ cert_cache_deinit (int full) } } - total_config_certificates = 0; - total_extra_certificates = 0; - total_trusted_certificates = 0; - total_system_trusted_certificates = 0; + total_nonperm_certificates = 0; initialization_done = 0; release_cache_lock (); } @@ -765,12 +746,51 @@ cert_cache_deinit (int full) void cert_cache_print_stats (void) { + cert_item_t ci; + int idx; + unsigned int n_nonperm = 0; + unsigned int n_permanent = 0; + unsigned int n_trusted = 0; + unsigned int n_trustclass_system = 0; + unsigned int n_trustclass_config = 0; + unsigned int n_trustclass_hkp = 0; + unsigned int n_trustclass_hkpspool = 0; + + acquire_cache_read_lock (); + for (idx = 0; idx < 256; idx++) + for (ci=cert_cache[idx]; ci; ci = ci->next) + if (ci->cert) + { + if (ci->permanent) + n_permanent++; + else + n_nonperm++; + if (ci->trustclasses) + { + n_trusted++; + if ((ci->trustclasses & CERTTRUST_CLASS_SYSTEM)) + n_trustclass_system++; + if ((ci->trustclasses & CERTTRUST_CLASS_CONFIG)) + n_trustclass_config++; + if ((ci->trustclasses & CERTTRUST_CLASS_HKP)) + n_trustclass_hkp++; + if ((ci->trustclasses & CERTTRUST_CLASS_HKPSPOOL)) + n_trustclass_hkpspool++; + } + } + + release_cache_lock (); + log_info (_("permanently loaded certificates: %u\n"), - total_config_certificates); + n_permanent); log_info (_(" runtime cached certificates: %u\n"), - total_extra_certificates); - log_info (_(" trusted certificates: %u (%u)\n"), - total_trusted_certificates, total_system_trusted_certificates); + n_nonperm); + log_info (_(" trusted certificates: %u (%u,%u,%u,%u)\n"), + n_trusted, + n_trustclass_system, + n_trustclass_config, + n_trustclass_hkp, + n_trustclass_hkpspool); } @@ -1543,12 +1563,12 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid) } -/* Return 0 if the certificate is a trusted certificate. Returns +/* Return 0 if the certificate is a trusted certificate. Returns * GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in - * case of systems errors. If WITH_SYSTRUST is set also system - * provided certificates are considered trusted. */ + * case of systems errors. TRUSTCLASSES are the bitwise ORed + * CERTTRUST_CLASS values to use for the check. */ gpg_error_t -is_trusted_cert (ksba_cert_t cert, int with_systrust) +is_trusted_cert (ksba_cert_t cert, unsigned int trustclasses) { unsigned char fpr[20]; cert_item_t ci; @@ -1559,8 +1579,10 @@ is_trusted_cert (ksba_cert_t cert, int with_systrust) for (ci=cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp (ci->fpr, fpr, 20)) { - if (ci->flags.trusted && (with_systrust || !ci->flags.systrust)) + if ((ci->trustclasses & trustclasses)) { + /* The certificate is trusted in one of the given + * TRUSTCLASSES. */ release_cache_lock (); return 0; /* Yes, it is trusted. */ } diff --git a/dirmngr/certcache.h b/dirmngr/certcache.h index 1f86706..fec2ff4 100644 --- a/dirmngr/certcache.h +++ b/dirmngr/certcache.h @@ -21,6 +21,15 @@ #ifndef CERTCACHE_H #define CERTCACHE_H +/* The origin of the trusted root certificates. */ +enum { + CERTTRUST_CLASS_SYSTEM = 1, /* From the system's list of trusted certs. */ + CERTTRUST_CLASS_CONFIG = 2, /* From dirmngr's config files. */ + CERTTRUST_CLASS_HKP = 4, /* From --hkp-cacert */ + CERTTRUST_CLASS_HKPSPOOL= 8, /* The one and only from sks-keyservers */ +}; + + /* First time initialization of the certificate cache. */ void cert_cache_init (void); @@ -42,9 +51,9 @@ gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer); /* Return 0 if the certificate is a trusted certificate. Returns * GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in - * case of systems errors. If WITH_SYSTRUST is set also system - * provided certificates are considered trusted. */ -gpg_error_t is_trusted_cert (ksba_cert_t cert, int with_systrust); + * case of systems errors. TRUSTCLASSES are the bitwise ORed + * CERTTRUST_CLASS values to use for the check. */ +gpg_error_t is_trusted_cert (ksba_cert_t cert, unsigned trustclasses); /* Return a certificate object for the given fingerprint. FPR is expected to be a 20 byte binary SHA-1 fingerprint. If no matching diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 1599a8d..5bd784f 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -203,7 +203,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen) return err; if (!flag) { - if (!is_trusted_cert (cert, 0)) + if (!is_trusted_cert (cert, CERTTRUST_CLASS_CONFIG)) { /* The German SigG Root CA's certificate does not flag itself as a CA; thus we relax this requirement if we @@ -540,8 +540,10 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (err) goto leave; /* No. */ - err = is_trusted_cert (subject_cert, - !!(flags & VALIDATE_FLAG_SYSTRUST)); + err = is_trusted_cert + (subject_cert, + (CERTTRUST_CLASS_CONFIG + | (flags & VALIDATE_FLAG_SYSTRUST)? CERTTRUST_CLASS_SYSTEM : 0)); if (!err) ; /* Yes we trust this cert. */ else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) commit 493c142e582ff5ef1b5fdfcb9653715ef43e83e9 Author: Werner Koch Date: Tue Feb 21 09:37:07 2017 +0100 dirmngr: New Assuan option "http-crl". * dirmngr/dirmngr.h (server_control_s): New flag 'http_no_crl'. * dirmngr/dirmngr.c (dirmngr_init_default_ctrl): Set this flag. * dirmngr/server.c (option_handler): New option "http-crl" * dirmngr/http.h (HTTP_FLAG_NO_CRL): New flag. * dirmngr/http-ntbtls.c (gnupg_http_tls_verify_cb): Consult this flag. * dirmngr/ks-engine-hkp.c (send_request): Set flag depending on CTRL. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/t-http.c (main): New option --no-crl. -- This new option can be used to enable CRL checks on a per session base. The default is not to use CRLs for https connections. Signed-off-by: Werner Koch diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 5e6d983..f04d088 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -1492,6 +1492,7 @@ dirmngr_init_default_ctrl (ctrl_t ctrl) ctrl->magic = SERVER_CONTROL_MAGIC; if (opt.http_proxy) ctrl->http_proxy = xstrdup (opt.http_proxy); + ctrl->http_no_crl = 1; } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 57e3372..b0b603f 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -190,6 +190,8 @@ struct server_control_s int audit_events; /* Send audit events to client. */ char *http_proxy; /* The used http_proxy or NULL. */ + + unsigned int http_no_crl:1; /* Do not check CRLs for https. */ }; diff --git a/dirmngr/http-ntbtls.c b/dirmngr/http-ntbtls.c index 5686877..3038cae 100644 --- a/dirmngr/http-ntbtls.c +++ b/dirmngr/http-ntbtls.c @@ -78,8 +78,8 @@ gnupg_http_tls_verify_cb (void *opaque, if ((http_flags & HTTP_FLAG_TRUST_SYS)) validate_flags |= VALIDATE_FLAG_SYSTRUST; - /* FIXME: For now we don't use CRLs. */ - validate_flags |= VALIDATE_FLAG_NOCRLCHECK; + if ((http_flags & HTTP_FLAG_NO_CRL)) + validate_flags |= VALIDATE_FLAG_NOCRLCHECK; err = validate_cert_chain (ctrl, hostcert, NULL, validate_flags, NULL); diff --git a/dirmngr/http.c b/dirmngr/http.c index 89e46ca..733018d 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -653,6 +653,7 @@ http_session_release (http_session_t sess) * Valid values for FLAGS are: * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system + * HTTP_FLAG_NO_CRL - Do not consult CRLs for https. */ gpg_error_t http_session_new (http_session_t *r_session, diff --git a/dirmngr/http.h b/dirmngr/http.h index 98ac4a3..331ee61 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -87,7 +87,8 @@ enum HTTP_FLAG_IGNORE_IPv4 = 64, /* Do not use IPv4. */ HTTP_FLAG_IGNORE_IPv6 = 128, /* Do not use IPv6. */ HTTP_FLAG_TRUST_DEF = 256, /* Use the default CAs. */ - HTTP_FLAG_TRUST_SYS = 512 /* Also use the system defined CAs. */ + HTTP_FLAG_TRUST_SYS = 512, /* Also use the system defined CAs. */ + HTTP_FLAG_NO_CRL = 1024 /* Do not consult CRLs for https. */ }; diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 4ca1e00..b6a0675 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1123,7 +1123,9 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, *r_fp = NULL; - err = http_session_new (&session, httphost, HTTP_FLAG_TRUST_DEF, + err = http_session_new (&session, httphost, + ((ctrl->http_no_crl? HTTP_FLAG_NO_CRL : 0) + | HTTP_FLAG_TRUST_DEF), gnupg_http_tls_verify_cb, ctrl); if (err) goto leave; diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 9352a0f..d4a6c8a 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -76,7 +76,9 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) once_more: /* Note that we only use the system provided certificates with the * fetch command. */ - err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_SYS, + err = http_session_new (&session, NULL, + ((ctrl->http_no_crl? HTTP_FLAG_NO_CRL : 0) + | HTTP_FLAG_TRUST_SYS), gnupg_http_tls_verify_cb, ctrl); if (err) goto leave; diff --git a/dirmngr/server.c b/dirmngr/server.c index 92bbc16..f726d1b 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -627,6 +627,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) if (dirmngr_use_tor ()) err = gpg_error (GPG_ERR_FORBIDDEN); } + else if (!strcmp (key, "http-crl")) + { + int i = *value? atoi (value) : 0; + ctrl->http_no_crl = !i; + } else err = gpg_error (GPG_ERR_UNKNOWN_OPTION); diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index c5bec89..68818de 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -199,6 +199,7 @@ main (int argc, char **argv) unsigned int my_http_flags = 0; int no_out = 0; int tls_dbg = 0; + int no_crl = 0; const char *cafile = NULL; http_session_t session = NULL; @@ -225,7 +226,8 @@ main (int argc, char **argv) " --no-verify do not verify the certificate\n" " --force-tls use HTTP_FLAG_FORCE_TLS\n" " --force-tor use HTTP_FLAG_FORCE_TOR\n" - " --no-out do not print the content\n", + " --no-out do not print the content\n" + " --no-crl do not consuilt a CRL\n", stdout); exit (0); } @@ -278,6 +280,11 @@ main (int argc, char **argv) no_out = 1; argc--; argv++; } + else if (!strcmp (*argv, "--no-crl")) + { + no_crl = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) { fprintf (stderr, PGM ": unknown option '%s'\n", *argv); @@ -298,7 +305,9 @@ main (int argc, char **argv) #if HTTP_USE_NTBTLS log_info ("new session.\n"); - err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_DEF, + err = http_session_new (&session, NULL, + ((no_crl? HTTP_FLAG_NO_CRL : 0) + | HTTP_FLAG_TRUST_DEF), my_http_tls_verify_cb, NULL); if (err) log_error ("http_session_new failed: %s\n", gpg_strerror (err)); @@ -313,7 +322,10 @@ main (int argc, char **argv) http_register_tls_callback (verify_callback); http_register_tls_ca (cafile); - err = http_session_new (&session, NULL, HTTP_FLAG_TRUST_DEF, NULL, NULL); + err = http_session_new (&session, NULL, + ((no_crl? HTTP_FLAG_NO_CRL : 0) + | HTTP_FLAG_TRUST_DEF), + NULL, NULL); if (err) log_error ("http_session_new failed: %s\n", gpg_strerror (err)); ----------------------------------------------------------------------- Summary of changes: dirmngr/certcache.c | 184 ++++++++++++++++++++++++++++------------------- dirmngr/certcache.h | 15 +++- dirmngr/dirmngr.c | 1 + dirmngr/dirmngr.h | 2 + dirmngr/http-ntbtls.c | 4 +- dirmngr/http.c | 1 + dirmngr/http.h | 3 +- dirmngr/ks-engine-hkp.c | 4 +- dirmngr/ks-engine-http.c | 4 +- dirmngr/server.c | 5 ++ dirmngr/t-http.c | 18 ++++- dirmngr/validate.c | 8 ++- 12 files changed, 160 insertions(+), 89 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 14:59:32 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 14:59:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-115-g831d014 Message-ID: This is an 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 831d014550863026dfefa774c961a21bd20c1e48 (commit) via d1625a9a82b1e5d96bbbf2132c49c53108565ae1 (commit) from 9741aa24d9056b56cd5366ff5379bd8a3e6118df (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 831d014550863026dfefa774c961a21bd20c1e48 Author: Werner Koch Date: Tue Feb 21 14:55:04 2017 +0100 dirmngr: Add special treatment for the standard hkps pool to ntbtls. * dirmngr/validate.h (VALIDATE_FLAG_SYSTRUST): Remove (VALIDATE_FLAG_EXTRATRUST): Remove (VALIDATE_FLAG_TRUST_SYSTEM): New. (VALIDATE_FLAG_TRUST_CONFIG): New. (VALIDATE_FLAG_TRUST_HKP): New. (VALIDATE_FLAG_TRUST_HKPSPOOL): New. (VALIDATE_FLAG_MASK_TRUST): New. * dirmngr/validate.c (check_header_constants): New. (validate_cert_chain): Call new function. Simplify call to is_trusted_cert. * dirmngr/crlcache.c (crl_parse_insert): Pass VALIDATE_FLAG_TRUST_CONFIG to validate_cert_chain * dirmngr/server.c (cmd_validate): Use VALDIATE_FLAG_TRUST_SYSTEM and VALIDATE_FLAG_TRUST_CONFIG. * dirmngr/http-ntbtls.c (gnupg_http_tls_verify_cb): Check provided TLS context. Set trustclass flags using the new VALIDATE_FLAG_TRUST values. * dirmngr/certcache.c (cert_cache_init): Load the standard pool certificate prior to the --hkp-cacerts. -- Note that this changes the way the standard cert is used: We require that it is installed at /usr/share/gnupg and we do not allow to change it. If this is not desired, the the standard cert can be removed or replaced by a newer one. Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 47eea25..c83b00e 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -709,16 +709,15 @@ cert_cache_init (strlist_t hkp_cacerts) load_certs_from_dir (fname, 0); xfree (fname); - for (sl = hkp_cacerts; sl; sl = sl->next) - load_certs_from_file (sl->d, CERTTRUST_CLASS_HKP, 0); - - fname = make_filename_try (gnupg_datadir (), "sks-keyservers.netCA.pem", NULL); if (fname) load_certs_from_file (fname, CERTTRUST_CLASS_HKPSPOOL, 1); xfree (fname); + for (sl = hkp_cacerts; sl; sl = sl->next) + load_certs_from_file (sl->d, CERTTRUST_CLASS_HKP, 0); + initialization_done = 1; release_cache_lock (); diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 3cd8cf4..c60d3fb 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -1851,7 +1851,8 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl, md = NULL; err = validate_cert_chain (ctrl, crlissuer_cert, NULL, - (VALIDATE_FLAG_CRL + (VALIDATE_FLAG_TRUST_CONFIG + | VALIDATE_FLAG_CRL | VALIDATE_FLAG_RECURSIVE), r_trust_anchor); if (err) diff --git a/dirmngr/http-ntbtls.c b/dirmngr/http-ntbtls.c index 3038cae..00d6a58 100644 --- a/dirmngr/http-ntbtls.c +++ b/dirmngr/http-ntbtls.c @@ -41,20 +41,23 @@ gnupg_http_tls_verify_cb (void *opaque, void *tls_context) { ctrl_t ctrl = opaque; + ntbtls_t tls = tls_context; gpg_error_t err; int idx; ksba_cert_t cert; ksba_cert_t hostcert = NULL; unsigned int validate_flags; + const char *hostname; (void)http; (void)session; log_assert (ctrl && ctrl->magic == SERVER_CONTROL_MAGIC); + log_assert (!ntbtls_check_context (tls)); /* Get the peer's certs fron ntbtls. */ for (idx = 0; - (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++) + (cert = ntbtls_x509_get_peer_cert (tls, idx)); idx++) { if (!idx) hostcert = cert; @@ -73,10 +76,22 @@ gnupg_http_tls_verify_cb (void *opaque, } validate_flags = VALIDATE_FLAG_TLS; - /* if ((http_flags & HTTP_FLAG_TRUST_DEF)) */ - /* validate_flags |= VALIDATE_FLAG_??; */ - if ((http_flags & HTTP_FLAG_TRUST_SYS)) - validate_flags |= VALIDATE_FLAG_SYSTRUST; + + /* Are we using the standard hkps:// pool use the dedicated + * root certificate. */ + hostname = ntbtls_get_hostname (tls); + if (hostname + && !ascii_strcasecmp (hostname, "hkps.pool.sks-keyservers.net")) + { + validate_flags |= VALIDATE_FLAG_TRUST_HKPSPOOL; + } + else /* Use the certificates as requested from the HTTP module. */ + { + if ((http_flags & HTTP_FLAG_TRUST_DEF)) + validate_flags |= VALIDATE_FLAG_TRUST_HKP; + if ((http_flags & HTTP_FLAG_TRUST_SYS)) + validate_flags |= VALIDATE_FLAG_TRUST_SYSTEM; + } if ((http_flags & HTTP_FLAG_NO_CRL)) validate_flags |= VALIDATE_FLAG_NOCRLCHECK; diff --git a/dirmngr/http.h b/dirmngr/http.h index 331ee61..2609b9e 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -86,7 +86,7 @@ enum HTTP_FLAG_IGNORE_CL = 32, /* Ignore content-length. */ HTTP_FLAG_IGNORE_IPv4 = 64, /* Do not use IPv4. */ HTTP_FLAG_IGNORE_IPv6 = 128, /* Do not use IPv6. */ - HTTP_FLAG_TRUST_DEF = 256, /* Use the default CAs. */ + HTTP_FLAG_TRUST_DEF = 256, /* Use the CAs configured for HKP. */ HTTP_FLAG_TRUST_SYS = 512, /* Also use the system defined CAs. */ HTTP_FLAG_NO_CRL = 1024 /* Do not consult CRLs for https. */ }; diff --git a/dirmngr/server.c b/dirmngr/server.c index f726d1b..961bba0 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1852,8 +1852,9 @@ cmd_validate (assuan_context_t ctx, char *line) } err = validate_cert_chain (ctrl, cert, NULL, - ((tls_mode ? VALIDATE_FLAG_TLS : 0) - | (systrust_mode ? VALIDATE_FLAG_SYSTRUST : 0) + (VALIDATE_FLAG_TRUST_CONFIG + | (tls_mode ? VALIDATE_FLAG_TLS : 0) + | (systrust_mode ? VALIDATE_FLAG_TRUST_SYSTEM : 0) | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)), NULL); diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 5bd784f..3671a8b 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -74,6 +74,29 @@ static const char oid_kp_ocspSigning[] = "1.3.6.1.5.5.7.3.9"; static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert); +/* Make sure that the values defined in the headers are correct. We + * can't use the preprocessor due to the use of enums. */ +static void +check_header_constants (void) +{ + log_assert (CERTTRUST_CLASS_SYSTEM == VALIDATE_FLAG_TRUST_SYSTEM); + log_assert (CERTTRUST_CLASS_CONFIG == VALIDATE_FLAG_TRUST_CONFIG); + log_assert (CERTTRUST_CLASS_HKP == VALIDATE_FLAG_TRUST_HKP); + log_assert (CERTTRUST_CLASS_HKPSPOOL == VALIDATE_FLAG_TRUST_HKPSPOOL); + +#undef X +#define X (VALIDATE_FLAG_TRUST_SYSTEM | VALIDATE_FLAG_TRUST_CONFIG \ + | VALIDATE_FLAG_TRUST_HKP | VALIDATE_FLAG_TRUST_HKPSPOOL) + +#if ( X & VALIDATE_FLAG_MASK_TRUST ) != X +# error VALIDATE_FLAG_MASK_TRUST is bad +#endif +#if ( ~X & VALIDATE_FLAG_MASK_TRUST ) +# error VALIDATE_FLAG_MASK_TRUST is bad +#endif + +#undef X +} /* Check whether CERT contains critical extensions we don't know @@ -393,6 +416,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, int any_no_policy_match = 0; chain_item_t chain; + check_header_constants (); if (r_exptime) *r_exptime = 0; @@ -540,10 +564,8 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, if (err) goto leave; /* No. */ - err = is_trusted_cert - (subject_cert, - (CERTTRUST_CLASS_CONFIG - | (flags & VALIDATE_FLAG_SYSTRUST)? CERTTRUST_CLASS_SYSTEM : 0)); + err = is_trusted_cert (subject_cert, + (flags & VALIDATE_FLAG_MASK_TRUST)); if (!err) ; /* Yes we trust this cert. */ else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) diff --git a/dirmngr/validate.h b/dirmngr/validate.h index b6222b5..c7082e3 100644 --- a/dirmngr/validate.h +++ b/dirmngr/validate.h @@ -22,28 +22,30 @@ #define VALIDATE_H -/* Make use of the system provided root certificates. */ -#define VALIDATE_FLAG_SYSTRUST 1 - -/* Make use of extra provided root certificates. */ -#define VALIDATE_FLAG_EXTRATRUST 2 +/* Flag values matching the CERTTRUST_CLASS values and a MASK for + * them. check_header_constants() checks their consistency. */ +#define VALIDATE_FLAG_TRUST_SYSTEM 1 +#define VALIDATE_FLAG_TRUST_CONFIG 2 +#define VALIDATE_FLAG_TRUST_HKP 4 +#define VALIDATE_FLAG_TRUST_HKPSPOOL 8 +#define VALIDATE_FLAG_MASK_TRUST 0x0f /* Standard CRL issuer certificate validation; i.e. CRLs are not * considered for CRL issuer certificates. */ -#define VALIDATE_FLAG_CRL 4 +#define VALIDATE_FLAG_CRL 64 /* If this flag is set along with VALIDATE_FLAG_CRL a full CRL * verification is done. */ -#define VALIDATE_FLAG_RECURSIVE 8 +#define VALIDATE_FLAG_RECURSIVE 128 /* Validation mode as used for OCSP. */ -#define VALIDATE_FLAG_OCSP 16 +#define VALIDATE_FLAG_OCSP 256 /* Validation mode as used with TLS. */ -#define VALIDATE_FLAG_TLS 32 +#define VALIDATE_FLAG_TLS 512 /* Don't do CRL checks. */ -#define VALIDATE_FLAG_NOCRLCHECK 64 +#define VALIDATE_FLAG_NOCRLCHECK 1024 /* Validate the certificate CHAIN up to the trust anchor. Optionally commit d1625a9a82b1e5d96bbbf2132c49c53108565ae1 Author: Werner Koch Date: Tue Feb 21 13:57:24 2017 +0100 dirmngr: Load --hkp-cacert values into the certificate cache. * dirmngr/dirmngr.c (hkp_cacert_filenames): New var. (parse_rereadable_options): Store filenames from --hkp-cacert in the new var. (main, dirmngr_sighup_action): Pass that var to cert_cache_init. * dirmngr/certcache.c (cert_cache_init): Add arg 'hkp_cacert' and load those certs. (load_certs_from_file): Use autodetect so that PEM and DER encodings are possible. Signed-off-by: Werner Koch diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 61be57e..47eea25 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -471,7 +471,8 @@ load_certs_from_file (const char *fname, unsigned int trustclasses, } err = gnupg_ksba_create_reader (&ioctx, - (GNUPG_KSBA_IO_PEM | GNUPG_KSBA_IO_MULTIPEM), + (GNUPG_KSBA_IO_AUTODETECT + | GNUPG_KSBA_IO_MULTIPEM), fp, &reader); if (err) { @@ -686,9 +687,10 @@ load_certs_from_system (void) /* Initialize the certificate cache if not yet done. */ void -cert_cache_init (void) +cert_cache_init (strlist_t hkp_cacerts) { char *fname; + strlist_t sl; if (initialization_done) return; @@ -707,6 +709,10 @@ cert_cache_init (void) load_certs_from_dir (fname, 0); xfree (fname); + for (sl = hkp_cacerts; sl; sl = sl->next) + load_certs_from_file (sl->d, CERTTRUST_CLASS_HKP, 0); + + fname = make_filename_try (gnupg_datadir (), "sks-keyservers.netCA.pem", NULL); if (fname) diff --git a/dirmngr/certcache.h b/dirmngr/certcache.h index fec2ff4..92529bf 100644 --- a/dirmngr/certcache.h +++ b/dirmngr/certcache.h @@ -31,7 +31,7 @@ enum { /* First time initialization of the certificate cache. */ -void cert_cache_init (void); +void cert_cache_init (strlist_t hkp_cacerts); /* Deinitialize the certificate cache. */ void cert_cache_deinit (int full); diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index f04d088..6b4cbcf 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -319,6 +319,10 @@ static int active_connections; * thread to run background network tasks. */ static int network_activity_seen; +/* A list of filenames registred with --hkp-cacert. */ +static strlist_t hkp_cacert_filenames; + + /* The timer tick used for housekeeping stuff. */ #define TIMERTICK_INTERVAL (60) @@ -586,6 +590,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) } FREE_STRLIST (opt.ignored_cert_extensions); http_register_tls_ca (NULL); + FREE_STRLIST (hkp_cacert_filenames); FREE_STRLIST (opt.keyserver); /* Note: We do not allow resetting of TOR_MODE_FORCE at runtime. */ if (tor_mode != TOR_MODE_FORCE) @@ -653,11 +658,14 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oHkpCaCert: { + /* We need to register the filenames with gnutls (http.c) and + * also for our own cert cache. */ char *tmpname; /* Do tilde expansion and make path absolute. */ tmpname = make_absfilename (pargs->r.ret_str, NULL); http_register_tls_ca (tmpname); + add_to_strlist (&hkp_cacert_filenames, pargs->r.ret_str); xfree (tmpname); } break; @@ -1069,7 +1077,7 @@ main (int argc, char **argv) thread_init (); - cert_cache_init (); + cert_cache_init (hkp_cacert_filenames); crl_cache_init (); http_register_netactivity_cb (netactivity_action); start_command_handler (ASSUAN_INVALID_FD); @@ -1104,7 +1112,7 @@ main (int argc, char **argv) log_set_prefix (NULL, 0); thread_init (); - cert_cache_init (); + cert_cache_init (hkp_cacert_filenames); crl_cache_init (); http_register_netactivity_cb (netactivity_action); handle_connections (3); @@ -1311,7 +1319,7 @@ main (int argc, char **argv) #endif thread_init (); - cert_cache_init (); + cert_cache_init (hkp_cacert_filenames); crl_cache_init (); http_register_netactivity_cb (netactivity_action); handle_connections (fd); @@ -1333,7 +1341,7 @@ main (int argc, char **argv) dirmngr_init_default_ctrl (&ctrlbuf); thread_init (); - cert_cache_init (); + cert_cache_init (hkp_cacert_filenames); crl_cache_init (); if (!argc) rc = crl_cache_load (&ctrlbuf, NULL); @@ -1356,7 +1364,7 @@ main (int argc, char **argv) dirmngr_init_default_ctrl (&ctrlbuf); thread_init (); - cert_cache_init (); + cert_cache_init (hkp_cacert_filenames); crl_cache_init (); rc = crl_fetch (&ctrlbuf, argv[0], &reader); if (rc) @@ -1769,7 +1777,7 @@ dirmngr_sighup_action (void) reread_configuration (); cert_cache_deinit (0); crl_cache_deinit (); - cert_cache_init (); + cert_cache_init (hkp_cacert_filenames); crl_cache_init (); reload_dns_stuff (0); ks_hkp_reload (); ----------------------------------------------------------------------- Summary of changes: dirmngr/certcache.c | 9 +++++++-- dirmngr/certcache.h | 2 +- dirmngr/crlcache.c | 3 ++- dirmngr/dirmngr.c | 20 ++++++++++++++------ dirmngr/http-ntbtls.c | 25 ++++++++++++++++++++----- dirmngr/http.h | 2 +- dirmngr/server.c | 5 +++-- dirmngr/validate.c | 30 ++++++++++++++++++++++++++---- dirmngr/validate.h | 22 ++++++++++++---------- 9 files changed, 86 insertions(+), 32 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 15:28:03 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 15:28:03 +0100 Subject: [git] NTBTLS - branch, master, updated. d7a441e28bd0962030d4bb00f626f56d46315a78 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via d7a441e28bd0962030d4bb00f626f56d46315a78 (commit) via 8a3e8a9948d7545238d5d0fd54eed43c7c0fb174 (commit) from 4e4d5a4c436ecf2d2ae96b61b2c0cfc177f585b7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d7a441e28bd0962030d4bb00f626f56d46315a78 Author: Werner Koch Date: Tue Feb 21 15:24:08 2017 +0100 Allow building for W32 -- Signed-off-by: Werner Koch diff --git a/autogen.rc b/autogen.rc index 1d98c70..a159fb8 100644 --- a/autogen.rc +++ b/autogen.rc @@ -1,23 +1,23 @@ # autogen.sh configuration for GnuPG -*- sh -*- -#version_parts=3 +ersion_parts=3 -# case "$myhost:$myhostsub" in -# w32:) -# extraoptions="" -# ;; -# esac +case "$myhost:$myhostsub" in + w32:) + extraoptions="" + ;; +esac -# case "$myhost" in -# w32) -# configure_opts=" -# --with-gpg-error-prefix=@SYSROOT@ -# --with-ksba-prefix=@SYSROOT@ -# --with-libgcrypt-prefix=@SYSROOT@ -# --with-zlib=@SYSROOT@ -# " -# ;; -# esac +case "$myhost" in + w32) + configure_opts=" + --with-gpg-error-prefix=@SYSROOT@ + --with-ksba-prefix=@SYSROOT@ + --with-libgcrypt-prefix=@SYSROOT@ + --with-zlib=@SYSROOT@ + " + ;; +esac extra_aclocal_flags= commit 8a3e8a9948d7545238d5d0fd54eed43c7c0fb174 Author: Werner Koch Date: Tue Feb 21 15:09:21 2017 +0100 Remove now superfluous functions from the public API. * src/visibility.c (ntbtls_x509_cert_new): Remove (ntbtls_x509_cert_release): Remove. (ntbtls_x509_append_cert): Remove. Signed-off-by: Werner Koch diff --git a/AUTHORS b/AUTHORS index 61d4d02..2abffc3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,9 +1,9 @@ Library: NTBTLS Homepage: https://gnupg.org/related_software/ntbtls/ -Download: ftp://ftp.gnupg.org/gcrypt/ntbtls/ +Download: https://gnupg.org/ftp/gcrypt/ntbtls/ Repository: git://git.gnupg.org/ntbtls.git Maintainer: Werner Koch -Bug reports: http://bugs.gnupg.org +Bug reports: https://bugs.gnupg.org Security related bug reports: License: GPLv3+ @@ -17,14 +17,14 @@ List of Copyright holders ========================= Copyright (C) 2006-2014 Brainspark B.V. - Copyright (C) 2014-2015 g10 Code GmbH + Copyright (C) 2014-2017 g10 Code GmbH Authors ================== Werner Koch (g10 Code GmbH) -2014-10-01::Initial work +NIIBE Yutaka diff --git a/NEWS b/NEWS index 17027a1..f760120 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ Noteworthy changes in version 0.1.0 (unreleased) [C0/A0/R0] ------------------------------------------------ - * Initial beta release + * Initial experimental release with only the client code. See the file AUTHORS for copying conditions. diff --git a/configure.ac b/configure.ac index 6cb2bd5..cfd8905 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # configure.ac - for the Not Too Bad TLS library -# Copyright (C) 2014 g10 Code GmbH +# Copyright (C) 2014-2017 g10 Code GmbH # # This file is part of NTBTLS # diff --git a/src/context.h b/src/context.h index 4934c6e..aac3017 100644 --- a/src/context.h +++ b/src/context.h @@ -94,6 +94,20 @@ typedef enum /* + * Object to hold X.509 certificates. + */ +struct x509_cert_s; +typedef struct x509_cert_s *x509_cert_t; + + +/* + * Object to hold an X.509 CRL. + */ +struct x509_crl_s; +typedef struct x509_crl_s *x509_crl_t; + + +/* * Object to hold an X.509 private key. */ struct x509_privkey_s; diff --git a/src/libntbtls.def b/src/libntbtls.def index 8526d10..fe6e0fd 100644 --- a/src/libntbtls.def +++ b/src/libntbtls.def @@ -23,23 +23,20 @@ EXPORTS ntbtls_check_version @1 ntbtls_set_debug @2 + ntbtls_set_log_handler @3 - ntbtls_new @3 - ntbtls_release @4 - ntbtls_set_transport @5 - ntbtls_get_stream @6 - ntbtls_set_hostname @7 + ntbtls_new @4 + _ntbtls_check_context @5 + ntbtls_release @6 - ntbtls_handshake @8 + ntbtls_set_transport @7 + ntbtls_get_stream @8 + ntbtls_set_hostname @9 + ntbtls_get_hostname @10 + ntbtls_set_verify_cb @11 - ntbtls_set_verify_cb @9 - - ntbtls_x509_cert_new @10 - ntbtls_x509_cert_release @11 - ntbtls_x509_append_cert @12 + ntbtls_handshake @12 ntbtls_x509_get_peer_cert @13 - ntbtls_set_log_handler @14 - ntbtls_get_hostname @15 - _ntbtls_check_context @16 + ; END diff --git a/src/libntbtls.vers b/src/libntbtls.vers index fa0b175..48d7662 100644 --- a/src/libntbtls.vers +++ b/src/libntbtls.vers @@ -28,18 +28,15 @@ NTBTLS_1.0 { ntbtls_new; _ntbtls_check_context; ntbtls_release; + ntbtls_set_transport; ntbtls_get_stream; ntbtls_set_hostname; ntbtls_get_hostname; + ntbtls_set_verify_cb; ntbtls_handshake; - ntbtls_set_verify_cb; - - ntbtls_x509_cert_new; - ntbtls_x509_cert_release; - ntbtls_x509_append_cert; ntbtls_x509_get_peer_cert; local: diff --git a/src/ntbtls.h.in b/src/ntbtls.h.in index f628698..6262cfb 100644 --- a/src/ntbtls.h.in +++ b/src/ntbtls.h.in @@ -1,5 +1,5 @@ /* ntbtls.h - Not Too Bad TLS -*- c -*- - * Copyright (C) 2014 g10 Code GmbH + * Copyright (C) 2014, 2017 g10 Code GmbH * * This file is part of NTBTLS * @@ -55,18 +55,6 @@ struct _ntbtls_context_s; typedef struct _ntbtls_context_s *ntbtls_t; /* - * Object to hold X.509 certificates. - */ -struct x509_cert_s; -typedef struct x509_cert_s *x509_cert_t; - -/* - * Object to hold an X.509 CRL. - */ -struct x509_crl_s; -typedef struct x509_crl_s *x509_crl_t; - -/* * The type of the verification callback. This must be registered * prior to the handshake and will be called by ntbltls when a peer's * certificate needs to be verified. OPAQUE is the vale set when the @@ -105,16 +93,6 @@ void ntbtls_release (ntbtls_t tls); gpg_error_t _ntbtls_check_context (ntbtls_t tls, const char *file, int line); #define ntbtls_check_context(t) _ntbtls_check_context ((t), __FILE__, __LINE__) -/* Create a new X509 certificate chain. */ -gpg_error_t ntbtls_x509_cert_new (x509_cert_t *r_cert); - -/* Destroy a X509 certificate chain. */ -void ntbtls_x509_cert_release (x509_cert_t cert); - -/* Parse a single DER formatted certificate and add it to the chained list. */ -gpg_error_t ntbtls_x509_append_cert (x509_cert_t cert, const void *der, - size_t derlen); - /* Setup the transport streams (usually connected to one socket). */ gpg_error_t ntbtls_set_transport (ntbtls_t tls, gpgrt_stream_t inbound, diff --git a/src/protocol.c b/src/protocol.c index a931cd0..f736894 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,6 +1,6 @@ /* protocol.c - TLS 1.2 protocol implementation * Copyright (C) 2006-2014, Brainspark B.V. - * Copyright (C) 2014 g10 code GmbH + * Copyright (C) 2014, 2017 g10 code GmbH * * This file is part of NTBTLS * diff --git a/src/util.h b/src/util.h index 98a8392..4f37f3b 100644 --- a/src/util.h +++ b/src/util.h @@ -58,6 +58,10 @@ #define OID_SIZE(x) (sizeof(x) - 1) +struct x509_cert_s; +typedef struct x509_cert_s *x509_cert_t; + + /* Constant-time compare of two buffers. Returns 0 if buffers are equal, and 1 if buffers differ. At most places this function can be used as a memcmp replacement. However, -1 will never be diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index afbbe02..5fccc83 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -39,7 +39,7 @@ BEGIN VALUE "FileDescription", "ntbtls - Not Too Bad Transport Layer Security\0" VALUE "FileVersion", "@LIBNTBTLS_LT_CURRENT at .@LIBNTBTLS_LT_AGE at .@LIBNTBTLS_LT_REVISION at .@BUILD_REVISION@\0" VALUE "InternalName", "libntbtls\0" - VALUE "LegalCopyright", "Copyright ? 2006-2014 Brainspark B.V., Copyright ? 2014-2015 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright ? 2006-2014 Brainspark B.V., Copyright ? 2014-2017 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libntbtls.dll\0" VALUE "PrivateBuild", "\0" diff --git a/src/visibility.c b/src/visibility.c index 40cb3ee..7f0e50e 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -117,27 +117,6 @@ ntbtls_set_verify_cb (ntbtls_t tls, ntbtls_verify_cb_t cb, void *cb_value) return _ntbtls_set_verify_cb (tls, cb, cb_value); } - -gpg_error_t -ntbtls_x509_cert_new (x509_cert_t *r_cert) -{ - return _ntbtls_x509_cert_new (r_cert); -} - - -void -ntbtls_x509_cert_release (x509_cert_t cert) -{ - _ntbtls_x509_cert_release (cert); -} - - -gpg_error_t -ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen) -{ - return _ntbtls_x509_append_cert (cert, der, derlen); -} - ksba_cert_t ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx) { diff --git a/src/visibility.h b/src/visibility.h index 8ac6c9e..d411126 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -52,12 +52,7 @@ MARK_VISIBLE (ntbtls_get_stream) MARK_VISIBLE (ntbtls_set_hostname) MARK_VISIBLE (ntbtls_get_hostname) MARK_VISIBLE (ntbtls_handshake) - MARK_VISIBLE (ntbtls_set_verify_cb) - -MARK_VISIBLE (ntbtls_x509_cert_new) -MARK_VISIBLE (ntbtls_x509_cert_release) -MARK_VISIBLE (ntbtls_x509_append_cert) MARK_VISIBLE (ntbtls_x509_get_peer_cert) @@ -78,11 +73,7 @@ MARK_VISIBLE (ntbtls_x509_get_peer_cert) #define ntbtls_set_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_get_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_handshake _ntbtls_USE_THE_UNDERSCORED_FUNCTION - #define ntbtls_set_verify_cb _ntbtls_USE_THE_UNDERSCORED_FUNCTION -#define ntbtls_x509_cert_new _ntbtls_USE_THE_UNDERSCORED_FUNCTION -#define ntbtls_x509_cert_release _ntbtls_USE_THE_UNDERSCORED_FUNCTION -#define ntbtls_x509_append_cert _ntbtls_USE_THE_UNDERSCORED_FUNCTION #define ntbtls_x509_get_peer_cert _ntbtls_USE_THE_UNDERSCORED_FUNCTION #endif /*!_NTBTLS_INCLUDED_BY_VISIBILITY_C*/ diff --git a/src/x509.c b/src/x509.c index f948b9c..6e7b967 100644 --- a/src/x509.c +++ b/src/x509.c @@ -1,5 +1,5 @@ /* x509.c - X.509 functions - * Copyright (C) 2001-2010, 2014-2015 g10 Code GmbH + * Copyright (C) 2001-2010, 2014-2015, 2017 g10 Code GmbH * * This file is part of NTBTLS * ----------------------------------------------------------------------- Summary of changes: AUTHORS | 8 ++++---- NEWS | 2 +- autogen.rc | 32 ++++++++++++++++---------------- configure.ac | 2 +- src/context.h | 14 ++++++++++++++ src/libntbtls.def | 25 +++++++++++-------------- src/libntbtls.vers | 7 ++----- src/ntbtls.h.in | 24 +----------------------- src/protocol.c | 2 +- src/util.h | 4 ++++ src/versioninfo.rc.in | 2 +- src/visibility.c | 21 --------------------- src/visibility.h | 9 --------- src/x509.c | 2 +- 14 files changed, 57 insertions(+), 97 deletions(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 19:12:10 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 21 Feb 2017 19:12:10 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-117-gccb4203 Message-ID: This is an 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 ccb420380b2f23f1bd28b17e6a4233c86291887d (commit) via 24cf0606b43038c7ce5e9c6ccb921895619c04f0 (commit) from 831d014550863026dfefa774c961a21bd20c1e48 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ccb420380b2f23f1bd28b17e6a4233c86291887d Author: Daniel Kahn Gillmor Date: Mon Feb 20 16:25:15 2017 -0500 Fix spelling. -- Clean up several other misspellings noticed while reviewing Yuri's de-duplication patch. Signed-off-by: Daniel Kahn Gillmor diff --git a/agent/call-scd.c b/agent/call-scd.c index 33a08a9..8d46b90 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -50,13 +50,13 @@ /* Definition of module local data of the CTRL structure. */ struct scd_local_s { - /* We keep a list of all allocated context with an achnor at + /* We keep a list of all allocated context with an anchor at SCD_LOCAL_LIST (see below). */ struct scd_local_s *next_local; /* We need to get back to the ctrl object actually referencing this - structure. This is really an awkward way of enumerint the lcoal - contects. A much cleaner way would be to keep a global list of + structure. This is really an awkward way of enumerating the local + contexts. A much cleaner way would be to keep a global list of ctrl objects to enumerate them. */ ctrl_t ctrl_backlink; diff --git a/dirmngr/ChangeLog-2011 b/dirmngr/ChangeLog-2011 index a793a33..243f2b5 100644 --- a/dirmngr/ChangeLog-2011 +++ b/dirmngr/ChangeLog-2011 @@ -1497,7 +1497,7 @@ * dirmngr-client.c (inq_cert): Ignore "SENDCERT" and "SENDISSUERCERT". - * server.c (do_get_cert_local): Limit the length of a retruned + * server.c (do_get_cert_local): Limit the length of a returned certificate. Return NULL without an error if an empry value has been received. @@ -1897,7 +1897,7 @@ corrupted CRL files. (open_dir): Read the new dbfile hash field. - * src/crlfetch.c (crl_fetch, crl_fetch_default): Changed to retrun + * src/crlfetch.c (crl_fetch, crl_fetch_default): Changed to return a stream. (fun_reader, fun_closer, setup_funopen): New. * src/server.c (inquire_cert): Changed to use the new stream interface diff --git a/g10/trustdb.c b/g10/trustdb.c index 103f83e..5f68012 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -222,7 +222,7 @@ tdb_register_trusted_key( const char *string ) /* * Helper to add a key to the global list of ultimately trusted keys. - * Retruns: true = inserted, false = already in list. + * Returns: true = inserted, false = already in list. */ static int add_utk (u32 *kid) diff --git a/g13/server.c b/g13/server.c index 0c4563e..e3cb313 100644 --- a/g13/server.c +++ b/g13/server.c @@ -44,7 +44,7 @@ static FILE *statusfp; the CTRL object of each connection. */ struct server_local_s { - /* The Assuan contect we are working on. */ + /* The Assuan context we are working on. */ assuan_context_t assuan_ctx; char *containername; /* Malloced active containername. */ diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index a54f0ae..523ec56 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -35,7 +35,7 @@ the CTRL object of each connection. */ struct server_local_s { - /* The Assuan contect we are working on. */ + /* The Assuan context we are working on. */ assuan_context_t assuan_ctx; /* The malloced name of the device. */ diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index 8c9c4d4..b122097 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -463,7 +463,7 @@ show_event (rfc822parse_event_t event) /* This function is called by the parser to communicate events. This callback comminucates with the main program using a structure - passed in OPAQUE. Should retrun 0 or set errno and return -1. */ + passed in OPAQUE. Should return 0 or set errno and return -1. */ static int message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) { commit 24cf0606b43038c7ce5e9c6ccb921895619c04f0 Author: Yuri Chornoivan Date: Mon Feb 20 16:19:50 2017 -0500 Clean up word replication. -- This fixes extra word repetitions (like "the the" or "is is") in the code and docs. Signed-off-by: Daniel Kahn Gillmor diff --git a/agent/call-scd.c b/agent/call-scd.c index 71e0f58..33a08a9 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -50,7 +50,7 @@ /* Definition of module local data of the CTRL structure. */ struct scd_local_s { - /* We keep a list of all allocated context with a an achnor at + /* We keep a list of all allocated context with an achnor at SCD_LOCAL_LIST (see below). */ struct scd_local_s *next_local; diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 7298700..79b8f85 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2721,7 +2721,7 @@ data_hash (unsigned char *data, size_t data_n, } -/* This function signs the data described by CTRL. If HASH is is not +/* This function signs the data described by CTRL. If HASH is not NULL, (HASH,HASHLEN) overrides the hash stored in CTRL. This is to allow the use of signature algorithms that implement the hashing internally (e.g. Ed25519). On success the created signature is @@ -3654,7 +3654,7 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) #ifdef HAVE_W32_SYSTEM /* Serve one ssh-agent request. This is used for the Putty support. - REQUEST is the the mmapped memory which may be accessed up to a + REQUEST is the mmapped memory which may be accessed up to a length of MAXREQLEN. Returns 0 on success which also indicates that a valid SSH response message is now in REQUEST. */ int @@ -3749,7 +3749,7 @@ serve_mmapped_ssh_request (ctrl_t ctrl, size_t response_size; /* NB: In contrast to the request-stream, the response stream - includes the the message type byte. */ + includes the message type byte. */ if (es_fclose_snatch (response_stream, &response_data, &response_size)) { log_error ("snatching ssh response failed: %s", diff --git a/agent/command.c b/agent/command.c index c8b34e9..ec38649 100644 --- a/agent/command.c +++ b/agent/command.c @@ -434,7 +434,7 @@ leave_cmd (assuan_context_t ctx, gpg_error_t err) static const char hlp_geteventcounter[] = "GETEVENTCOUNTER\n" "\n" - "Return a a status line named EVENTCOUNTER with the current values\n" + "Return a status line named EVENTCOUNTER with the current values\n" "of all event counters. The values are decimal numbers in the range\n" "0 to UINT_MAX and wrapping around to 0. The actual values should\n" "not be relied upon, they shall only be used to detect a change.\n" @@ -2007,7 +2007,7 @@ static const char hlp_keywrap_key[] = "KEYWRAP_KEY [--clear] \n" "\n" "Return a key to wrap another key. For now the key is returned\n" - "verbatim and and thus makes not much sense because an eavesdropper on\n" + "verbatim and thus makes not much sense because an eavesdropper on\n" "the gpg-agent connection will see the key as well as the wrapped key.\n" "However, this function may either be equipped with a public key\n" "mechanism or not used at all if the key is a pre-shared key. In any\n" @@ -2631,7 +2631,7 @@ static const char hlp_putval[] = "try to connect to that daemon. Only if that fails they may start\n" "an own instance of the service daemon. \n" "\n" - "KEY is an an arbitrary symbol with the same syntax rules as keys\n" + "KEY is an arbitrary symbol with the same syntax rules as keys\n" "for shell environment variables. PERCENT_ESCAPED_VALUE is the\n" "corresponding value; they should be similar to the values of\n" "envronment variables but gpg-agent does not enforce any\n" diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 7331f58..c23c673 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -387,7 +387,7 @@ divert_pksign (ctrl_t ctrl, } -/* Decrypt the the value given asn an S-expression in CIPHER using the +/* Decrypt the value given asn an S-expression in CIPHER using the key identified by SHADOW_INFO and return the plaintext in an allocated buffer in R_BUF. The padding information is stored at R_PADDING with -1 for not known. */ diff --git a/agent/findkey.c b/agent/findkey.c index 1b187ba..698f765 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -1289,7 +1289,7 @@ agent_public_key_from_file (ctrl_t ctrl, -/* Check whether the the secret key identified by GRIP is available. +/* Check whether the secret key identified by GRIP is available. Returns 0 is the key is available. */ int agent_key_available (const unsigned char *grip) diff --git a/agent/genkey.c b/agent/genkey.c index 8a43d89..7fb0139 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -220,7 +220,7 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw, } /* Now check the constraints and collect the error messages unless - in in silent mode which returns immediately. */ + in silent mode which returns immediately. */ if (utf8_charcount (pw, -1) < minlen ) { if (!failed_constraint) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index c0208cc..5a5b55b 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2394,7 +2394,7 @@ handle_signal (int signo) } #endif -/* Check the nonce on a new connection. This is a NOP unless we we +/* Check the nonce on a new connection. This is a NOP unless we are using our Unix domain socket emulation under Windows. */ static int check_nonce (ctrl_t ctrl, assuan_sock_nonce_t *nonce) diff --git a/agent/keyformat.txt b/agent/keyformat.txt index e80496e..68fbdbc 100644 --- a/agent/keyformat.txt +++ b/agent/keyformat.txt @@ -133,7 +133,7 @@ The currently defined protection modes are: *** openpgp-s2k3-sha1-aes-cbc - This describes an algorithm using using AES in CBC mode for + This describes an algorithm using AES in CBC mode for encryption, SHA-1 for integrity protection and the String to Key algorithm 3 from OpenPGP (rfc4880). @@ -182,7 +182,7 @@ The currently defined protection modes are: *** openpgp-s2k3-ocb-aes - This describes an algorithm using using AES-128 in OCB mode, a nonce + This describes an algorithm using AES-128 in OCB mode, a nonce of 96 bit, a taglen of 128 bit, and the String to Key algorithm 3 from OpenPGP (rfc4880). @@ -311,7 +311,7 @@ This format is used to transfer keys between gpg and gpg-agent. * PROTALGO is a Libgcrypt style cipher algorithm name * IV is the initialization verctor. * S2KMODE is the value from RFC-4880. - * S2KHASH is a a libgcrypt style hash algorithm identifier. + * S2KHASH is a libgcrypt style hash algorithm identifier. * S2KSALT is the 8 byte salt * S2KCOUNT is the count value from RFC-4880. diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c index ae6f0ce..b8d2aaa 100644 --- a/agent/preset-passphrase.c +++ b/agent/preset-passphrase.c @@ -239,7 +239,7 @@ main (int argc, char **argv) else usage (1); - /* Tell simple-pwquery about the the standard socket name. */ + /* Tell simple-pwquery about the standard socket name. */ { char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL); simple_pw_set_socket (tmp); diff --git a/agent/protect.c b/agent/protect.c index e205869..7ae7e64 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -690,7 +690,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, return rc; /* Now create the protected version of the key. Note that the 10 - extra bytes are for for the inserted "protected-" string (the + extra bytes are for the inserted "protected-" string (the beginning of the plaintext reads: "((11:private-key(" ). The 35 term is the space for (12:protected-at15:). */ *resultlen = (10 diff --git a/common/argparse.c b/common/argparse.c index b53efce..fbe8a37 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -61,7 +61,7 @@ /* GnuPG uses GPLv3+ but a standalone version of this defaults to GPLv2+ because that is the license of this file. Change this if you include it in a program which uses GPLv3. If you don't want to - set a a copyright string for your usage() you may also hardcode it + set a copyright string for your usage() you may also hardcode it here. */ #ifndef GNUPG_MAJOR_VERSION @@ -571,7 +571,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, int unread_buf[3]; /* We use an int so that we can store EOF. */ int unread_buf_count = 0; - if (!fp) /* Divert to to arg_parse() in this case. */ + if (!fp) /* Divert to arg_parse() in this case. */ return arg_parse (arg, opts); initialize (arg, filename, lineno); diff --git a/common/asshelp.c b/common/asshelp.c index 2cab310..f3a92f9 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -414,7 +414,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx, /* If the agent has been configured for use with a standard socket, an environment variable is not required and thus - we we can savely start the agent here. */ + we can safely start the agent here. */ i = 0; argv[i++] = "--homedir"; argv[i++] = abs_homedir; diff --git a/common/dotlock.c b/common/dotlock.c index 7ebd523..5fe652e 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -411,7 +411,7 @@ struct dotlock_handle }; -/* A list of of all lock handles. The volatile attribute might help +/* A list of all lock handles. The volatile attribute might help if used in an atexit handler. Note that [UN]LOCK_all_lockfiles must not change ERRNO. */ static volatile dotlock_t all_lockfiles; @@ -913,7 +913,7 @@ dotlock_create (const char *file_to_lock, unsigned int flags) -/* Convenience function to store a file descriptor (or any any other +/* Convenience function to store a file descriptor (or any other integer value) in the context of handle H. */ void dotlock_set_fd (dotlock_t h, int fd) @@ -921,7 +921,7 @@ dotlock_set_fd (dotlock_t h, int fd) h->extra_fd = fd; } -/* Convenience function to retrieve a file descriptor (or any any other +/* Convenience function to retrieve a file descriptor (or any other integer value) stored in the context of handle H. */ int dotlock_get_fd (dotlock_t h) diff --git a/common/iobuf.c b/common/iobuf.c index d346027..db66a7f 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2502,7 +2502,7 @@ iobuf_get_fname_nonnull (iobuf_t a) * Enable or disable partial body length mode (RFC 4880 4.2.2.4). * * If LEN is 0, this disables partial block mode by popping the - * partial body length filter, which which must be the most recently + * partial body length filter, which must be the most recently * added filter. * * If LEN is non-zero, it pushes a partial body length filter. If diff --git a/common/membuf.c b/common/membuf.c index 4c1a844..18a971d 100644 --- a/common/membuf.c +++ b/common/membuf.c @@ -67,7 +67,7 @@ init_membuf_secure (membuf_t *mb, int initiallen) } -/* Shift the the content of the membuf MB by AMOUNT bytes. The next +/* Shift the content of the membuf MB by AMOUNT bytes. The next operation will then behave as if AMOUNT bytes had not been put into the buffer. If AMOUNT is greater than the actual accumulated bytes, the membuf is basically reset to its initial state. */ diff --git a/common/name-value.c b/common/name-value.c index 1018668..5094acd 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -59,7 +59,7 @@ struct name_value_entry /* The name. Comments and blank lines have NAME set to NULL. */ char *name; - /* The value as stored in the file. We store it when when we parse + /* The value as stored in the file. We store it when we parse a file so that we can reproduce it. */ strlist_t raw_value; diff --git a/common/session-env.c b/common/session-env.c index 1bc3a2b..c1eb1d9 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -317,7 +317,7 @@ session_env_getenv (session_env_t se, const char *name) long it has not been removed or updated by a call to session_env_putenv. If the variable does not exist, the function tries to return the value trough a call to getenv; if that returns - a value, this value is recorded and and used. If no value could be + a value, this value is recorded and used. If no value could be found, returns NULL. The caller must not change the returned value. */ char * diff --git a/common/sexp-parse.h b/common/sexp-parse.h index 9b14f77..4f77f14 100644 --- a/common/sexp-parse.h +++ b/common/sexp-parse.h @@ -89,7 +89,7 @@ sskip (unsigned char const **buf, int *depth) } -/* Check whether the the string at the address BUF points to matches +/* Check whether the string at the address BUF points to matches the token. Return true on match and update BUF to point behind the token. Return false and do not update the buffer if it does not match. */ diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index c74317f..e7f4af3 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -352,7 +352,7 @@ default_inq_cb (void *opaque, const char *line) /* Ask the gpg-agent for a passphrase and present the user with a DESCRIPTION, a PROMPT and optionally with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in + If a CACHEID is not NULL it is used to locate the passphrase in the cache and store it under this ID. If OPT_CHECK is true gpg-agent is asked to apply some checks on the passphrase security. If ERRORCODE is not NULL it should point a variable receiving an diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h index f98a396..772aa39 100644 --- a/common/simple-pwquery.h +++ b/common/simple-pwquery.h @@ -42,7 +42,7 @@ /* Ask the gpg-agent for a passphrase and present the user with a DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in + If a CACHEID is not NULL it is used to locate the passphrase in the cache and store it under this ID. If OPT_CHECK is true gpg-agent is asked to apply some checks on the passphrase security. If ERRORCODE is not NULL it should point a variable receiving an diff --git a/common/ttyio.c b/common/ttyio.c index 29af1b3..c7c9d85 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -602,7 +602,7 @@ tty_get( const char *prompt ) return do_get ( prompt, 0 ); } -/* Variable argument version of tty_get. The prompt is is actually a +/* Variable argument version of tty_get. The prompt is actually a format string with arguments. */ char * tty_getf (const char *promptfmt, ... ) diff --git a/common/utf8conv.c b/common/utf8conv.c index bce9e3a..d26eff0 100644 --- a/common/utf8conv.c +++ b/common/utf8conv.c @@ -160,7 +160,7 @@ set_native_charset (const char *newset) const char *aliases; /* We are a console program thus we need to use the - GetConsoleOutputCP function and not the the GetACP which + GetConsoleOutputCP function and not the GetACP which would give the codepage for a GUI program. Note this is not a bulletproof detection because GetConsoleCP might return a different one for console input. Not sure how to cope with diff --git a/common/yesno.c b/common/yesno.c index 58de63d..ebe8d82 100644 --- a/common/yesno.c +++ b/common/yesno.c @@ -114,7 +114,7 @@ answer_is_yes_no_quit ( const char *s ) } /* - Return 1 for okay, 0 for for cancel or DEF_ANSWER for default. + Return 1 for okay, 0 for cancel or DEF_ANSWER for default. */ int answer_is_okay_cancel (const char *s, int def_answer) diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index c83b00e..3284ff2 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -251,7 +251,7 @@ clean_cache_slot (cert_item_t ci) * * FROM_CONFIG indicates that CERT is a permanent certificate and * should stay in the cache. IS_TRUSTED requests that the trusted - * flag is set for the certificate; a value of 1 indicates the the + * flag is set for the certificate; a value of 1 indicates the * cert is trusted due to GnuPG mechanisms, a value of 2 indicates * that it is trusted because it has been taken from the system's * store of trusted certificates. If FPR_BUFFER is not NULL the @@ -1002,7 +1002,7 @@ get_cert_bysubject (const char *subject_dn, unsigned int seq) -/* Return a value describing the the class of PATTERN. The offset of +/* Return a value describing the class of PATTERN. The offset of the actual string to be used for the comparison is stored at R_OFFSET. The offset of the serialnumer is stored at R_SN_OFFSET. */ static enum pattern_class diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index c60d3fb..248ad9a 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -44,7 +44,7 @@ Field 1: Constant "v" Field 2: Version number of this file. Must be 1. - This record must be the first non-comment record record and + This record must be the first non-comment record and there shall only exist one record of this type. 1.3. CRL cache record diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 074e012..d72d1c7 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -881,7 +881,7 @@ resolve_name_standard (const char *name, unsigned short port, else *portstr = 0; - /* We can't use the the AI_IDN flag because that does the conversion + /* We can't use the AI_IDN flag because that does the conversion using the current locale. However, GnuPG always used UTF-8. To support IDN we would need to make use of the libidn API. */ ret = getaddrinfo (name, *portstr? portstr : NULL, &hints, &aibuf); @@ -1680,7 +1680,7 @@ get_dns_cert_standard (const char *name, int want_certtype, found, the malloced data is returned at (R_KEY, R_KEYLEN) and the other return parameters are set to NULL/0. If an IPGP CERT record was found the fingerprint is stored as an allocated block at - R_FPR and its length at R_FPRLEN; an URL is is allocated as a + R_FPR and its length at R_FPRLEN; an URL is allocated as a string and returned at R_URL. If WANT_CERTTYPE is 0 this function returns the first CERT found with a supported type; it is expected that only one CERT record is used. If WANT_CERTTYPE is one of the diff --git a/dirmngr/http.c b/dirmngr/http.c index 733018d..f4b40a8 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -1157,7 +1157,7 @@ http_get_status_code (http_t hd) /* Return information pertaining to TLS. If TLS is not in use for HD, NULL is returned. WHAT is used ask for specific information: - (NULL) := Only check whether TLS is is use. Returns an + (NULL) := Only check whether TLS is in use. Returns an unspecified string if TLS is in use. That string may even be the empty string. */ diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index b7aa7cc..f664655 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -1471,7 +1471,7 @@ modlist_dump (LDAPMod **modlist, estream_t output) for ((ptr = (*m)->mod_values), (i = 1); ptr && *ptr; ptr++, i ++) { /* Assuming terminals are about 80 characters wide, - display at most most about 10 lines of debugging + display at most about 10 lines of debugging output. If we do trim the buffer, append '...' to the end. */ const int max_len = 10 * 70; diff --git a/dirmngr/server.c b/dirmngr/server.c index 961bba0..9fa8229 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -190,7 +190,7 @@ data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size) const char *buffer = buffer_arg; gpg_error_t err; - /* If we do not want logging, enable it it here. */ + /* If we do not want logging, enable it here. */ if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging) ctrl->server_local->inhibit_data_logging_now = 1; diff --git a/doc/DETAILS b/doc/DETAILS index ac599fc..d9b1fa6 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -187,7 +187,7 @@ described here. only filled if the issuer certificate is available. The root has been reached if this is the same string as the fingerprint. The advantage of using this value is that it is guaranteed to have - been been build by the same lookup algorithm as gpgsm uses. + been built by the same lookup algorithm as gpgsm uses. For "uid" records this field lists the preferences in the same way gpg's --edit-key menu does. @@ -702,7 +702,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: VALIDATION_MODEL describes the algorithm used to check the validity of the key. The defaults are the standard Web of Trust - model for gpg and the the standard X.509 model for gpgsm. The + model for gpg and the standard X.509 model for gpgsm. The defined values are - pgp :: The standard PGP WoT. @@ -796,7 +796,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: recent message was verified 4 seconds ago.' *** PKA_TRUST_ - This is is one: + This is one of: - PKA_TRUST_GOOD - PKA_TRUST_BAD diff --git a/doc/TRANSLATE b/doc/TRANSLATE index 7c3e544..9bd9b08 100644 --- a/doc/TRANSLATE +++ b/doc/TRANSLATE @@ -37,7 +37,7 @@ are disabled like this .#gpgsm.some.help-item This string is not translated. -After translation you should remove the the hash mark so that the +After translation you should remove the hash mark so that the entry looks like. .gpgsm.some.help-item diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 7fc11a2..7a6ba47 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -775,7 +775,7 @@ configuration. @end table If DirMngr has not enough information about the given certificate (which -is the case for not yet cached certificates), it will will inquire the +is the case for not yet cached certificates), it will inquire the missing data: @example @@ -1038,7 +1038,7 @@ as a binary blob. @c c) No authorityKeyIdentifier exits: The certificate is retrieved @c using @code{find_cert_bysubject} without the key ID argument. If @c the certificate is in the certificate cache the first one with a - at c matching subject is is directly returned. Then the requester is + at c matching subject is directly returned. Then the requester is @c asked via the Assuan inquiry ``SENDCERT'' and an exact @c specification of the subject whether he can @c provide this certificate. If this succeed the returned @@ -1115,7 +1115,7 @@ as a binary blob. @c respectively. The have already been described above under the @c description of @code{crl_cache_insert}. If no certificate was found @c or with no authorityKeyIdentifier, only the cache is consulted using - at c @code{get_cert_bysubject}. The latter is is done under the assumption + at c @code{get_cert_bysubject}. The latter is done under the assumption @c that a matching certificate has explicitly been put into the @c certificate cache. If the issuer's certificate could not be found, @c the validation terminates with the error code @code{GPG_ERR_MISSING_CERT}. diff --git a/doc/faq.org b/doc/faq.org index 8fc3775..f038508 100644 --- a/doc/faq.org +++ b/doc/faq.org @@ -1462,7 +1462,7 @@ update this FAQ in the next month. See the section "Changes" for recent updates : | sort | uniq | xargs echo gpg --recv-keys Note that the invocation of sort is also required to wait for the - of the listing before before starting the import. + of the listing before starting the import. * Bug reporting and hacking @@ -1491,7 +1491,7 @@ details. GnuPG has originally been developed in Germany because we have been able to do that without being affected by the US export restrictions. We had to reject any contributions from US citizens or from people -living the the US. That changed by end of 2000 when the export +living in the US. That changed by end of 2000 when the export restrictions were basically dropped for all kind of freely available software. However there are still some requirements in the US. Quoting David Shaw: mail diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 3177af4..b72892c 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -77,7 +77,7 @@ the included Secure Shell Agent you may start the agent using: @c @c The rationale for this separation is that it allows access to the @c secret key to be tightly controlled and audited, and it doesn't permit - at c the the supplicant to either copy the key or to override the owner's + at c the supplicant to either copy the key or to override the owner's @c intentions. @example @@ -1412,7 +1412,7 @@ numbers in the range @code{0} to @code{UINT_MAX} and wrapping around to 0. The actual values should not be relied upon; they shall only be used to detect a change. -The currently defined counters are are: +The currently defined counters are: @table @code @item ANY Incremented with any change of any of the other counters. @@ -1508,7 +1508,7 @@ following values are defined: @item cache-ttl-opt-preset This option sets the cache TTL for new entries created by GENKEY and -PASSWD commands when using the @option{--preset} option. It it is not +PASSWD commands when using the @option{--preset} option. It is not used a default value is used. @item s2k-count diff --git a/doc/gpg.texi b/doc/gpg.texi index 16c9674..78dd651 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1430,7 +1430,7 @@ Note that this adds a keyring to the current list. If the intent is to use the specified keyring alone, use @option{--keyring} along with @option{--no-default-keyring}. -If the the option @option{--no-keyring} has been used no keyrings will +If the option @option{--no-keyring} has been used no keyrings will be used at all. @@ -3391,7 +3391,7 @@ For existing users a small helper script is provided to create these files (@pxref{addgnupghome}). For internal purposes @command{@gpgname} creates and maintains a few other -files; They all live in in the current home directory (@pxref{option +files; They all live in the current home directory (@pxref{option --homedir}). Only the @command{@gpgname} program may modify these files. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index b92eaea..1d00839 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -898,7 +898,7 @@ start up with a working configuration. For existing users a small helper script is provided to create these files (@pxref{addgnupghome}). For internal purposes @command{gpgsm} creates and maintains a few other files; -they all live in in the current home directory (@pxref{option +they all live in the current home directory (@pxref{option --homedir}). Only @command{gpgsm} may modify these files. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 1617801..4c6bb93 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -225,7 +225,7 @@ This option appends a thread ID to the PID in the log output. @efindex ASSUAN_DEBUG Changes the active Libassuan logging categories to @var{cats}. The value for @var{cats} is an unsigned integer given in usual C-Syntax. -A value of of 0 switches to a default category. If this option is not +A value of 0 switches to a default category. If this option is not used the categories are taken from the environment variable @code{ASSUAN_DEBUG}. Note that this option has only an effect if the Assuan debug flag has also been with the option @option{--debug}. For diff --git a/doc/vuln-announce-2007-multiple-message.txt b/doc/vuln-announce-2007-multiple-message.txt index 16c08d4..154b274 100644 --- a/doc/vuln-announce-2007-multiple-message.txt +++ b/doc/vuln-announce-2007-multiple-message.txt @@ -81,7 +81,7 @@ Here the PLAINTEXT status lines clearly identify the start of a new message. Note, that using gpg on the command line is in almost all cases not -done with redirection but by letting gpg save the the signed message. +done with redirection but by letting gpg save the signed message. In this case gpg will save the message to different files or in case the file names are identical, prompt the over to overwrite the first one again. diff --git a/doc/whats-new-in-2.1.txt b/doc/whats-new-in-2.1.txt index 19ed8b9..4b7349a 100644 --- a/doc/whats-new-in-2.1.txt +++ b/doc/whats-new-in-2.1.txt @@ -103,7 +103,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? The scripts to create a Windows installer are now part of GnuPG. Now for the detailed description of these new features. Note that the - examples assume that that /gpg/ is installed as /gpg/. Your + examples assume that /gpg/ is installed as /gpg/. Your installation may have it installed under the name /gpg2/. @@ -510,7 +510,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html at login time and use an environment variable (`GPG_AGENT_INFO') to tell the other GnuPG modules how to connect to the agent. However, correctly managing the start up and this environment variable is - cumbersome so that that an easier method is required. Since GnuPG + cumbersome so that an easier method is required. Since GnuPG 2.0.16 the `--use-standard-socket' option already allowed to start the agent on the fly; however the environment variable was still required. @@ -535,7 +535,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html A deficit of the OpenPGP protocol is that signatures carry only a limited indication on which public key has been used to create a signature. Thus a verification engine may only use this ?long key id? - to look up the the key in its own store or from a public keyserver. + to look up the key in its own store or from a public keyserver. Unfortunately it has now become possible to create a key with a long 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 diff --git a/g10/armor.c b/g10/armor.c index 58d8e01..6b7c3f7 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1294,7 +1294,7 @@ armor_filter( void *opaque, int control, c = bintoasc[radbuf[2]&077]; iobuf_put(a, c); iobuf_writestr(a,afx->eol); - /* and the the trailer */ + /* and the trailer */ if( afx->what >= DIM(tail_strings) ) log_bug("afx->what=%d", afx->what); iobuf_writestr(a, "-----"); diff --git a/g10/build-packet.c b/g10/build-packet.c index ad46a02..489fadd 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -621,7 +621,7 @@ calc_plaintext( PKT_plaintext *pt ) is assumed to have been enabled on OUT. On success, partial block mode is disabled. - If PT->BUF is NULL, the the caller must write out the data. In + If PT->BUF is NULL, the caller must write out the data. In this case, if PT->LEN was 0, then partial body length mode was enabled and the caller must disable it by calling iobuf_set_partial_body_length_mode (out, 0). */ diff --git a/g10/call-agent.c b/g10/call-agent.c index 335e12a..7c30bdb 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -340,7 +340,7 @@ unescape_status_string (const unsigned char *s) } -/* Take a 20 byte hexencoded string and put it into the the provided +/* Take a 20 byte hexencoded string and put it into the provided 20 byte buffer FPR in binary format. */ static int unhexify_fpr (const char *hexstr, unsigned char *fpr) diff --git a/g10/card-util.c b/g10/card-util.c index e358572..969f6c9 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -72,7 +72,7 @@ write_sc_op_status (gpg_error_t err) } -/* Change the PIN of a an OpenPGP card. This is an interactive +/* Change the PIN of an OpenPGP card. This is an interactive function. */ void change_pin (int unblock_v2, int allow_admin) diff --git a/g10/compress.c b/g10/compress.c index fbc8097..a14d107 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -182,7 +182,7 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs, nread = iobuf_read( a, zfx->inbuf + n, count ); if( nread == -1 ) nread = 0; n += nread; - /* Algo 1 has no zlib header which requires us to to give + /* Algo 1 has no zlib header which requires us to give * inflate an extra dummy byte to read. To be on the safe * side we allow for up to 4 ff bytes. */ if( nread < count && zfx->algo == 1 && zfx->algo1hack < 4) { diff --git a/g10/encrypt.c b/g10/encrypt.c index 5268946..6130ba0 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -319,7 +319,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) && !overflow && opt.verbose) log_info(_("WARNING: '%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because - OpenPGP uses only 32 bit for file sizes. So if the the + OpenPGP uses only 32 bit for file sizes. So if the size of a file is larger than 2^32 minus some bytes for packet headers, we switch to partial length encoding. */ if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) @@ -461,7 +461,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, * The caller may provide a checked list of public keys in * PROVIDED_PKS; if not the function builds a list of keys on its own. * - * Note that FILEFD is currently only used by cmd_encrypt in the the + * Note that FILEFD is currently only used by cmd_encrypt in the * not yet finished server.c. */ int @@ -659,7 +659,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, && !overflow && opt.verbose) log_info(_("WARNING: '%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because - OpenPGP uses only 32 bit for file sizes. So if the the size + OpenPGP uses only 32 bit for file sizes. So if the size of a file is larger than 2^32 minus some bytes for packet headers, we switch to partial length encoding. */ if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) diff --git a/g10/export.c b/g10/export.c index 8668126..025b936 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1022,7 +1022,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) err = gpg_error (GPG_ERR_UNKNOWN_CURVE); goto leave; } - /* Put the curve's OID into into the MPI array. This requires + /* Put the curve's OID into the MPI array. This requires that we shift Q and D. For ECDH also insert the KDF parms. */ if (is_ecdh) { diff --git a/g10/getkey.c b/g10/getkey.c index e39de28..163ab80 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1143,7 +1143,7 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist, /* Find a public key identified by NAME. * - * If name appears to be a valid valid RFC822 mailbox (i.e., email + * If name appears to be a valid RFC822 mailbox (i.e., email * address) and auto key lookup is enabled (no_akl == 0), then the * specified auto key lookup methods (--auto-key-lookup) are used to * import the key into the local keyring. Otherwise, just the local diff --git a/g10/import.c b/g10/import.c index b6c04dc..45ec07a 100644 --- a/g10/import.c +++ b/g10/import.c @@ -76,7 +76,7 @@ struct import_stats_s #define NODE_FLAG_A 8 -/* A an object and a global instance to store selectors created from +/* An object and a global instance to store selectors created from * --import-filter keep-uid=EXPR. * --import-filter drop-sig=EXPR. * diff --git a/g10/keydb.c b/g10/keydb.c index aab90e3..4c5149d 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1092,7 +1092,7 @@ unlock_all (KEYDB_HANDLE hd) * keydb_get_keyblock (hd, ...); // -> Result 1. * * Note: it is only possible to save a single save state at a time. - * In other words, the the save stack only has room for a single + * In other words, the save stack only has room for a single * instance of the state. */ void keydb_push_found_state (KEYDB_HANDLE hd) diff --git a/g10/keyedit.c b/g10/keyedit.c index 1456d28..ab66d01 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1080,7 +1080,7 @@ trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp) /* - * Loop over all LOCUSR and and sign the uids after asking. If no + * Loop over all LOCUSR and sign the uids after asking. If no * user id is marked, all user ids will be signed; if some user_ids * are marked only those will be signed. If QUICK is true the * function won't ask the user and use sensible defaults. @@ -5186,7 +5186,7 @@ change_primary_uid_cb (PKT_signature * sig, void *opaque) * Set the primary uid flag for the selected UID. We will also reset * all other primary uid flags. For this to work with have to update * all the signature timestamps. If we would do this with the current - * time, we lose quite a lot of information, so we use a a kludge to + * time, we lose quite a lot of information, so we use a kludge to * do this: Just increment the timestamp by one second which is * sufficient to updated a signature during import. */ diff --git a/g10/keygen.c b/g10/keygen.c index e2bdfc1..844d38d 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1786,7 +1786,7 @@ ask_key_flags (int algo, int subkey, unsigned int current) else if (!subkey && *s == 'c') { /* Accept 'c' for the primary key because USAGE_CERT - will will be set anyway. This is for folks who + will be set anyway. This is for folks who want to experiment with a cert-only primary key. */ current |= PUBKEY_USAGE_CERT; } diff --git a/g10/keyid.c b/g10/keyid.c index dd098fd..6e8d97f 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -202,7 +202,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) } gcry_md_putc ( md, 0x99 ); /* ctb */ - /* What does it mean if n is greater than than 0xFFFF ? */ + /* What does it mean if n is greater than 0xFFFF ? */ gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */ gcry_md_putc ( md, n ); gcry_md_putc ( md, pk->version ); diff --git a/g10/keyring.c b/g10/keyring.c index 328290e..9b7b5fd 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -777,7 +777,7 @@ prepare_search (KEYRING_HANDLE hd) /* A map of the all characters valid used for word_match() - * Valid characters are in in this table converted to uppercase. + * Valid characters are in this table converted to uppercase. * because the upper 128 bytes have special meaning, we assume * that they are all valid. * Note: We must use numerical values here in case that this program diff --git a/g10/mainproc.c b/g10/mainproc.c index ac2ab03..8e29891 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -78,7 +78,7 @@ struct mainproc_context signature. */ struct { - /* A file descriptor of the the signed data. Only used if not -1. */ + /* A file descriptor of the signed data. Only used if not -1. */ int data_fd; /* A list of filenames with the data files or NULL. This is only used if DATA_FD is -1. */ @@ -1997,7 +1997,7 @@ check_sig_and_print (CTX c, kbnode_t node) log_assert (mainpk); - /* In case we did not found a valid valid textual userid above + /* In case we did not found a valid textual userid above we print the first user id packet or a "[?]" instead along with the "Good|Expired|Bad signature" line. */ if (!count) diff --git a/g10/misc.c b/g10/misc.c index 4b9ad99..ac00009 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -522,7 +522,7 @@ openpgp_cipher_blocklen (cipher_algo_t algo) block length. This is so that the packet parsing code works even for unknown algorithms (for which we assume 8 due to tradition). - NOTE: If you change the the returned blocklen above 16, check + NOTE: If you change the returned blocklen above 16, check the callers because they may use a fixed size buffer of that size. */ switch (algo) diff --git a/g10/pkclist.c b/g10/pkclist.c index 288affc..4991d20 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -818,7 +818,7 @@ expand_group (strlist_t input) * success the new key is added to PK_LIST_ADDR. NAME is the user id * of the key. USE the requested usage and a set MARK_HIDDEN will * mark the key in the updated list as a hidden recipient. If - * FROM_FILE is true, NAME is is not a user ID but the name of a file + * FROM_FILE is true, NAME is not a user ID but the name of a file * holding a key. */ gpg_error_t find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 117744f..de98d99 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -211,7 +211,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) /* Now get the DEK (data encryption key) from the frame * - * Old versions encode the DEK in in this format (msb is left): + * Old versions encode the DEK in this format (msb is left): * * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2 * diff --git a/g10/revoke.c b/g10/revoke.c index 591b641..3a2b068 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -442,7 +442,7 @@ gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr) to stdout or the filename given by --output. REASON describes the revocation reason. PSK is the public primary key - we expect that a corresponding secret key is available. KEYBLOCK is the entire - KEYBLOCK which is used in PGP mode to write a a minimal key and not + KEYBLOCK which is used in PGP mode to write a minimal key and not just the naked revocation signature; it may be NULL. If LEADINTEXT is not NULL, it is written right before the (armored) output.*/ static int diff --git a/g10/rmd160.c b/g10/rmd160.c index 7c77ca5..cf27796 100644 --- a/g10/rmd160.c +++ b/g10/rmd160.c @@ -17,7 +17,7 @@ * along with this program; if not, see . */ -/* For historic reasons gpg uses RIPE-MD160 to to identify names in +/* For historic reasons gpg uses RIPE-MD160 to identify names in the trustdb. It would be better to change that to SHA-1, to take advantage of a SHA-1 hardware operation provided by some CPUs. This would break trustdb compatibility and thus we don't want to do diff --git a/g10/tofu.c b/g10/tofu.c index 449e921..8c41ad7 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2949,7 +2949,7 @@ write_stats_status (estream_t fp, * * POLICY is the key's policy (as returned by get_policy). * - * Returns 0 if if ONLY_STATUS_FD is set. Otherwise, returns whether + * Returns 0 if ONLY_STATUS_FD is set. Otherwise, returns whether * the caller should call show_warning after iterating over all user * ids. */ diff --git a/g10/trust.c b/g10/trust.c index 888b4ca..b1fa3d6 100644 --- a/g10/trust.c +++ b/g10/trust.c @@ -186,7 +186,7 @@ get_ownertrust (PKT_public_key *pk) /* * Same as get_ownertrust but this takes the minimum ownertrust value - * into into account, and will bump up the value as needed. + * into account, and will bump up the value as needed. */ static int get_ownertrust_with_min (PKT_public_key *pk) diff --git a/g10/trustdb.c b/g10/trustdb.c index 75714ab..103f83e 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -222,7 +222,7 @@ tdb_register_trusted_key( const char *string ) /* * Helper to add a key to the global list of ultimately trusted keys. - * Retruns: true = inserted, false = already in in list. + * Retruns: true = inserted, false = already in list. */ static int add_utk (u32 *kid) diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h index b6adcbd..0243166 100644 --- a/g13/g13-syshelp.h +++ b/g13/g13-syshelp.h @@ -32,7 +32,7 @@ struct tab_item_s char *label; /* Optional malloced label for that entry. */ char *mountpoint; /* NULL or a malloced mountpoint. */ char blockdev[1]; /* String with the name of the block device. If - it starts with a slash is is a regular device + it starts with a slash it is a regular device name, otherwise it is a PARTUUID. */ }; diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 73ecfbe..f3bdceb 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -123,7 +123,7 @@ IDs go here. - bN Space for the keyblock or certificate. - bN RFU. This is the remaining space after keyblock and before - the checksum. Is is not covered by the checksum. + the checksum. It is not covered by the checksum. - b20 SHA-1 checksum (useful for KS syncronisation?) Note, that KBX versions before GnuPG 2.1 used an MD5 checksum. However it was only created but never checked. @@ -589,7 +589,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) put32 ( a, 0 ); /* size of reserved space */ /* reserved space (which is currently of size 0) */ - /* space where we write keyIDs and and other stuff so that the + /* space where we write keyIDs and other stuff so that the pointers can actually point to somewhere */ if (blobtype == KEYBOX_BLOBTYPE_PGP) { diff --git a/m4/autobuild.m4 b/m4/autobuild.m4 index bd1f4dc..ceed464 100644 --- a/m4/autobuild.m4 +++ b/m4/autobuild.m4 @@ -7,7 +7,7 @@ # that contains a configuration script generated by Autoconf, under # the same distribution terms as the rest of that program. # -# This file can can be used in projects which are not available under +# This file can be used in projects which are not available under # the GNU General Public License or the GNU Library General Public # License but which still want to provide support for Autobuild. diff --git a/m4/gettext.m4 b/m4/gettext.m4 index c9ae1f7..cdac014 100644 --- a/m4/gettext.m4 +++ b/m4/gettext.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/m4/intl.m4 b/m4/intl.m4 index 3906a17..ee47182 100644 --- a/m4/intl.m4 +++ b/m4/intl.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/m4/intldir.m4 b/m4/intldir.m4 index 7a28843..0bc1b7a 100644 --- a/m4/intldir.m4 +++ b/m4/intldir.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. AC_PREREQ(2.52) diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 index 19aa77e..eef389d 100644 --- a/m4/lcmessage.m4 +++ b/m4/lcmessage.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/m4/nls.m4 b/m4/nls.m4 index 7967cc2..6b50be3 100644 --- a/m4/nls.m4 +++ b/m4/nls.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/m4/po.m4 b/m4/po.m4 index f7c9c06..201c7ca 100644 --- a/m4/po.m4 +++ b/m4/po.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/m4/progtest.m4 b/m4/progtest.m4 index a56365c..6dc2f0f 100644 --- a/m4/progtest.m4 +++ b/m4/progtest.m4 @@ -4,13 +4,13 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -dnl This file can can be used in projects which are not available under +dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/scd/apdu.c b/scd/apdu.c index 82d53b1..9df1572 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2017,7 +2017,7 @@ open_pcsc_reader_wrapped (const char *portstr) unsigned int dummy_status; /* Note that we use the constant and not the function because this - code won't be be used under Windows. */ + code won't be used under Windows. */ const char *wrapperpgm = GNUPG_LIBEXECDIR "/gnupg-pcsc-wrapper"; if (access (wrapperpgm, X_OK)) diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 3f99e2e..99e4f00 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -416,7 +416,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, return gpg_error (GPG_ERR_INV_VALUE); /* Check that the provided ID is vaid. This is not really needed - but we do it to to enforce correct usage by the caller. */ + but we do it to enforce correct usage by the caller. */ if (strncmp (keyidstr, "DINSIG.", 7) ) return gpg_error (GPG_ERR_INV_ID); keyidstr += 7; diff --git a/scd/app-geldkarte.c b/scd/app-geldkarte.c index e3c7dcc..c277171 100644 --- a/scd/app-geldkarte.c +++ b/scd/app-geldkarte.c @@ -288,7 +288,7 @@ app_select_geldkarte (app_t app) goto leave; /* Read the first record of EF_ID (SFI=0x17). We require this - record to be at least 24 bytes with the the first byte 0x67 and a + record to be at least 24 bytes with the first byte 0x67 and a correct filler byte. */ err = iso7816_read_record (slot, 1, 1, ((0x17 << 3)|4), &result, &resultlen); if (err) diff --git a/scd/app-nks.c b/scd/app-nks.c index a6487c4..4442a10 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -1004,7 +1004,7 @@ do_decipher (app_t app, const char *keyidstr, return gpg_error (GPG_ERR_INV_VALUE); /* Check that the provided ID is valid. This is not really needed - but we do it to to enforce correct usage by the caller. */ + but we do it to enforce correct usage by the caller. */ if (!strncmp (keyidstr, "NKS-NKS3.", 9) ) ; else if (!strncmp (keyidstr, "NKS-DF01.", 9) ) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 71c9e1b..608e3cc 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -619,7 +619,7 @@ count_bits (const unsigned char *a, size_t len) The lsb is here the rightmost bit. Defined flags bits are: Bit 0 = CHV1 and CHV2 are not syncronized - Bit 1 = CHV2 has been been set to the default PIN of "123456" + Bit 1 = CHV2 has been set to the default PIN of "123456" (this implies that bit 0 is also set). P= @@ -1874,7 +1874,7 @@ check_pinpad_request (app_t app, pininfo_t *pininfo, int admin_pin) } -/* Verify a CHV either using using the pinentry or if possible by +/* Verify a CHV either using the pinentry or if possible by using a pinpad. PINCB and PINCB_ARG describe the usual callback for the pinentry. CHVNO must be either 1 or 2. SIGCOUNT is only used with CHV1. PINVALUE is the address of a pointer which will diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 1a01ff0..40b2599 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -961,7 +961,7 @@ parse_ccid_descriptor (ccid_driver_t handle, unsigned short bcd_device, The 0x5117 - SCR 3320 USB ID-000 reader seems to be very slow but enabling this workaround boosts the - performance to a a more or less acceptable level (tested by David). + performance to a more or less acceptable level (tested by David). */ if (handle->id_vendor == VENDOR_SCM @@ -1302,7 +1302,7 @@ scan_or_find_usb_device (int scan_mode, With READERNO >= 0 or READERID is not NULL find mode is used. This uses the same algorithm as the scan mode but stops and returns at - the entry number READERNO and return the handle for the the opened + the entry number READERNO and return the handle for the opened USB device. If R_RID is not NULL it will receive the reader ID of that device. If R_DEV is not NULL it will the device pointer of that device. If IFCDESC_EXTRA is NOT NULL it will receive a diff --git a/scd/command.c b/scd/command.c index 5b7ddc8..b1d5539 100644 --- a/scd/command.c +++ b/scd/command.c @@ -900,7 +900,7 @@ cmd_getattr (assuan_context_t ctx, char *line) static const char hlp_setattr[] = "SETATTR \n" "\n" - "This command is used to store data on a a smartcard. The allowed\n" + "This command is used to store data on a smartcard. The allowed\n" "names and values are depend on the currently selected smartcard\n" "application. NAME and VALUE must be percent and '+' escaped.\n" "\n" @@ -954,7 +954,7 @@ static const char hlp_writecert[] = "application. The actual certifciate is requested using the inquiry\n" "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n" "\n" - "In almost all cases a a PIN will be requested. See the related\n" + "In almost all cases a PIN will be requested. See the related\n" "writecert function of the actually used application (app-*.c) for\n" "details."; static gpg_error_t @@ -1007,7 +1007,7 @@ cmd_writecert (assuan_context_t ctx, char *line) static const char hlp_writekey[] = "WRITEKEY [--force] \n" "\n" - "This command is used to store a secret key on a a smartcard. The\n" + "This command is used to store a secret key on a smartcard. The\n" "allowed keyids depend on the currently selected smartcard\n" "application. The actual keydata is requested using the inquiry\n" "\"KEYDATA\" and need to be provided without any protection. With\n" diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index d025063..45303e8 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -430,7 +430,7 @@ inq_certificate (void *opaque, const char *line) } -/* Take a 20 byte hexencoded string and put it into the the provided +/* Take a 20 byte hexencoded string and put it into the provided 20 byte buffer FPR in binary format. */ static int unhexify_fpr (const char *hexstr, unsigned char *fpr) diff --git a/sm/certchain.c b/sm/certchain.c index 083c3ad..b3e8656 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -2120,7 +2120,7 @@ get_regtp_ca_info (ctrl_t ctrl, ksba_cert_t cert, int *chainlen) } /* If this is a German signature law issued certificate, we store - additional additional information. */ + additional information. */ if (!gpgsm_is_in_qualified_list (NULL, array[depth-1], country) && !strcmp (country, "de")) { diff --git a/sm/certdump.c b/sm/certdump.c index bd7c6c3..bd37da4 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -492,7 +492,7 @@ print_dn_part (estream_t stream, { /* Forward to the last multi-valued RDN, so that we can print them all in reverse in the correct order. Note - that this overrides the the standard sequence but that + that this overrides the standard sequence but that seems to a reasonable thing to do with multi-valued RDNs. */ while (dn->multivalued && dn[1].key) diff --git a/sm/certlist.c b/sm/certlist.c index 7baec65..bfc35ce 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -336,7 +336,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, { if (!first_subject) { - /* Save the the subject and the issuer for key usage + /* Save the subject and the issuer for key usage and ambiguous name tests. */ first_subject = ksba_cert_get_subject (cert, 0); first_issuer = ksba_cert_get_issuer (cert, 0); diff --git a/sm/keydb.c b/sm/keydb.c index 44dd9ca..75f83ee 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -265,7 +265,7 @@ keydb_add_resource (ctrl_t ctrl, const char *url, int force, int *auto_created) /* Do we have an URL? gnupg-kbx:filename := this is a plain keybox - filename := See what is is, but create as plain keybox. + filename := See what it is, but create as plain keybox. */ if (strlen (resname) > 10) { diff --git a/sm/keylist.c b/sm/keylist.c index 88a9c4f..6db42e3 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -1280,7 +1280,7 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret, } -/* Same as standard mode mode list all certifying certs too. */ +/* Same as standard mode list all certifying certs too. */ static void list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd, ksba_cert_t cert, int raw_mode, diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c index c96dcf1..3191e05 100644 --- a/tests/gpgscm/main.c +++ b/tests/gpgscm/main.c @@ -88,7 +88,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts) } } -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage( int level ) { diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index 1d8173d..a890d40 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -29,7 +29,7 @@ (define usrpass3 "") (define dsa-usrname1 "pgp5") -;; we use the sub key because we do not yet have the logic to to derive +;; we use the sub key because we do not yet have the logic to derive ;; the first encryption key from a keyblock (I guess) (Well of course ;; we have this by now and the notation below will lookup the primary ;; first and then search for the encryption subkey.) diff --git a/tests/openpgp/verify.scm b/tests/openpgp/verify.scm index a398a14..9b82827 100755 --- a/tests/openpgp/verify.scm +++ b/tests/openpgp/verify.scm @@ -269,7 +269,7 @@ 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. +will only show the article to the reader once! Don't tolerate this. -- Emily Postnews Answers Your Questions on Netiquette -----BEGIN PGP SIGNATURE----- diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 2d054f4..59e2192 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -187,7 +187,7 @@ static assuan_context_t start_agent (void); -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage( int level ) { diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 5814b40..fa19fc1 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -129,7 +129,7 @@ static gpg_error_t command_receive_cb (void *opaque, -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage( int level ) { diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index ca89fc3..c17c1cf 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -133,7 +133,7 @@ static gpg_error_t command_cron (void); -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage( int level ) { @@ -1105,7 +1105,7 @@ process_new_key (server_ctx_t ctx, estream_t key) if (policybuf.auth_submit) { - /* Bypass the confirmation stuff and publish the the key as is. */ + /* Bypass the confirmation stuff and publish the key as is. */ log_info ("publishing address '%s'\n", sl->d); /* FIXME: We need to make sure that we do this only for the * address in the mail. */ @@ -1525,7 +1525,7 @@ command_receive_cb (void *opaque, const char *mediatype, /* Return a list of all configured domains. ECh list element is the - * top directory for for the domain. To figure out the actual domain + * top directory for the domain. To figure out the actual domain * name strrchr(name, '/') can be used. */ static gpg_error_t get_domain_list (strlist_t *r_list) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index a5ee188..a9f4607 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -109,7 +109,7 @@ static ARGPARSE_OPTS opts[] = }; -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage( int level ) { diff --git a/tools/gpgtar.c b/tools/gpgtar.c index 23176dc..3dff176 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -137,7 +137,7 @@ static ARGPARSE_OPTS tar_opts[] = { -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage( int level ) { @@ -507,7 +507,7 @@ main (int argc, char **argv) /* Read the next record from STREAM. RECORD is a buffer provided by the caller and must be at leadt of size RECORDSIZE. The function - return 0 on success and and error code on failure; a diagnostic + return 0 on success and error code on failure; a diagnostic printed as well. Note that there is no need for an EOF indicator because a tarball has an explicit EOF record. */ gpg_error_t diff --git a/tools/mail-signed-keys b/tools/mail-signed-keys index c63001a..3c564f1 100755 --- a/tools/mail-signed-keys +++ b/tools/mail-signed-keys @@ -41,7 +41,7 @@ if [ -z "$signedby" ]; then fi if [ "$dryrun" = "0" ]; then - echo "About to send the the keys signed by $signedby" >&2 + echo "About to send the keys signed by $signedby" >&2 echo -n "to their owners. Do you really want to do this? (y/N)" >&2 read [ "$REPLY" != "y" -a "$REPLY" != "Y" ] && exit 0 diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index dc680f5..a72b9cf 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -191,7 +191,7 @@ struct } opt; -/* Print usage information and and provide strings for help. */ +/* Print usage information and provide strings for help. */ static const char * my_strusage (int level) { @@ -997,7 +997,7 @@ main (int argc, char **argv) setup_libgcrypt_logging (); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - /* Tell simple-pwquery about the the standard socket name. */ + /* Tell simple-pwquery about the standard socket name. */ { char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL); simple_pw_set_socket (tmp); ----------------------------------------------------------------------- Summary of changes: agent/call-scd.c | 6 +++--- agent/command-ssh.c | 6 +++--- agent/command.c | 6 +++--- agent/divert-scd.c | 2 +- agent/findkey.c | 2 +- agent/genkey.c | 2 +- agent/gpg-agent.c | 2 +- agent/keyformat.txt | 6 +++--- agent/preset-passphrase.c | 2 +- agent/protect.c | 2 +- common/argparse.c | 4 ++-- common/asshelp.c | 2 +- common/dotlock.c | 6 +++--- common/iobuf.c | 2 +- common/membuf.c | 2 +- common/name-value.c | 2 +- common/session-env.c | 2 +- common/sexp-parse.h | 2 +- common/simple-pwquery.c | 2 +- common/simple-pwquery.h | 2 +- common/ttyio.c | 2 +- common/utf8conv.c | 2 +- common/yesno.c | 2 +- dirmngr/ChangeLog-2011 | 4 ++-- dirmngr/certcache.c | 4 ++-- dirmngr/crlcache.c | 2 +- dirmngr/dns-stuff.c | 4 ++-- dirmngr/http.c | 2 +- dirmngr/ks-engine-ldap.c | 2 +- dirmngr/server.c | 2 +- doc/DETAILS | 6 +++--- doc/TRANSLATE | 2 +- doc/dirmngr.texi | 6 +++--- doc/faq.org | 4 ++-- doc/gpg-agent.texi | 6 +++--- doc/gpg.texi | 4 ++-- doc/gpgsm.texi | 2 +- doc/scdaemon.texi | 2 +- doc/vuln-announce-2007-multiple-message.txt | 2 +- doc/whats-new-in-2.1.txt | 6 +++--- g10/armor.c | 2 +- g10/build-packet.c | 2 +- g10/call-agent.c | 2 +- g10/card-util.c | 2 +- g10/compress.c | 2 +- g10/encrypt.c | 6 +++--- g10/export.c | 2 +- g10/getkey.c | 2 +- g10/import.c | 2 +- g10/keydb.c | 2 +- g10/keyedit.c | 4 ++-- g10/keygen.c | 2 +- g10/keyid.c | 2 +- g10/keyring.c | 2 +- g10/mainproc.c | 4 ++-- g10/misc.c | 2 +- g10/pkclist.c | 2 +- g10/pubkey-enc.c | 2 +- g10/revoke.c | 2 +- g10/rmd160.c | 2 +- g10/tofu.c | 2 +- g10/trust.c | 2 +- g10/trustdb.c | 2 +- g13/g13-syshelp.h | 2 +- g13/server.c | 2 +- g13/sh-cmd.c | 2 +- kbx/keybox-blob.c | 4 ++-- m4/autobuild.m4 | 2 +- m4/gettext.m4 | 4 ++-- m4/intl.m4 | 4 ++-- m4/intldir.m4 | 4 ++-- m4/lcmessage.m4 | 4 ++-- m4/nls.m4 | 4 ++-- m4/po.m4 | 4 ++-- m4/progtest.m4 | 4 ++-- scd/apdu.c | 2 +- scd/app-dinsig.c | 2 +- scd/app-geldkarte.c | 2 +- scd/app-nks.c | 2 +- scd/app-openpgp.c | 4 ++-- scd/ccid-driver.c | 4 ++-- scd/command.c | 6 +++--- sm/call-dirmngr.c | 2 +- sm/certchain.c | 2 +- sm/certdump.c | 2 +- sm/certlist.c | 2 +- sm/keydb.c | 2 +- sm/keylist.c | 2 +- tests/gpgscm/main.c | 2 +- tests/openpgp/defs.scm | 2 +- tests/openpgp/verify.scm | 2 +- tools/gpg-connect-agent.c | 2 +- tools/gpg-wks-client.c | 2 +- tools/gpg-wks-server.c | 6 +++--- tools/gpgconf.c | 2 +- tools/gpgparsemail.c | 2 +- tools/gpgtar.c | 4 ++-- tools/mail-signed-keys | 2 +- tools/symcryptrun.c | 4 ++-- 99 files changed, 143 insertions(+), 143 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 20:21:51 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 20:21:51 +0100 Subject: [git] NTBTLS - branch, master, updated. 8d98665dc2a1d7876f9841d4788c4ea4c710270b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via 8d98665dc2a1d7876f9841d4788c4ea4c710270b (commit) via 50ad7a2206bac7682195e8285af96e0d790891b3 (commit) from d7a441e28bd0962030d4bb00f626f56d46315a78 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8d98665dc2a1d7876f9841d4788c4ea4c710270b Author: Werner Koch Date: Tue Feb 21 20:17:58 2017 +0100 Post release updates. -- diff --git a/NEWS b/NEWS index ac70e1c..4786e9a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 0.1.1 (unreleased) [C0/A0/R_] +------------------------------------------------ + + Noteworthy changes in version 0.1.0 (2017-02-21) [C0/A0/R0] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 7fe9e1c..9edb53f 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -min_automake_version="1.11" +min_automake_version="1.14" # To build a release you need to create a tag with the version number # (git tag -s gnupg-2.n.m) and run "./autogen.sh --force". Please @@ -27,7 +27,7 @@ min_automake_version="1.11" m4_define([mym4_package],[ntbtls]) m4_define([mym4_major], [0]) m4_define([mym4_minor], [1]) -m4_define([mym4_micro], [0]) +m4_define([mym4_micro], [1]) # 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 @@ -78,8 +78,6 @@ VERSION=$PACKAGE_VERSION AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_SRCDIR([src/ntbtls.h.in]) AC_CONFIG_HEADER([config.h]) -# Note: For automake 1.13 add the option -# serial-tests AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip]) AC_CANONICAL_HOST AC_GNU_SOURCE commit 50ad7a2206bac7682195e8285af96e0d790891b3 Author: Werner Koch Date: Tue Feb 21 19:55:58 2017 +0100 Release 0.1.0 Signed-off-by: Werner Koch diff --git a/Makefile.am b/Makefile.am index eb0692c..21fa90b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,6 @@ ## Process this file with automake to produce Makefile.in ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = dist-bzip2 DISTCHECK_CONFIGURE_FLAGS = # (A suitable gitlog-to-changelog script can be found in GnuPG master.) @@ -33,6 +32,22 @@ EXTRA_DIST = autogen.sh autogen.rc README.GIT VERSION \ DISTCLEANFILES = +dist-hook: gen-ChangeLog + +distcheck-hook: + set -e; ( \ + pref="#+macro: ntbtls_" ;\ + 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 + .PHONY: gen-ChangeLog gen-ChangeLog: diff --git a/NEWS b/NEWS index f760120..ac70e1c 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Noteworthy changes in version 0.1.0 (unreleased) [C0/A0/R0] +Noteworthy changes in version 0.1.0 (2017-02-21) [C0/A0/R0] ------------------------------------------------ * Initial experimental release with only the client code. diff --git a/README b/README index 9c4f706..45fd7be 100644 --- a/README +++ b/README @@ -2,5 +2,10 @@ Not Too Bad Transport Layer Security Version 0.1 + WARNING: Although this library is based on PolarSSL code it is + pretty young and NOT WELL TESTED. There are lot of things missing + and we release it only to get pratical experience with its use. + More releases can be expected in the near future. + See the file AUTHORS for copying conditions. See HACKING for internals. diff --git a/configure.ac b/configure.ac index cfd8905..7fe9e1c 100644 --- a/configure.ac +++ b/configure.ac @@ -80,7 +80,7 @@ AC_CONFIG_SRCDIR([src/ntbtls.h.in]) AC_CONFIG_HEADER([config.h]) # Note: For automake 1.13 add the option # serial-tests -AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip]) +AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip]) AC_CANONICAL_HOST AC_GNU_SOURCE diff --git a/src/ntbtls.h.in b/src/ntbtls.h.in index 6262cfb..899e8b2 100644 --- a/src/ntbtls.h.in +++ b/src/ntbtls.h.in @@ -1,5 +1,5 @@ /* ntbtls.h - Not Too Bad TLS -*- c -*- - * Copyright (C) 2014, 2017 g10 Code GmbH + * Copyright (C) 2014-2017 g10 Code GmbH * * This file is part of NTBTLS * @@ -32,15 +32,21 @@ extern "C" { #endif #endif -/* The version of this header should match the one of the library. It - should not be used by a program because ntbtls_check_version() - should return the same version. The purpose of this macro is to - let autoconf (using the AM_PATH_NTBTLS macro) check that this - header matches the installed library. */ +/* + * The version of this header file. + * + * A program should better the fucntion ntbtls_check_version() which + * will return the actual version of the library. The sole purpose of + * this macro is to let autoconf (using the AM_PATH_NTBTLS macro) + * check that this header matches the installed library. + */ #define NTBTLS_VERSION "@VERSION@" -/* The version number of this header. It may be used to handle minor - API incompatibilities. */ +/* + * The version number of this header. + * + * It may be used to handle minor API incompatibilities. +*/ #define NTBTLS_VERSION_NUMBER @VERSION_NUMBER@ @@ -54,12 +60,14 @@ extern "C" { struct _ntbtls_context_s; typedef struct _ntbtls_context_s *ntbtls_t; + /* - * The type of the verification callback. This must be registered - * prior to the handshake and will be called by ntbltls when a peer's - * certificate needs to be verified. OPAQUE is the vale set when the - * callback has been set. TLS is the respective TLS context. - * VERIFY_FLAGS are not yet defined flags. + * The type of the verification callback. + * + * This must be registered prior to the handshake and will be called + * by ntbltls when a peer's certificate needs to be verified. OPAQUE + * is the vale set when the callback has been set. TLS is the + * respective TLS context. VERIFY_FLAGS are not yet defined flags. */ typedef gpg_error_t (*ntbtls_verify_cb_t) (void *opaque, ntbtls_t tls, ----------------------------------------------------------------------- Summary of changes: Makefile.am | 17 ++++++++++++++++- NEWS | 6 +++++- README | 5 +++++ configure.ac | 8 +++----- src/ntbtls.h.in | 34 +++++++++++++++++++++------------- 5 files changed, 50 insertions(+), 20 deletions(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 21 20:57:13 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 21 Feb 2017 20:57:13 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-118-g7742455 Message-ID: This is an 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 774245508920eccb6a28b719a5cde26861800c60 (commit) from ccb420380b2f23f1bd28b17e6a4233c86291887d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 774245508920eccb6a28b719a5cde26861800c60 Author: Werner Koch Date: Tue Feb 21 20:53:20 2017 +0100 speedo: Now build for W32 with ntbtls support. -- Signed-off-by: Werner Koch diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 1adcabe..c799863 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -191,7 +191,15 @@ endif endif speedo_spkgs += \ - libassuan libksba gnupg + libassuan libksba + +ifeq ($(TARGETOS),w32) +speedo_spkgs += \ + ntbtls +endif + +speedo_spkgs += \ + gnupg ifeq ($(TARGETOS),w32) ifeq ($(WITH_GUI),1) @@ -241,7 +249,7 @@ endif # Packages which use the gnupg autogen.sh build style speedo_gnupg_style = \ libgpg-error npth libgcrypt \ - libassuan libksba gnupg gpgme \ + libassuan libksba ntbtls gnupg gpgme \ pinentry gpa gpgex # Packages which use only make and no build directory @@ -290,6 +298,10 @@ libksba_ver := $(shell awk '$$1=="libksba_ver" {print $$2}' swdb.lst) libksba_sha1 := $(shell awk '$$1=="libksba_sha1" {print $$2}' swdb.lst) libksba_sha2 := $(shell awk '$$1=="libksba_sha2" {print $$2}' swdb.lst) +ntbtls_ver := $(shell awk '$$1=="ntbtls_ver" {print $$2}' swdb.lst) +ntbtls_sha1 := $(shell awk '$$1=="ntbtls_sha1" {print $$2}' swdb.lst) +ntbtls_sha2 := $(shell awk '$$1=="ntbtls_sha2" {print $$2}' swdb.lst) + gpgme_ver := $(shell awk '$$1=="gpgme_ver" {print $$2}' swdb.lst) gpgme_sha1 := $(shell awk '$$1=="gpgme_sha1" {print $$2}' swdb.lst) gpgme_sha2 := $(shell awk '$$1=="gpgme_sha2" {print $$2}' swdb.lst) @@ -325,9 +337,11 @@ $(info Libgpg-error ...: $(libgpg_error_ver)) $(info Npth ...........: $(npth_ver)) $(info Libgcrypt ......: $(libgcrypt_ver)) $(info Libassuan ......: $(libassuan_ver)) +$(info Libksba ........: $(libksba_ver)) $(info Zlib ...........: $(zlib_ver)) $(info Bzip2 ..........: $(bzip2_ver)) $(info SQLite .........: $(sqlite_ver)) +$(info NtbTLS .. ......: $(ntbtls_ver)) $(info GPGME ..........: $(gpgme_ver)) $(info Pinentry .......: $(pinentry_ver)) $(info GPA ............: $(gpa_ver)) @@ -391,6 +405,8 @@ else ifeq ($(WHAT),git) speedo_pkg_libgcrypt_gitref = master speedo_pkg_libksba_git = $(gitrep)/libksba speedo_pkg_libksba_gitref = master + speedo_pkg_ntbtls_git = $(gitrep)/ntbtls + speedo_pkg_ntbtls_gitref = master speedo_pkg_gpgme_git = $(gitrep)/gpgme speedo_pkg_gpgme_gitref = master speedo_pkg_pinentry_git = $(gitrep)/pinentry @@ -410,6 +426,8 @@ else ifeq ($(WHAT),release) $(pkgrep)/libgcrypt/libgcrypt-$(libgcrypt_ver).tar.bz2 speedo_pkg_libksba_tar = \ $(pkgrep)/libksba/libksba-$(libksba_ver).tar.bz2 + speedo_pkg_ntbtls_tar = \ + $(pkgrep)/ntbtls/ntbtls-$(ntbtls_ver).tar.bz2 speedo_pkg_gpgme_tar = \ $(pkgrep)/gpgme/gpgme-$(gpgme_ver).tar.bz2 speedo_pkg_pinentry_tar = \ @@ -453,9 +471,12 @@ speedo_pkg_libgcrypt_configure = --disable-static speedo_pkg_libksba_configure = --disable-static +# For now we build ntbtls only static +speedo_pkg_ntbtls_configure = --enable-static --disable-shared + ifeq ($(TARGETOS),w32) speedo_pkg_gnupg_configure = \ - --enable-gpg2-is-gpg --disable-g13 --disable-ntbtls \ + --enable-gpg2-is-gpg --disable-g13 --enable-ntbtls \ --enable-build-timestamp else speedo_pkg_gnupg_configure = --disable-g13 ----------------------------------------------------------------------- Summary of changes: build-aux/speedo.mk | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 22 05:05:03 2017 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 22 Feb 2017 05:05:03 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-119-gef42435 Message-ID: This is an 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 ef424353f342f80ca6d18ede8b63c1b02215d105 (commit) from 774245508920eccb6a28b719a5cde26861800c60 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ef424353f342f80ca6d18ede8b63c1b02215d105 Author: NIIBE Yutaka Date: Wed Feb 22 13:03:33 2017 +0900 tests: No spelling fix for test text. * tests/openpgp/verify.scm (msg_ed25519_rshort): Revert the spelling fix. Signed-off-by: NIIBE Yutaka diff --git a/tests/openpgp/verify.scm b/tests/openpgp/verify.scm index 9b82827..d3bd763 100755 --- a/tests/openpgp/verify.scm +++ b/tests/openpgp/verify.scm @@ -243,6 +243,9 @@ FWIAQUplk7JWbyRKAJ92ZJyJpWfzb0yc1s7MY65r2qEHrg== ;; 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. +;; +;; Note that the message has a typo ("the the"), but this should not +;; be fixed because it breaks this test. (define msg_ed25519_rshort " -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 @@ -269,7 +272,7 @@ 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 article to the reader once! Don't tolerate this. +will only show the the article to the reader once! Don't tolerate this. -- Emily Postnews Answers Your Questions on Netiquette -----BEGIN PGP SIGNATURE----- ----------------------------------------------------------------------- Summary of changes: tests/openpgp/verify.scm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 22 11:07:49 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 22 Feb 2017 11:07:49 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-121-g6488ffb Message-ID: This is an 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 6488ffb767733a2cf92ca5ba3e61fc0c53e0f673 (commit) via 78d875a0f83bc046279b951aea76cd74f3c44fd8 (commit) from ef424353f342f80ca6d18ede8b63c1b02215d105 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6488ffb767733a2cf92ca5ba3e61fc0c53e0f673 Author: Werner Koch Date: Wed Feb 22 11:04:55 2017 +0100 agent: Prepend the description to a PIN prompt. * agent/divert-scd.c (has_percent0A_suffix): New. (getpin_cb): Prepend DESC_TEXT to the prompt. * agent/findkey.c (modify_description): Rename to ... (agent_modify_description): this. MAke global. Add kludge to remove empty parentheses from the end. (agent_key_from_file, agent_delete_key): Adjust for above change. * agent/pksign.c (agent_pksign_do): Modify DESC_TEXT also when diverting to a card. -- Now that we have support for multiple tokens, it is important to show information on which key has been requested. Without that it may happen that the PIN for a wrong card is accidentally entered. The texts are a bit ugly, because they talk about "passphrase" but later about entering a PIN. A quick hack would be to s/passphrase/PIN/ in the description but that is complicated due to i18n. Another solution might be never to talk about PINs in the description but always about "passphrase: and only use "PIN" or "passphrase" on the left of the entry field. diff --git a/agent/agent.h b/agent/agent.h index 22a4d43..e98a246 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -381,6 +381,8 @@ gpg_error_t ssh_search_control_file (ssh_control_file_t cf, void start_command_handler_ssh (ctrl_t, gnupg_fd_t); /*-- findkey.c --*/ +gpg_error_t agent_modify_description (const char *in, const char *comment, + const gcry_sexp_t key, char **result); int agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force); gpg_error_t agent_key_from_file (ctrl_t ctrl, diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 5ffb7ea..3164404 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -157,6 +157,18 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, } +/* Return true if STRING ends in "%0A". */ +static int +has_percent0A_suffix (const char *string) +{ + size_t n; + + return (string + && (n = strlen (string)) >= 3 + && !strcmp (string + n - 3, "%0A")); +} + + /* Callback used to ask for the PIN which should be set into BUF. The buf has been allocated by the caller and is of size MAXBUF which includes the terminating null. The function should return an UTF-8 @@ -246,7 +258,7 @@ getpin_cb (void *opaque, const char *desc_text, const char *info, { if (info) { - char *desc; + char *desc, *desc2; if ( asprintf (&desc, L_("%s%%0A%%0AUse the reader's pinpad for input."), @@ -254,12 +266,22 @@ getpin_cb (void *opaque, const char *desc_text, const char *info, rc = gpg_error_from_syserror (); else { - rc = agent_popup_message_start (ctrl, desc, NULL); + /* Prepend DESC_TEXT to INFO. */ + if (desc_text) + desc2 = strconcat (desc_text, + has_percent0A_suffix (desc_text) + ? "%0A" : "%0A%0A", + desc, NULL); + else + desc2 = NULL; + rc = agent_popup_message_start (ctrl, + desc2? desc2:desc, NULL); + xfree (desc2); xfree (desc); } } else - rc = agent_popup_message_start (ctrl, NULL, NULL); + rc = agent_popup_message_start (ctrl, desc_text, NULL); } else rc = gpg_error (GPG_ERR_INV_VALUE); @@ -280,7 +302,19 @@ getpin_cb (void *opaque, const char *desc_text, const char *info, if (any_flags) { - rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL, 0); + { + char *desc2; + + if (desc_text) + desc2 = strconcat (desc_text, + has_percent0A_suffix (desc_text) + ? "%0A" : "%0A%0A", + info, NULL); + else + desc2 = NULL; + rc = agent_askpin (ctrl, desc2, prompt, again_text, pi, NULL, 0); + xfree (desc2); + } again_text = NULL; if (!rc && newpin) { @@ -319,14 +353,24 @@ getpin_cb (void *opaque, const char *desc_text, const char *info, } else { - char *desc; + char *desc, *desc2; + if ( asprintf (&desc, L_("Please enter the PIN%s%s%s to unlock the card"), info? " (":"", info? info:"", info? ")":"") < 0) desc = NULL; - rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL, 0); + if (desc_text) + desc2 = strconcat (desc_text, + has_percent0A_suffix (desc_text) + ? "%0A" : "%0A%0A", + desc, NULL); + else + desc2 = NULL; + rc = agent_askpin (ctrl, desc2? desc2 : desc? desc : info, + prompt, NULL, pi, NULL, 0); + xfree (desc2); xfree (desc); } diff --git a/agent/findkey.c b/agent/findkey.c index 698f765..ac74fa9 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -321,9 +321,9 @@ try_unprotect_cb (struct pin_entry_info_s *pi) The functions returns 0 on success or an error code. On success a newly allocated string is stored at the address of RESULT. */ -static gpg_error_t -modify_description (const char *in, const char *comment, const gcry_sexp_t key, - char **result) +gpg_error_t +agent_modify_description (const char *in, const char *comment, + const gcry_sexp_t key, char **result) { size_t comment_length; size_t in_len; @@ -332,12 +332,19 @@ modify_description (const char *in, const char *comment, const gcry_sexp_t key, size_t i; int special, pass; char *ssh_fpr = NULL; + char *p; + + *result = NULL; + + if (!comment) + comment = ""; comment_length = strlen (comment); in_len = strlen (in); /* First pass calculates the length, second pass does the actual copying. */ + /* FIXME: This can be simplified by using es_fopenmem. */ out = NULL; out_len = 0; for (pass=0; pass < 2; pass++) @@ -427,8 +434,23 @@ modify_description (const char *in, const char *comment, const gcry_sexp_t key, } *out = 0; - assert (*result + out_len == out); + log_assert (*result + out_len == out); xfree (ssh_fpr); + + /* The ssh prompt may sometimes end in + * "...%0A ()" + * The empty parentheses doesn't look very good. We use this hack + * here to remove them as well as the indentation spaces. */ + p = *result; + i = strlen (p); + if (i > 2 && !strcmp (p + i - 2, "()")) + { + p += i - 2; + *p-- = 0; + while (p > *result && spacep (p)) + *p-- = 0; + } + return 0; } @@ -874,8 +896,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, desc_text_final = NULL; if (desc_text) - rc = modify_description (desc_text, comment? comment:"", s_skey, - &desc_text_final); + rc = agent_modify_description (desc_text, comment, s_skey, + &desc_text_final); gcry_free (comment); if (!rc) @@ -1453,8 +1475,8 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, } if (desc_text) - err = modify_description (desc_text, comment? comment:"", s_skey, - &desc_text_final); + err = agent_modify_description (desc_text, comment, s_skey, + &desc_text_final); if (err) goto leave; diff --git a/agent/pksign.c b/agent/pksign.c index 4a5daed..3b2fcc4 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -285,7 +285,8 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, cache_mode_t cache_mode, lookup_ttl_t lookup_ttl, const void *overridedata, size_t overridedatalen) { - gcry_sexp_t s_skey = NULL, s_sig = NULL; + gcry_sexp_t s_skey = NULL; + gcry_sexp_t s_sig = NULL; gcry_sexp_t s_hash = NULL; gcry_sexp_t s_pkey = NULL; unsigned char *shadow_info = NULL; @@ -346,10 +347,18 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, is_ECDSA = 1; } - rc = divert_pksign (ctrl, desc_text, - data, datalen, - ctrl->digest.algo, - shadow_info, &buf, &len); + { + char *desc2 = NULL; + + if (desc_text) + agent_modify_description (desc_text, NULL, s_skey, &desc2); + + rc = divert_pksign (ctrl, desc2? desc2 : desc_text, + data, datalen, + ctrl->digest.algo, + shadow_info, &buf, &len); + xfree (desc2); + } if (rc) { log_error ("smartcard signing failed: %s\n", gpg_strerror (rc)); commit 78d875a0f83bc046279b951aea76cd74f3c44fd8 Author: Werner Koch Date: Wed Feb 22 09:40:50 2017 +0100 agent: Prepare to pass an additional parameter to the getpin callback. * agent/call-scd.c (writekey_parm_s, inq_needpin_s): Merge into ... (inq_needpin_parm_s): new struct. Add new field 'getpin_cb_desc'. Change users to set all fields. (inq_needpin): Pass GETPIN_CB_DESC to the GETPIN_CB. (agent_card_pksign): Add arg 'desc_text' and change arg 'getpin_cb' to take an additional arg 'desc_text'. (agent_card_pkdecrypt): Ditto. (agent_card_writekey): Change arg 'getpin_cb' to take an additional arg 'desc_text'. (agent_card_scd): Ditto. * agent/divert-scd.c (getpin_cb): Add new arg 'desc_text'. (divert_pksign): Add new arg 'desc_text' and pass is to agent_card_pksign. (divert_pkdecrypt): Add new arg 'desc_text' and pass is to agent_card_pkdecrypt. * agent/pkdecrypt.c (agent_pkdecrypt): Pass DESC_TEXT to divert_pkdecrypt. * agent/pksign.c (agent_pksign_do): Pass DESC_TEXT to divert_pksign. -- Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 2a722fd..22a4d43 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -505,11 +505,11 @@ void agent_reload_trustlist (void); /*-- divert-scd.c --*/ -int divert_pksign (ctrl_t ctrl, +int divert_pksign (ctrl_t ctrl, const char *desc_text, const unsigned char *digest, size_t digestlen, int algo, const unsigned char *shadow_info, unsigned char **r_sig, size_t *r_siglen); -int divert_pkdecrypt (ctrl_t ctrl, +int divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *cipher, const unsigned char *shadow_info, char **r_buf, size_t *r_len, int *r_padding); @@ -536,15 +536,19 @@ int agent_card_learn (ctrl_t ctrl, int agent_card_serialno (ctrl_t ctrl, char **r_serialno, const char *demand); int agent_card_pksign (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, + const char *desc_text, int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen); int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*,size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*,size_t), void *getpin_cb_arg, + const char *desc_text, const unsigned char *indata, size_t indatalen, char **r_buf, size_t *r_buflen, int *r_padding); int agent_card_readcert (ctrl_t ctrl, @@ -553,12 +557,14 @@ int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf); int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, const char *id, const char *keydata, size_t keydatalen, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg); gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result); gpg_error_t agent_card_cardlist (ctrl_t ctrl, strlist_t *result); int agent_card_scd (ctrl_t ctrl, const char *cmdline, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, void *assuan_context); diff --git a/agent/call-scd.c b/agent/call-scd.c index 8d46b90..c86eb74 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -79,14 +79,21 @@ struct learn_parm_s void *sinfo_cb_arg; }; -struct inq_needpin_s + +/* Callback parameter used by inq_getpin and inq_writekey_parms. */ +struct inq_needpin_parm_s { assuan_context_t ctx; - int (*getpin_cb)(void *, const char *, char*, size_t); + int (*getpin_cb)(void *, const char *, const char *, char*, size_t); void *getpin_cb_arg; + const char *getpin_cb_desc; assuan_context_t passthru; /* If not NULL, pass unknown inquiries up to the caller. */ int any_inq_seen; + + /* The next fields are used by inq_writekey_parm. */ + const unsigned char *keydata; + size_t keydatalen; }; @@ -714,7 +721,7 @@ agent_card_serialno (ctrl_t ctrl, char **r_serialno, const char *demand) static gpg_error_t inq_needpin (void *opaque, const char *line) { - struct inq_needpin_s *parm = opaque; + struct inq_needpin_parm_s *parm = opaque; const char *s; char *pin; size_t pinlen; @@ -729,18 +736,21 @@ inq_needpin (void *opaque, const char *line) if (!pin) return out_of_core (); - rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen); + rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, + line, pin, pinlen); if (!rc) rc = assuan_send_data (parm->ctx, pin, pinlen); xfree (pin); } else if ((s = has_leading_keyword (line, "POPUPPINPADPROMPT"))) { - rc = parm->getpin_cb (parm->getpin_cb_arg, s, NULL, 1); + rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, + s, NULL, 1); } else if ((s = has_leading_keyword (line, "DISMISSPINPADPROMPT"))) { - rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0); + rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, + "", NULL, 0); } else if (parm->passthru) { @@ -824,13 +834,17 @@ cancel_inquire (ctrl_t ctrl, gpg_error_t rc) return rc; } + /* Create a signature using the current card. MDALGO is either 0 or - gives the digest algorithm. */ + * gives the digest algorithm. DESC_TEXT is an additional parameter + * passed to GETPIN_CB. */ int agent_card_pksign (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, + const char *desc_text, int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen) @@ -838,7 +852,7 @@ agent_card_pksign (ctrl_t ctrl, int rc; char line[ASSUAN_LINELENGTH]; membuf_t data; - struct inq_needpin_s inqparm; + struct inq_needpin_parm_s inqparm; *r_buf = NULL; rc = start_scd (ctrl); @@ -859,8 +873,12 @@ agent_card_pksign (ctrl_t ctrl, inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; inqparm.any_inq_seen = 0; + inqparm.keydata = NULL; + inqparm.keydatalen = 0; + if (ctrl->use_auth_call) snprintf (line, sizeof line, "PKAUTH %s", keyid); else @@ -906,21 +924,24 @@ padding_info_cb (void *opaque, const char *line) /* Decipher INDATA using the current card. Note that the returned - value is not an s-expression but the raw data as returned by - scdaemon. The padding information is stored at R_PADDING with -1 - for not known. */ + * value is not an s-expression but the raw data as returned by + * scdaemon. The padding information is stored at R_PADDING with -1 + * for not known. DESC_TEXT is an additional parameter passed to + * GETPIN_CB. */ int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, + const char *desc_text, const unsigned char *indata, size_t indatalen, char **r_buf, size_t *r_buflen, int *r_padding) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; membuf_t data; - struct inq_needpin_s inqparm; + struct inq_needpin_parm_s inqparm; size_t len; *r_buf = NULL; @@ -951,8 +972,11 @@ agent_card_pkdecrypt (ctrl_t ctrl, inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; inqparm.any_inq_seen = 0; + inqparm.keydata = NULL; + inqparm.keydatalen = 0; snprintf (line, DIM(line), "PKDECRYPT %s", keyid); rc = assuan_transact (ctrl->scd_local->ctx, line, put_membuf_cb, &data, @@ -1051,24 +1075,12 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf) } -struct writekey_parm_s -{ - assuan_context_t ctx; - int (*getpin_cb)(void *, const char *, char*, size_t); - void *getpin_cb_arg; - assuan_context_t passthru; - int any_inq_seen; - /**/ - const unsigned char *keydata; - size_t keydatalen; -}; - /* Handle a KEYDATA inquiry. Note, we only send the data, assuan_transact takes care of flushing and writing the end */ static gpg_error_t inq_writekey_parms (void *opaque, const char *line) { - struct writekey_parm_s *parm = opaque; + struct inq_needpin_parm_s *parm = opaque; if (has_leading_keyword (line, "KEYDATA")) return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen); @@ -1080,12 +1092,13 @@ inq_writekey_parms (void *opaque, const char *line) int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, const char *id, const char *keydata, size_t keydatalen, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg) { int rc; char line[ASSUAN_LINELENGTH]; - struct writekey_parm_s parms; + struct inq_needpin_parm_s parms; (void)serialno; rc = start_scd (ctrl); @@ -1096,6 +1109,7 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, parms.ctx = ctrl->scd_local->ctx; parms.getpin_cb = getpin_cb; parms.getpin_cb_arg = getpin_cb_arg; + parms.getpin_cb_desc= NULL; parms.passthru = 0; parms.any_inq_seen = 0; parms.keydata = keydata; @@ -1108,6 +1122,8 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, rc = cancel_inquire (ctrl, rc); return unlock_scd (ctrl, rc); } + + /* Type used with the card_getattr_cb. */ struct card_getattr_parm_s { @@ -1190,6 +1206,8 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result) return unlock_scd (ctrl, err); } + + struct card_cardlist_parm_s { int error; @@ -1258,6 +1276,8 @@ agent_card_cardlist (ctrl_t ctrl, strlist_t *result) return unlock_scd (ctrl, err); } + + static gpg_error_t pass_status_thru (void *opaque, const char *line) @@ -1307,11 +1327,12 @@ pass_data_thru (void *opaque, const void *buffer, size_t length) inquiry is handled inside gpg-agent. */ int agent_card_scd (ctrl_t ctrl, const char *cmdline, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, void *assuan_context) { int rc; - struct inq_needpin_s inqparm; + struct inq_needpin_parm_s inqparm; int saveflag; rc = start_scd (ctrl); @@ -1321,8 +1342,12 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline, inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.getpin_cb_desc = NULL; inqparm.passthru = assuan_context; inqparm.any_inq_seen = 0; + inqparm.keydata = NULL; + inqparm.keydatalen = 0; + saveflag = assuan_get_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS); assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, 1); rc = assuan_transact (ctrl->scd_local->ctx, cmdline, diff --git a/agent/divert-scd.c b/agent/divert-scd.c index c23c673..5ffb7ea 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -163,6 +163,9 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, string with the passphrase, the buffer may optionally be padded with arbitrary characters. + If DESC_TEXT is not NULL it can be used as further informtion shown + atop of the INFO message. + INFO gets displayed as part of a generic string. However if the first character of INFO is a vertical bar all up to the next verical bar are considered flags and only everything after the @@ -185,7 +188,8 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, are considered. */ static int -getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) +getpin_cb (void *opaque, const char *desc_text, const char *info, + char *buf, size_t maxbuf) { struct pin_entry_info_s *pi; int rc; @@ -337,9 +341,13 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) - +/* This function is used when a sign operation has been diverted to a + * smartcard. DESC_TEXT is the original text for a prompt has send by + * gpg to gpg-agent. + * + * FIXME: Explain the other args. */ int -divert_pksign (ctrl_t ctrl, +divert_pksign (ctrl_t ctrl, const char *desc_text, const unsigned char *digest, size_t digestlen, int algo, const unsigned char *shadow_info, unsigned char **r_sig, size_t *r_siglen) @@ -357,7 +365,7 @@ divert_pksign (ctrl_t ctrl, { int save = ctrl->use_auth_call; ctrl->use_auth_call = 1; - rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text, algo, digest, digestlen, &sigval, &siglen); ctrl->use_auth_call = save; } @@ -369,7 +377,7 @@ divert_pksign (ctrl_t ctrl, rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata); if (!rc) { - rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text, algo, data, ndata, &sigval, &siglen); xfree (data); } @@ -392,7 +400,7 @@ divert_pksign (ctrl_t ctrl, allocated buffer in R_BUF. The padding information is stored at R_PADDING with -1 for not known. */ int -divert_pkdecrypt (ctrl_t ctrl, +divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *cipher, const unsigned char *shadow_info, char **r_buf, size_t *r_len, int *r_padding) @@ -471,7 +479,7 @@ divert_pkdecrypt (ctrl_t ctrl, if (rc) return rc; - rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, + rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, desc_text, ciphertext, ciphertextlen, &plaintext, &plaintextlen, r_padding); if (!rc) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 3d0f5aa..f1023b4 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -86,7 +86,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, + rc = divert_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info, &buf, &len, r_padding); if (rc) { diff --git a/agent/pksign.c b/agent/pksign.c index b347608..4a5daed 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -346,7 +346,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, is_ECDSA = 1; } - rc = divert_pksign (ctrl, + rc = divert_pksign (ctrl, desc_text, data, datalen, ctrl->digest.algo, shadow_info, &buf, &len); ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 20 +++++++++---- agent/call-scd.c | 87 +++++++++++++++++++++++++++++++++++------------------- agent/divert-scd.c | 78 ++++++++++++++++++++++++++++++++++++++++-------- agent/findkey.c | 38 +++++++++++++++++++----- agent/pkdecrypt.c | 2 +- agent/pksign.c | 19 ++++++++---- 6 files changed, 180 insertions(+), 64 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 22 15:51:59 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 22 Feb 2017 15:51:59 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-122-ge3944f3 Message-ID: This is an 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 e3944f34e3220f96fb1be449eb6f3d7360bc2d0b (commit) from 6488ffb767733a2cf92ca5ba3e61fc0c53e0f673 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e3944f34e3220f96fb1be449eb6f3d7360bc2d0b Author: Werner Koch Date: Wed Feb 22 13:03:52 2017 +0100 scd: Improve the prompts for OpenPGP cards. * scd/app-openpgp.c (get_disp_name): New. (get_disp_serialno): New. (get_prompt_info): New. (build_enter_admin_pin_prompt): Rework the prompt texts. Factor some code out to ... (get_remaining_tries): New. (verify_a_chv): Print a remaining counter also for the standard PIN. Rework the prompt texts. * agent/divert-scd.c (ask_for_card): Pretty format an OpenPGP serial no. Signed-off-by: Werner Koch diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 3164404..d9d734c 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -39,22 +39,39 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid) char *serialno; int no_card = 0; char *desc; - char *want_sn, *want_kid; - int want_sn_displen; + char *want_sn, *want_kid, *want_sn_disp; + int len; *r_kid = NULL; rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL); if (rc) return rc; + want_sn_disp = xtrystrdup (want_sn); + if (!want_sn_disp) + { + rc = gpg_error_from_syserror (); + xfree (want_sn); + return rc; + } - /* We assume that a 20 byte serial number is a standard one which - has the property to have a zero in the last nibble (Due to BCD - representation). We don't display this '0' because it may - confuse the user. */ - want_sn_displen = strlen (want_sn); - if (want_sn_displen == 20 && want_sn[19] == '0') - want_sn_displen--; + len = strlen (want_sn_disp); + if (len == 32 && !strncmp (want_sn_disp, "D27600012401", 12)) + { + /* This is an OpenPGP card - reformat */ + memmove (want_sn_disp, want_sn_disp+16, 4); + want_sn_disp[4] = ' '; + memmove (want_sn_disp+5, want_sn_disp+20, 8); + want_sn_disp[13] = 0; + } + else if (len == 20 && want_sn_disp[19] == '0') + { + /* We assume that a 20 byte serial number is a standard one + * which has the property to have a zero in the last nibble (Due + * to BCD representation). We don't display this '0' because it + * may confuse the user. */ + want_sn_disp[19] = 0; + } for (;;) { @@ -93,12 +110,12 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid) { if (asprintf (&desc, "%s:%%0A%%0A" - " \"%.*s\"", + " %s", no_card ? L_("Please insert the card with serial number") : L_("Please remove the current card and " "insert the one with serial number"), - want_sn_displen, want_sn) < 0) + want_sn_disp) < 0) { rc = out_of_core (); } @@ -114,6 +131,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid) } if (rc) { + xfree (want_sn_disp); xfree (want_sn); xfree (want_kid); return rc; @@ -312,7 +330,8 @@ getpin_cb (void *opaque, const char *desc_text, const char *info, info, NULL); else desc2 = NULL; - rc = agent_askpin (ctrl, desc2, prompt, again_text, pi, NULL, 0); + rc = agent_askpin (ctrl, desc2? desc2 : info, + prompt, again_text, pi, NULL, 0); xfree (desc2); } again_text = NULL; @@ -401,6 +420,8 @@ divert_pksign (ctrl_t ctrl, const char *desc_text, size_t siglen; unsigned char *sigval = NULL; + (void)desc_text; + rc = ask_for_card (ctrl, shadow_info, &kid); if (rc) return rc; @@ -409,7 +430,7 @@ divert_pksign (ctrl_t ctrl, const char *desc_text, { int save = ctrl->use_auth_call; ctrl->use_auth_call = 1; - rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text, + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, NULL, algo, digest, digestlen, &sigval, &siglen); ctrl->use_auth_call = save; } @@ -421,7 +442,7 @@ divert_pksign (ctrl_t ctrl, const char *desc_text, rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata); if (!rc) { - rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text, + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, NULL, algo, data, ndata, &sigval, &siglen); xfree (data); } @@ -458,6 +479,8 @@ divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, char *plaintext; size_t plaintextlen; + (void)desc_text; + *r_padding = -1; s = cipher; @@ -523,7 +546,7 @@ divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, if (rc) return rc; - rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, desc_text, + rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, NULL, ciphertext, ciphertextlen, &plaintext, &plaintextlen, r_padding); if (!rc) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 608e3cc..90c2661 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1082,6 +1082,104 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) return rc; } + +/* Return the DISP-NAME without any padding characters. Caller must + * free the result. If not found or empty NULL is returned. */ +static char * +get_disp_name (app_t app) +{ + int rc; + void *relptr; + unsigned char *value; + size_t valuelen; + char *string; + char *p, *given; + char *result; + + relptr = get_one_do (app, 0x005B, &value, &valuelen, &rc); + if (!relptr) + return NULL; + + string = xtrymalloc (valuelen + 1); + if (!string) + { + xfree (relptr); + return NULL; + } + memcpy (string, value, valuelen); + string[valuelen] = 0; + xfree (relptr); + + /* Swap surname and given name. */ + given = strstr (string, "<<"); + for (p = string; *p; p++) + if (*p == '<') + *p = ' '; + + if (given && given[2]) + { + *given = 0; + given += 2; + result = strconcat (given, " ", string, NULL); + } + else + { + result = string; + string = NULL; + } + + xfree (string); + return result; +} + + +/* Return the pretty formatted serialnumber. On error NULL is + * returned. */ +static char * +get_disp_serialno (app_t app) +{ + char *serial = app_get_serialno (app); + + /* For our OpenPGP cards we do not want to show the entire serial + * number but a nicely reformatted actual serial number. */ + if (serial && strlen (serial) > 16+12) + { + memmove (serial, serial+16, 4); + serial[4] = ' '; + /* memmove (serial+5, serial+20, 4); */ + /* serial[9] = ' '; */ + /* memmove (serial+10, serial+24, 4); */ + /* serial[14] = 0; */ + memmove (serial+5, serial+20, 8); + serial[13] = 0; + } + return serial; +} + + +/* Return the number of remaining tries for the standard or the admin + * pw. Returns -1 on card error. */ +static int +get_remaining_tries (app_t app, int adminpw) +{ + void *relptr; + unsigned char *value; + size_t valuelen; + int remaining; + + relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); + if (!relptr || valuelen < 7) + { + log_error (_("error retrieving CHV status from card\n")); + xfree (relptr); + return -1; + } + remaining = value[adminpw? 6 : 4]; + xfree (relptr); + return remaining; +} + + /* Retrieve the fingerprint from the card inserted in SLOT and write the according hex representation to FPR. Caller must have provide a buffer at FPR of least 41 bytes. Returns 0 on success or an @@ -1874,6 +1972,62 @@ check_pinpad_request (app_t app, pininfo_t *pininfo, int admin_pin) } +/* Return a string with information about the card for use in a + * prompt. Returns NULL on memory failure. */ +static char * +get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) +{ + char *serial, *disp_name, *rembuf, *tmpbuf, *result; + + serial = get_disp_serialno (app); + if (!serial) + return NULL; + + disp_name = get_disp_name (app); + if (chvno == 1) + { + result = xtryasprintf (_("Card number:\t%s%%0A" + "Signatures:\t%lu%%0A" + "Cardholder:\t%s"), + serial, + sigcount, + disp_name? disp_name:""); + } + else + { + result = xtryasprintf (_("Card number:\t%s%%0A" + "Cardholder:\t%s"), + serial, + disp_name? disp_name:""); + } + xfree (disp_name); + xfree (serial); + + if (remaining != -1) + { + /* TRANSLATORS: This is the number of remaining attempts to + * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. */ + rembuf = xtryasprintf (_("Remaining attempts: %d"), remaining); + if (!rembuf) + { + xfree (result); + return NULL; + } + tmpbuf = strconcat (result, "%0A%0A", rembuf, NULL); + xfree (rembuf); + if (!tmpbuf) + { + xfree (result); + return NULL; + } + xfree (result); + result = tmpbuf; + } + + return result; +} + + /* Verify a CHV either using the pinentry or if possible by using a pinpad. PINCB and PINCB_ARG describe the usual callback for the pinentry. CHVNO must be either 1 or 2. SIGCOUNT is only @@ -1895,11 +2049,16 @@ verify_a_chv (app_t app, const char *prompt; pininfo_t pininfo; int minlen = 6; + int remaining; - assert (chvno == 1 || chvno == 2); + log_assert (chvno == 1 || chvno == 2); *pinvalue = NULL; + remaining = get_remaining_tries (app, 0); + if (remaining == -1) + return gpg_error (GPG_ERR_CARD); + if (chvno == 2 && app->app_local->flags.def_chv2) { /* Special case for def_chv2 mechanism. */ @@ -1923,22 +2082,19 @@ verify_a_chv (app_t app, pininfo.fixedlen = -1; pininfo.minlen = minlen; + { + const char *firstline = _("||Please unlock the card"); + char *infoblock = get_prompt_info (app, chvno, sigcount, + remaining < 3? remaining : -1); - if (chvno == 1) - { -#define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]") - size_t promptsize = strlen (PROMPTSTRING) + 50; - - prompt_buffer = xtrymalloc (promptsize); - if (!prompt_buffer) - return gpg_error_from_syserror (); - snprintf (prompt_buffer, promptsize, PROMPTSTRING, sigcount); + prompt_buffer = strconcat (firstline, "%0A%0A", infoblock, NULL); + if (prompt_buffer) prompt = prompt_buffer; -#undef PROMPTSTRING - } - else - prompt = _("||Please enter the PIN"); + else + prompt = firstline; /* ENOMEM fallback. */ + xfree (infoblock); + } if (!opt.disable_pinpad && !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) @@ -1961,7 +2117,7 @@ verify_a_chv (app_t app, /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); - assert (!*pinvalue); + log_assert (!*pinvalue); } else { @@ -2049,29 +2205,20 @@ verify_chv2 (app_t app, static gpg_error_t build_enter_admin_pin_prompt (app_t app, char **r_prompt) { - void *relptr; - unsigned char *value; - size_t valuelen; int remaining; char *prompt; + char *infoblock; *r_prompt = NULL; - relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); - if (!relptr || valuelen < 7) - { - log_error (_("error retrieving CHV status from card\n")); - xfree (relptr); - return gpg_error (GPG_ERR_CARD); - } - if (value[6] == 0) + remaining = get_remaining_tries (app, 1); + if (remaining == -1) + return gpg_error (GPG_ERR_CARD); + if (!remaining) { log_info (_("card is permanently locked!\n")); - xfree (relptr); return gpg_error (GPG_ERR_BAD_PIN); } - remaining = value[6]; - xfree (relptr); log_info (ngettext("%d Admin PIN attempt remaining before card" " is permanently locked\n", @@ -2079,16 +2226,13 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt) " is permanently locked\n", remaining), remaining); - if (remaining < 3) - { - /* TRANSLATORS: Do not translate the "|A|" prefix but keep it at - the start of the string. Use %%0A to force a linefeed. */ - prompt = xtryasprintf (_("|A|Please enter the Admin PIN%%0A" - "[remaining attempts: %d]"), remaining); - } - else - prompt = xtrystrdup (_("|A|Please enter the Admin PIN")); + infoblock = get_prompt_info (app, 3, 0, remaining < 3? remaining : -1); + /* TRANSLATORS: Do not translate the "|A|" prefix but keep it at + the start of the string. Use %0A (single percent) for a linefeed. */ + prompt = strconcat (_("|A|Please enter the Admin PIN"), + "%0A%0A", infoblock, NULL); + xfree (infoblock); if (!prompt) return gpg_error_from_syserror (); ----------------------------------------------------------------------- Summary of changes: agent/divert-scd.c | 53 +++++++++---- scd/app-openpgp.c | 220 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 220 insertions(+), 53 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 22 16:24:57 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 22 Feb 2017 16:24:57 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-124-gaa61cb5 Message-ID: This is an 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 aa61cb5bbaba6797cf0d6d89ba39fe0c9b393724 (commit) via 6d50eeb5072475eb74e65064743fbec6b8fa9c37 (commit) from e3944f34e3220f96fb1be449eb6f3d7360bc2d0b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aa61cb5bbaba6797cf0d6d89ba39fe0c9b393724 Author: Werner Koch Date: Wed Feb 22 16:22:13 2017 +0100 po: Update the German translation -- diff --git a/po/de.po b/po/de.po index 36ba928..ea875d4 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2017-01-23 19:23+0100\n" +"PO-Revision-Date: 2017-02-22 16:21+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "Language: de\n" @@ -154,6 +154,10 @@ msgid "no suitable card key found: %s\n" msgstr "keine passender Kartenschl?ssel gefunden: %s\n" #, c-format +msgid "error getting list of cards: %s\n" +msgstr "Fehler beim Holen der Liste der Karten: %s\n" + +#, c-format msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " "allow this?" @@ -1007,6 +1011,10 @@ msgstr "Zeile mit nicht identifizierten Zeichen wird ignoriert" msgid "[none]" msgstr "[keine]" +#, c-format +msgid "invalid radix64 character %02x skipped\n" +msgstr "Ung?ltiges Basis-64 Zeichen %02X wurde ?bersprungen\n" + msgid "argument not expected" msgstr "Argument nicht erwartet" @@ -2386,6 +2394,9 @@ msgstr "" "'%s\" sieht nicht nach einer g?ltigen Schl?ssel-ID, einem Fingerabdruck oder " "einem \"Keygrip\" aus\n" +msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" +msgstr "WARNING: Kein Kommando angegeben. Versuche zu raten was gemeint ist ...\n" + msgid "Go ahead and type your message ...\n" msgstr "Auf geht's - Botschaft eintippen ...\n" @@ -5719,7 +5730,7 @@ msgstr "gGaAuUlLfF" msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? " msgstr "(G)ut, einmal (A)kzeptieren, (U)nbekannt, einmal ab(L)ehnen, (F)alsch?" -msgid "Defaulting to unknown." +msgid "Defaulting to unknown.\n" msgstr "" msgid "TOFU db corruption detected.\n" @@ -5927,7 +5938,7 @@ msgid "error opening TOFU database: %s\n" msgstr "Fehler beim ?ffnen der TOFU Datenbank: %s\n" #, c-format -msgid "WARNING: Encrypting to %s, which has no non-revoked user ids.\n" +msgid "WARNING: Encrypting to %s, which has no non-revoked user ids\n" msgstr "" #, fuzzy, c-format @@ -6190,6 +6201,9 @@ msgstr "Der Fingerabdruck kann nicht gespeichert werden: %s\n" msgid "failed to store the creation date: %s\n" msgstr "Das Erzeugungsdatum konnte nicht gespeichert werden: %s\n" +msgid "error retrieving CHV status from card\n" +msgstr "Fehler beim Holen des CHV-Status' von der Karte\n" + msgid "response does not contain the RSA modulus\n" msgstr "Die Antwort enth?lt das RSA-Modulus nicht\n" @@ -6207,6 +6221,20 @@ msgid "reading public key failed: %s\n" msgstr "Lesen des ?ffentlichen Schl?ssels fehlgeschlagen: %s\n" #, c-format +msgid "Card number:\t%s%%0ASignatures:\t%lu%%0ACardholder:\t%s" +msgstr "Kartennummer:\t%s%%0ASignaturen:\t%lu%%0AKartenbesitzer:\t%s" + +#, c-format +msgid "Card number:\t%s%%0ACardholder:\t%s" +msgstr "Kartennummer:\t%s%%0AKartenbesitzer:\t%s" + +#. TRANSLATORS: This is the number of remaining attempts to +#. * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. +#, c-format +msgid "Remaining attempts: %d" +msgstr "Verbliebene Versuche: %d" + +#, c-format msgid "using default PIN as %s\n" msgstr "Die Standard PIN wird f?r %s benutzt\n" @@ -6216,12 +6244,8 @@ msgstr "" "Die Standard PIN f?r %s konnte nicht benutzt werden: %s - Die Standard PIN " "wird nicht weiter benutzt\n" -#, c-format -msgid "||Please enter the PIN%%0A[sigs done: %lu]" -msgstr "||Bitte die PIN eingeben%%0A[Sigs erzeugt: %lu]" - -msgid "||Please enter the PIN" -msgstr "||Bitte die PIN eingeben" +msgid "||Please unlock the card" +msgstr "||Bitte entsperren Sie die Karte" #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" @@ -6231,9 +6255,6 @@ msgstr "PIN f?r CHV%d ist zu kurz; die Mindestl?nge betr?gt %d\n" msgid "verify CHV%d failed: %s\n" msgstr "Pr?fung des CHV%d fehlgeschlagen: %s\n" -msgid "error retrieving CHV status from card\n" -msgstr "Fehler beim Holen des CHV-Status' von der Karte\n" - msgid "card is permanently locked!\n" msgstr "Karte ist dauerhaft gesperrt!\n" @@ -6245,17 +6266,16 @@ msgstr[0] "Noch %d Admin-PIN-Versuch, bis die Karte dauerhaft gesperrt ist\n" msgstr[1] "Noch %d Admin-PIN-Versuche, bis die Karte dauerhaft gesperrt ist\n" #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at -#. the start of the string. Use %%0A to force a linefeed. -#, c-format -msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" -msgstr "|A|Bitte die Admin-PIN eingeben.%%0A[Verbliebene Versuche: %d]" - +#. the start of the string. Use %0A (single percent) for a linefeed. msgid "|A|Please enter the Admin PIN" msgstr "|A|Bitte die Admin-PIN eingeben." msgid "access to admin commands is not configured\n" msgstr "Zugriff auf Admin-Befehle ist nicht eingerichtet\n" +msgid "||Please enter the PIN" +msgstr "||Bitte die PIN eingeben" + msgid "||Please enter the Reset Code for the card" msgstr "Bitte geben Sie den R?ckstellcode f?r diese Karte ein" @@ -6414,10 +6434,6 @@ msgstr "Handhabungsroutine f?r fd %d gestartet\n" msgid "handler for fd %d terminated\n" msgstr "Handhabungsroutine f?r den fd %d beendet\n" -#, c-format -msgid "invalid radix64 character %02x skipped\n" -msgstr "Ung?ltiges Basis-64 Zeichen %02X wurde ?bersprungen\n" - msgid "no dirmngr running in this session\n" msgstr "Der Dirmngr l?uft nicht f?r diese Session\n" @@ -7207,7 +7223,11 @@ msgstr " dauerhaft geladene Zertifikate: %u\n" #, c-format msgid " runtime cached certificates: %u\n" -msgstr "zur Laufzeit zwischengespeicherte Zertifikate: %u\n" +msgstr " zwischengespeicherte Zertifikate: %u\n" + +#, c-format +msgid " trusted certificates: %u (%u,%u,%u,%u)\n" +msgstr " vertrauensw?rdige Zertifikate: %u (%u,%u,%u,%u)\n" msgid "certificate already cached\n" msgstr "Zertifikat ist bereits im Zwischenspeicher\n" @@ -8345,9 +8365,6 @@ msgstr "" msgid "certificate chain is good\n" msgstr "Der Zertifikatkette ist g?ltig\n" -msgid "DSA requires the use of a 160 bit hash algorithm\n" -msgstr "DSA ben?tigt eine 160 Bit Hashmethode\n" - msgid "certificate should not have been used for CRL signing\n" msgstr "" "Das Zertifikat h?tte nicht zum Signieren einer CRL benutzt werden sollen\n" @@ -8770,6 +8787,15 @@ msgstr "" "Syntax: gpg-check-pattern [optionen] Musterdatei\n" "Die von stdin gelesene Passphrase gegen die Musterdatei pr?fen\n" +#~ msgid "||Please enter the PIN%%0A[sigs done: %lu]" +#~ msgstr "||Bitte die PIN eingeben%%0A[Sigs erzeugt: %lu]" + +#~ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" +#~ msgstr "|A|Bitte die Admin-PIN eingeben.%%0A[Verbliebene Versuche: %d]" + +#~ msgid "DSA requires the use of a 160 bit hash algorithm\n" +#~ msgstr "DSA ben?tigt eine 160 Bit Hashmethode\n" + #, fuzzy #~| msgid "" #~| "@\n" commit 6d50eeb5072475eb74e65064743fbec6b8fa9c37 Author: Werner Koch Date: Wed Feb 22 16:06:50 2017 +0100 po: Fix two fuzzy strings. -- These strings rear the Key generation edit prompts without the option to change the comment of a user id. Module possible grammar bugs this should a straightforward change. GnuPG-bug-id: 2966 Signed-off-by: Werner Koch diff --git a/po/pl.po b/po/pl.po index 59b798b..94a0be3 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1,5 +1,5 @@ # Gnu Privacy Guard. -# Copyright (C) 1998, 1999, 2000, 2001, 2002, +# Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2007 Free Software Foundation, Inc. # Janusz A. Urbanowicz , 1999, 2000, 2001, 2002, 2003-2004 # Jakub Bogusz , 2003-2013. @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.0.20\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2013-05-12 17:25+0200\n" +"PO-Revision-Date: 2017-02-22 16:03+0100\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -160,6 +160,11 @@ msgstr "b??d pobierania domy?lnego keyID uwierzytelnienia karty: %s\n" msgid "no suitable card key found: %s\n" msgstr "nie znaleziono pasuj?cego klucza karty: %s\n" +#, fuzzy, c-format +#| msgid "error getting stored flags: %s\n" +msgid "error getting list of cards: %s\n" +msgstr "b??d pobierania zapisanych flag: %s\n" + #, c-format msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " @@ -1071,6 +1076,10 @@ msgstr "zignorowano b??dn? lini?" msgid "[none]" msgstr "[brak]" +#, c-format +msgid "invalid radix64 character %02x skipped\n" +msgstr "niew?a?ciwy znak formatu radix64 %02x zosta? pomini?ty\n" + msgid "argument not expected" msgstr "nieoczekiwany argument" @@ -2561,6 +2570,9 @@ msgstr "b??d zapisywania certyfikatu: %s\n" msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" msgstr "" +msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" +msgstr "" + msgid "Go ahead and type your message ...\n" msgstr "Wpisz tutaj swoj? wiadomo?? ...\n" @@ -4276,16 +4288,12 @@ msgstr "" "Zmieni? (I)mi?/nazwisko, (K)omentarz, adres (E)mail, przej?? (D)alej,\n" "czy (W)yj?? z programu? " -#, fuzzy -#| msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? " msgid "Change (N)ame, (E)mail, or (Q)uit? " -msgstr "Zmieni? (I)mi?/nazwisko, (K)omentarz, adres (E)mail, czy (W)yj??? " +msgstr "Zmieni? (I)mi?/nazwisko, adres (E)mail, czy (W)yj??? " -#, fuzzy -#| msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? " msgstr "" -"Zmieni? (I)mi?/nazwisko, (K)omentarz, adres (E)mail, przej?? (D)alej,\n" +"Zmieni? (I)mi?/nazwisko, adres (E)mail, przej?? (D)alej,\n" "czy (W)yj?? z programu? " msgid "Please correct the error first\n" @@ -5999,7 +6007,7 @@ msgstr "" msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? " msgstr "" -msgid "Defaulting to unknown." +msgid "Defaulting to unknown.\n" msgstr "" msgid "TOFU db corruption detected.\n" @@ -6141,7 +6149,7 @@ msgid "error opening TOFU database: %s\n" msgstr "b??d wysy?ania polecenia %s: %s\n" #, c-format -msgid "WARNING: Encrypting to %s, which has no non-revoked user ids.\n" +msgid "WARNING: Encrypting to %s, which has no non-revoked user ids\n" msgstr "" #, fuzzy, c-format @@ -6406,6 +6414,9 @@ msgstr "nie powi?d? si? zapis odcisku: %s\n" msgid "failed to store the creation date: %s\n" msgstr "nie powi?d? si? zapis daty utworzenia: %s\n" +msgid "error retrieving CHV status from card\n" +msgstr "b??d podczas odczytu stanu CHV z karty\n" + msgid "response does not contain the RSA modulus\n" msgstr "odpowied? nie zawiera wsp??czynnika RSA\n" @@ -6425,6 +6436,20 @@ msgid "reading public key failed: %s\n" msgstr "odczyt klucza publicznego nie powi?d? si?: %s\n" #, c-format +msgid "Card number:\t%s%%0ASignatures:\t%lu%%0ACardholder:\t%s" +msgstr "" + +#, c-format +msgid "Card number:\t%s%%0ACardholder:\t%s" +msgstr "" + +#. TRANSLATORS: This is the number of remaining attempts to +#. * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. +#, c-format +msgid "Remaining attempts: %d" +msgstr "" + +#, c-format msgid "using default PIN as %s\n" msgstr "u?ycie domy?lnego PIN-u jako %s\n" @@ -6434,11 +6459,9 @@ msgstr "" "nie uda?o si? u?y? domy?lnego PIN-u jako %s: %s - wy??czenie dalszego " "domy?lnego u?ycia\n" -#, c-format -msgid "||Please enter the PIN%%0A[sigs done: %lu]" -msgstr "||Prosz? wpisa? PIN%%0A[podpis?w wykonanych: %lu]" - -msgid "||Please enter the PIN" +#, fuzzy +#| msgid "||Please enter the PIN" +msgid "||Please unlock the card" msgstr "||Prosz? wpisa? PIN" #, c-format @@ -6449,9 +6472,6 @@ msgstr "PIN dla CHV%d jest zbyt kr?tki; minimalna d?ugo?? to %d\n" msgid "verify CHV%d failed: %s\n" msgstr "weryfikacja CHV%d nie powiod?a si?: %s\n" -msgid "error retrieving CHV status from card\n" -msgstr "b??d podczas odczytu stanu CHV z karty\n" - msgid "card is permanently locked!\n" msgstr "karta zosta?a trwale zablokowana!\n" @@ -6468,17 +6488,16 @@ msgstr[2] "" "Zosta?o %d pr?b PIN-u administracyjnego do trwa?ego zablokowania karty\n" #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at -#. the start of the string. Use %%0A to force a linefeed. -#, c-format -msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" -msgstr "|A|Prosz? wprowadzi? PIN administracyjny%%0A[pozosta?o pr?b: %d]" - +#. the start of the string. Use %0A (single percent) for a linefeed. msgid "|A|Please enter the Admin PIN" msgstr "|A|Prosz? wprowadzi? PIN administracyjny" msgid "access to admin commands is not configured\n" msgstr "dost?p do polece? administratora nie zosta? skonfigurowany\n" +msgid "||Please enter the PIN" +msgstr "||Prosz? wpisa? PIN" + msgid "||Please enter the Reset Code for the card" msgstr "||Prosz? wprowadzi? kod resetuj?cy dla karty" @@ -6648,10 +6667,6 @@ msgstr "obs?uga fd %d uruchomiona\n" msgid "handler for fd %d terminated\n" msgstr "obs?uga fd %d zako?czona\n" -#, c-format -msgid "invalid radix64 character %02x skipped\n" -msgstr "niew?a?ciwy znak formatu radix64 %02x zosta? pomini?ty\n" - #, fuzzy #| msgid "no gpg-agent running in this session\n" msgid "no dirmngr running in this session\n" @@ -7473,6 +7488,11 @@ msgstr "Do??czone certyfikaty" msgid " runtime cached certificates: %u\n" msgstr "liczba pasuj?cych certyfikat?w: %d\n" +#, fuzzy, c-format +#| msgid "number of matching certificates: %d\n" +msgid " trusted certificates: %u (%u,%u,%u,%u)\n" +msgstr "liczba pasuj?cych certyfikat?w: %d\n" + #, fuzzy #| msgid " (certificate created at " msgid "certificate already cached\n" @@ -8790,9 +8810,6 @@ msgstr "sprawdzenie certyfikatu kwalifikowanego nie powiod?o si?: %s\n" msgid "certificate chain is good\n" msgstr "certyfikat jest dobry\n" -msgid "DSA requires the use of a 160 bit hash algorithm\n" -msgstr "" - #, fuzzy #| msgid "certificate should not have been used for signing\n" msgid "certificate should not have been used for CRL signing\n" @@ -9258,6 +9275,12 @@ msgstr "" "Sk?adnia: gpg-check-pattern [opcje] plik-wzorc?w\n" "Sprawdzanie has?a ze standardowego wej?cia wzgl?dem pliku wzorc?w\n" +#~ msgid "||Please enter the PIN%%0A[sigs done: %lu]" +#~ msgstr "||Prosz? wpisa? PIN%%0A[podpis?w wykonanych: %lu]" + +#~ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" +#~ msgstr "|A|Prosz? wprowadzi? PIN administracyjny%%0A[pozosta?o pr?b: %d]" + #~ msgid "--store [filename]" #~ msgstr "--store [plik]" ----------------------------------------------------------------------- Summary of changes: po/de.po | 76 +++++++++++++++++++++++++++++++++++++++------------------- po/pl.po | 83 +++++++++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 104 insertions(+), 55 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 22 17:12:19 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 22 Feb 2017 17:12:19 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-126-g468dbc7 Message-ID: This is an 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 468dbc74d2a07a095911f334213bb82d97fc1ff6 (commit) via 143ca039e1e81140ae520cc1025f8e25c01acc80 (commit) from aa61cb5bbaba6797cf0d6d89ba39fe0c9b393724 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 468dbc74d2a07a095911f334213bb82d97fc1ff6 Author: Andre Heinecke Date: Wed Feb 22 17:07:16 2017 +0100 po: Update the German translation -- diff --git a/po/de.po b/po/de.po index ea875d4..c72fe49 100644 --- a/po/de.po +++ b/po/de.po @@ -6221,12 +6221,12 @@ msgid "reading public key failed: %s\n" msgstr "Lesen des ?ffentlichen Schl?ssels fehlgeschlagen: %s\n" #, c-format -msgid "Card number:\t%s%%0ASignatures:\t%lu%%0ACardholder:\t%s" -msgstr "Kartennummer:\t%s%%0ASignaturen:\t%lu%%0AKartenbesitzer:\t%s" +msgid "Number:\t%s%%0AHolder:\t%s%%0ASignatures:\t%lu" +msgstr "Nummer:\t%s%%0ABesitzer:\t%s%%0ASignaturen:\t%lu" #, c-format -msgid "Card number:\t%s%%0ACardholder:\t%s" -msgstr "Kartennummer:\t%s%%0AKartenbesitzer:\t%s" +msgid "Number:\t%s%%0AHolder:\t%s" +msgstr "Nummer:\t%s%%0ABesitzer:\t%s" #. TRANSLATORS: This is the number of remaining attempts to #. * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. commit 143ca039e1e81140ae520cc1025f8e25c01acc80 Author: Andre Heinecke Date: Wed Feb 22 16:57:58 2017 +0100 scd: Nitpicks on the improved card prompts * src/app-openpgp.c (get_prompt_info): Change wording and order slightly. -- The word "Card" was repeated too much in the prompt and moving signatures to the bottom results in a more consistent layout between the prompts with signcount and the prompts without. Signed-off-by: Andre Heinecke diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 90c2661..f68d8bb 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1986,17 +1986,17 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) disp_name = get_disp_name (app); if (chvno == 1) { - result = xtryasprintf (_("Card number:\t%s%%0A" - "Signatures:\t%lu%%0A" - "Cardholder:\t%s"), + result = xtryasprintf (_("Number:\t%s%%0A" + "Holder:\t%s%%0A" + "Signatures:\t%lu"), serial, - sigcount, - disp_name? disp_name:""); + disp_name? disp_name:"", + sigcount); } else { - result = xtryasprintf (_("Card number:\t%s%%0A" - "Cardholder:\t%s"), + result = xtryasprintf (_("Number:\t%s%%0A" + "Holder:\t%s"), serial, disp_name? disp_name:""); } ----------------------------------------------------------------------- Summary of changes: po/de.po | 8 ++++---- scd/app-openpgp.c | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 22 18:59:53 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 22 Feb 2017 18:59:53 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-129-gfd9cb9f Message-ID: This is an 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 fd9cb9f8152158b81c2aaef6e9c65cfdd763a0d1 (commit) via f98c8cb013033c08e98ebedcc0e084fbd2a85b0c (commit) via 7ccabbc26a2fd0d18fef4f4f15731377b514c97d (commit) from 468dbc74d2a07a095911f334213bb82d97fc1ff6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fd9cb9f8152158b81c2aaef6e9c65cfdd763a0d1 Author: Werner Koch Date: Wed Feb 22 18:56:42 2017 +0100 po: Adjust the German translation. -- Signed-off-by: Werner Koch diff --git a/po/de.po b/po/de.po index c72fe49..165dade 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2017-02-22 16:21+0100\n" +"PO-Revision-Date: 2017-02-22 18:55+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "Language: de\n" @@ -2395,7 +2395,8 @@ msgstr "" "einem \"Keygrip\" aus\n" msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" -msgstr "WARNING: Kein Kommando angegeben. Versuche zu raten was gemeint ist ...\n" +msgstr "" +"WARNING: Kein Kommando angegeben. Versuche zu raten was gemeint ist ...\n" msgid "Go ahead and type your message ...\n" msgstr "Auf geht's - Botschaft eintippen ...\n" @@ -6220,13 +6221,16 @@ msgstr "Die Antwort enth?lt keine ?ffentliche Schl?ssel-Daten\n" msgid "reading public key failed: %s\n" msgstr "Lesen des ?ffentlichen Schl?ssels fehlgeschlagen: %s\n" +#. TRANSLATORS: Put a \x1f right before a colon. This can be +#. * used by pinentry to nicely align the names and values. Keep +#. * the %s at the start and end of the string. #, c-format -msgid "Number:\t%s%%0AHolder:\t%s%%0ASignatures:\t%lu" -msgstr "Nummer:\t%s%%0ABesitzer:\t%s%%0ASignaturen:\t%lu" +msgid "%sNumber: %s%%0AHolder: %s%%0ACounter: %lu%s" +msgstr "%sNummer: %s%%0ABesitzer: %s%%0AAnzahl: %lu%s" #, c-format -msgid "Number:\t%s%%0AHolder:\t%s" -msgstr "Nummer:\t%s%%0ABesitzer:\t%s" +msgid "%sNumber: %s%%0AHolder: %s%s" +msgstr "%sNummer: %s%%0ABesitzer: %s%s" #. TRANSLATORS: This is the number of remaining attempts to #. * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. commit f98c8cb013033c08e98ebedcc0e084fbd2a85b0c Author: Werner Koch Date: Wed Feb 22 16:54:32 2017 +0100 scd,agent: Improve the OpenPGP PIN prompt texts. * scd/app-openpgp.c (get_prompt_info): Change texts. * agent/call-pinentry.c (struct entry_features): New. (getinfo_features_cb): New. (start_pinentry): Set new fucntion as status callback. (build_cmd_setdesc): New. Replace all snprintf for SETDESC by this one. -- Suggested-by: Andre Heinecke Signed-off-by: Werner Koch diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 9931665..0af1854 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -56,6 +56,17 @@ /* The assuan context of the current pinentry. */ static assuan_context_t entry_ctx; +/* A list of features of the current pinentry. */ +static struct +{ + /* The Pinentry support RS+US tabbing. This means that a RS (0x1e) + * starts a new tabbing block in which a US (0x1f) followed by a + * colon marks a colon. A pinentry can use this to pretty print + * name value pairs. */ + unsigned int tabbing:1; +} entry_features; + + /* The control variable of the connection owning the current pinentry. This is only valid if ENTRY_CTX is not NULL. Note, that we care only about the value of the pointer and that it should never be @@ -208,6 +219,31 @@ atfork_cb (void *opaque, int where) } +/* Status line callback for the FEATURES status. */ +static gpg_error_t +getinfo_features_cb (void *opaque, const char *line) +{ + const char *args; + char **tokens; + int i; + + (void)opaque; + + if ((args = has_leading_keyword (line, "FEATURES"))) + { + tokens = strtokenize (args, " "); + if (!tokens) + return gpg_error_from_syserror (); + for (i=0; tokens[i]; i++) + if (!strcmp (tokens[i], "tabbing")) + entry_features.tabbing = 1; + xfree (tokens); + } + + return 0; +} + + static gpg_error_t getinfo_pid_cb (void *opaque, const void *buffer, size_t length) { @@ -567,13 +603,17 @@ start_pinentry (ctrl_t ctrl) /* Ask the pinentry for its version and flavor and store that as a * string in MB. This information is useful for helping users to - * figure out Pinentry problems. */ + * figure out Pinentry problems. Noet that "flavor" may also return + * a status line with the features; we use a dedicated handler for + * that. */ { membuf_t mb; init_membuf (&mb, 256); if (assuan_transact (entry_ctx, "GETINFO flavor", - put_membuf_cb, &mb, NULL, NULL, NULL, NULL)) + put_membuf_cb, &mb, + NULL, NULL, + getinfo_features_cb, NULL)) put_membuf_str (&mb, "unknown"); put_membuf_str (&mb, " "); if (assuan_transact (entry_ctx, "GETINFO version", @@ -871,6 +911,25 @@ pinentry_status_cb (void *opaque, const char *line) } +/* Build a SETDESC command line. This is a dedicated funcion so that + * it can remove control characters which are not supported by the + * current Pinentry. */ +static void +build_cmd_setdesc (char *line, size_t linelen, const char *desc) +{ + char *src, *dst; + + snprintf (line, linelen, "SETDESC %s", desc); + if (!entry_features.tabbing) + { + /* Remove RS and US. */ + for (src=dst=line; *src; src++) + if (!strchr ("\x1e\x1f", *src)) + *dst++ = *src; + *dst = 0; + } +} + /* Call the Entry and ask for the PIN. We do check for a valid PIN @@ -961,7 +1020,7 @@ agent_askpin (ctrl_t ctrl, if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD) return unlock_pinentry (rc); - snprintf (line, DIM(line), "SETDESC %s", desc_text); + build_cmd_setdesc (line, DIM(line), desc_text); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return unlock_pinentry (rc); @@ -1170,7 +1229,7 @@ agent_get_passphrase (ctrl_t ctrl, if (desc) - snprintf (line, DIM(line), "SETDESC %s", desc); + build_cmd_setdesc (line, DIM(line), desc); else snprintf (line, DIM(line), "RESET"); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1258,7 +1317,7 @@ agent_get_confirmation (ctrl_t ctrl, return rc; if (desc) - snprintf (line, DIM(line), "SETDESC %s", desc); + build_cmd_setdesc (line, DIM(line), desc); else snprintf (line, DIM(line), "RESET"); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1331,7 +1390,7 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn) return rc; if (desc) - snprintf (line, DIM(line), "SETDESC %s", desc); + build_cmd_setdesc (line, DIM(line), desc); else snprintf (line, DIM(line), "RESET"); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1401,7 +1460,7 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn) return rc; if (desc) - snprintf (line, DIM(line), "SETDESC %s", desc); + build_cmd_setdesc (line, DIM(line), desc); else snprintf (line, DIM(line), "RESET"); rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 90c2661..5e75d4b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1986,19 +1986,30 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) disp_name = get_disp_name (app); if (chvno == 1) { - result = xtryasprintf (_("Card number:\t%s%%0A" - "Signatures:\t%lu%%0A" - "Cardholder:\t%s"), + /* TRANSLATORS: Put a \x1f right before a colon. This can be + * used by pinentry to nicely align the names and values. Keep + * the %s at the start and end of the string. */ + result = xtryasprintf (_("%s" + "Number\x1f: %s%%0A" + "Holder\x1f: %s%%0A" + "Counter\x1f: %lu" + "%s"), + "\x1e", serial, + disp_name? disp_name:"", sigcount, - disp_name? disp_name:""); + ""); } else { - result = xtryasprintf (_("Card number:\t%s%%0A" - "Cardholder:\t%s"), + result = xtryasprintf (_("%s" + "Number\x1f: %s%%0A" + "Holder\x1f: %s" + "%s"), + "\x1e", serial, - disp_name? disp_name:""); + disp_name? disp_name:"", + ""); } xfree (disp_name); xfree (serial); commit 7ccabbc26a2fd0d18fef4f4f15731377b514c97d Author: Werner Koch Date: Wed Feb 22 18:49:43 2017 +0100 Revert "scd: Nitpicks on the improved card prompts" -- This reverts commit 143ca039e1e81140ae520cc1025f8e25c01acc80. I have a more improved version in the works. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index f68d8bb..90c2661 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1986,17 +1986,17 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) disp_name = get_disp_name (app); if (chvno == 1) { - result = xtryasprintf (_("Number:\t%s%%0A" - "Holder:\t%s%%0A" - "Signatures:\t%lu"), + result = xtryasprintf (_("Card number:\t%s%%0A" + "Signatures:\t%lu%%0A" + "Cardholder:\t%s"), serial, - disp_name? disp_name:"", - sigcount); + sigcount, + disp_name? disp_name:""); } else { - result = xtryasprintf (_("Number:\t%s%%0A" - "Holder:\t%s"), + result = xtryasprintf (_("Card number:\t%s%%0A" + "Cardholder:\t%s"), serial, disp_name? disp_name:""); } ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- po/de.po | 16 ++++++----- scd/app-openpgp.c | 25 +++++++++++++----- 3 files changed, 94 insertions(+), 20 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 23 09:01:46 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 23 Feb 2017 09:01:46 +0100 Subject: [git] NTBTLS - branch, master, updated. 23670ada738071ec464c9a40f6b3528e23998655 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via 23670ada738071ec464c9a40f6b3528e23998655 (commit) from 8d98665dc2a1d7876f9841d4788c4ea4c710270b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 23670ada738071ec464c9a40f6b3528e23998655 Author: Werner Koch Date: Thu Feb 23 08:59:00 2017 +0100 Make ntbtls-cli work for W32. * src/ntbtls-cli.c: Include errno.h. (w32_cookie_read) [W32]: New. (w32_write_server) [W32]: New. (w32_cookie_write) [W32]: New. (w32_cookie_functions) [W32]: New. (connect_estreams) [W32]: Use es_fopencookie. (main) [W32]: Init Winsock. Signed-off-by: Werner Koch diff --git a/src/ntbtls-cli.c b/src/ntbtls-cli.c index 1656376..67affc1 100644 --- a/src/ntbtls-cli.c +++ b/src/ntbtls-cli.c @@ -24,6 +24,7 @@ #include #include +#include #include #ifdef HAVE_W32_SYSTEM # define WIN32_LEAN_AND_MEAN @@ -121,6 +122,77 @@ info (const char *format, ...) +/* Until we support send/recv in estream we need to use es_fopencookie + * under Windows. */ +#ifdef HAVE_W32_SYSTEM +static gpgrt_ssize_t +w32_cookie_read (void *cookie, void *buffer, size_t size) +{ + int sock = (int)cookie; + int nread; + + do + { + /* Under Windows we need to use recv for a socket. */ + nread = recv (sock, buffer, size, 0); + } + while (nread == -1 && errno == EINTR); + + return (gpgrt_ssize_t)nread; +} + +static gpg_error_t +w32_write_server (int sock, const char *data, size_t length) +{ + int nleft; + int nwritten; + + nleft = length; + while (nleft > 0) + { + nwritten = send (sock, data, nleft, 0); + if ( nwritten == SOCKET_ERROR ) + { + info ("network write failed: ec=%d\n", (int)WSAGetLastError ()); + return gpg_error (GPG_ERR_NETWORK); + } + nleft -= nwritten; + data += nwritten; + } + + return 0; +} + +/* Write handler for estream. */ +static gpgrt_ssize_t +w32_cookie_write (void *cookie, const void *buffer_arg, size_t size) +{ + int sock = (int)cookie; + const char *buffer = buffer_arg; + int nwritten = 0; + + if (w32_write_server (sock, buffer, size)) + { + gpg_err_set_errno (EIO); + nwritten = -1; + } + else + nwritten = size; + + return (gpgrt_ssize_t)nwritten; +} + +static es_cookie_io_functions_t w32_cookie_functions = + { + w32_cookie_read, + w32_cookie_write, + NULL, + NULL + }; +#endif /*HAVE_W32_SYSTEM*/ + + + static int connect_server (const char *server, unsigned short port) { @@ -175,14 +247,25 @@ connect_estreams (const char *server, int port, sock = connect_server (server, port); if (sock == -1) return gpg_error (GPG_ERR_GENERAL); - *r_in = es_fdopen_nc (sock, "rb"); + +#ifdef HAVE_W32_SYSTEM + *r_in = es_fopencookie ((void*)(unsigned int)sock, "rb", + w32_cookie_functions); +#else + *r_in = es_fdopen (sock, "rb"); +#endif if (!*r_in) { err = gpg_error_from_syserror (); close (sock); return err; } +#ifdef HAVE_W32_SYSTEM + *r_out = es_fopencookie ((void*)(unsigned int)sock, "wb", + w32_cookie_functions); +#else *r_out = es_fdopen (sock, "wb"); +#endif if (!*r_out) { err = gpg_error_from_syserror (); @@ -358,6 +441,13 @@ main (int argc, char **argv) if (!*opt_hostname) opt_hostname = NULL; +#ifdef HAVE_W32_SYSTEM + { + WSADATA wsadat; + WSAStartup (0x202, &wsadat); + } +#endif + if (!ntbtls_check_version (PACKAGE_VERSION)) die ("NTBTLS library too old (need %s, have %s)\n", PACKAGE_VERSION, ntbtls_check_version (NULL)); ----------------------------------------------------------------------- Summary of changes: src/ntbtls-cli.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 23 10:33:34 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 23 Feb 2017 10:33:34 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-130-ga42bf00 Message-ID: This is an 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 a42bf00b4edce789999aa3bdfce235cf726463ae (commit) from fd9cb9f8152158b81c2aaef6e9c65cfdd763a0d1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a42bf00b4edce789999aa3bdfce235cf726463ae Author: Werner Koch Date: Thu Feb 23 10:30:58 2017 +0100 dirmngr,w32: Make https with ntbtls work. * dirmngr/http.c (simple_cookie_functions): New. (send_request) [HTTP_USE_NTBTLS, W32]: Use es_fopencookie. (cookie_read): Factor some code out to ... (read_server): new. (simple_cookie_read, simple_cookie_write) [W32]: New. Signed-off-by: Werner Koch diff --git a/dirmngr/http.c b/dirmngr/http.c index f4b40a8..e5e36b2 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -158,13 +158,19 @@ static gpg_error_t parse_response (http_t hd); static gpg_error_t connect_server (const char *server, unsigned short port, unsigned int flags, const char *srvtag, assuan_fd_t *r_sock); +static gpgrt_ssize_t read_server (int sock, void *buffer, size_t size); static gpg_error_t write_server (int sock, const char *data, size_t length); static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size); static gpgrt_ssize_t cookie_write (void *cookie, const void *buffer, size_t size); static int cookie_close (void *cookie); - +#ifdef HAVE_W32_SYSTEM +static gpgrt_ssize_t simple_cookie_read (void *cookie, + void *buffer, size_t size); +static gpgrt_ssize_t simple_cookie_write (void *cookie, + const void *buffer, size_t size); +#endif /* A socket object used to a allow ref counting of sockets. */ struct my_socket_s @@ -184,6 +190,7 @@ static es_cookie_io_functions_t cookie_functions = cookie_close }; + struct cookie_s { /* Socket object or NULL if already closed. */ @@ -203,6 +210,19 @@ struct cookie_s typedef struct cookie_s *cookie_t; +/* Simple cookie functions. Here the cookie is an int with the + * socket. */ +#ifdef HAVE_W32_SYSTEM +static es_cookie_io_functions_t simple_cookie_functions = + { + simple_cookie_read, + simple_cookie_write, + NULL, + NULL + }; +#endif + + #if SIZEOF_UNSIGNED_LONG == 8 # define HTTP_SESSION_MAGIC 0x0068545470534553 /* "hTTpSES" */ #else @@ -362,7 +382,7 @@ _my_socket_new (int lnr, assuan_fd_t fd) so->refcount = 1; if (opt_debug) log_debug ("http.c:%d:socket_new: object %p for fd %d created\n", - lnr, so, so->fd); + lnr, (int)so, so->fd); return so; } #define my_socket_new(a) _my_socket_new (__LINE__, (a)) @@ -374,7 +394,7 @@ _my_socket_ref (int lnr, my_socket_t so) so->refcount++; if (opt_debug > 1) log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n", - lnr, so, so->fd, so->refcount); + lnr, (int)so, so->fd, so->refcount); return so; } #define my_socket_ref(a) _my_socket_ref (__LINE__,(a)) @@ -392,7 +412,7 @@ _my_socket_unref (int lnr, my_socket_t so, so->refcount--; if (opt_debug > 1) log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n", - lnr, so, so->fd, so->refcount); + lnr, (int)so, so->fd, so->refcount); if (!so->refcount) { @@ -1768,7 +1788,14 @@ send_request (http_t hd, const char *httphost, const char *auth, my_socket_ref (hd->sock); + /* Until we support send/recv in estream under Windows we need + * to use es_fopencookie. */ +#ifdef HAVE_W32_SYSTEM + in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb", + simple_cookie_functions); +#else in = es_fdopen_nc (hd->sock->fd, "rb"); +#endif if (!in) { err = gpg_error_from_syserror (); @@ -1776,7 +1803,12 @@ send_request (http_t hd, const char *httphost, const char *auth, return err; } +#ifdef HAVE_W32_SYSTEM + out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb", + simple_cookie_functions); +#else out = es_fdopen_nc (hd->sock->fd, "wb"); +#endif if (!out) { err = gpg_error_from_syserror (); @@ -2651,6 +2683,41 @@ connect_server (const char *server, unsigned short port, } +/* Helper to read from a socket. This handles npth things and + * EINTR. */ +static gpgrt_ssize_t +read_server (int sock, void *buffer, size_t size) +{ + int nread; + + do + { +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to use recv for a socket. */ +# if defined(USE_NPTH) + npth_unprotect (); +# endif + nread = recv (sock, buffer, size, 0); +# if defined(USE_NPTH) + npth_protect (); +# endif + +#else /*!HAVE_W32_SYSTEM*/ + +# ifdef USE_NPTH + nread = npth_read (sock, buffer, size); +# else + nread = read (sock, buffer, size); +# endif + +#endif /*!HAVE_W32_SYSTEM*/ + } + while (nread == -1 && errno == EINTR); + + return nread; +} + + static gpg_error_t write_server (int sock, const char *data, size_t length) { @@ -2766,29 +2833,7 @@ cookie_read (void *cookie, void *buffer, size_t size) else #endif /*HTTP_USE_GNUTLS*/ { - do - { -#ifdef HAVE_W32_SYSTEM - /* Under Windows we need to use recv for a socket. */ -# if defined(USE_NPTH) - npth_unprotect (); -# endif - nread = recv (c->sock->fd, buffer, size, 0); -# if defined(USE_NPTH) - npth_protect (); -# endif - -#else /*!HAVE_W32_SYSTEM*/ - -# ifdef USE_NPTH - nread = npth_read (c->sock->fd, buffer, size); -# else - nread = read (c->sock->fd, buffer, size); -# endif - -#endif /*!HAVE_W32_SYSTEM*/ - } - while (nread == -1 && errno == EINTR); + nread = read_server (c->sock->fd, buffer, size); } if (c->content_length_valid && nread > 0) @@ -2870,6 +2915,34 @@ cookie_write (void *cookie, const void *buffer_arg, size_t size) } +#ifdef HAVE_W32_SYSTEM +static gpgrt_ssize_t +simple_cookie_read (void *cookie, void *buffer, size_t size) +{ + int sock = (int)(uintptr_t)cookie; + return read_server (sock, buffer, size); +} + +static gpgrt_ssize_t +simple_cookie_write (void *cookie, const void *buffer_arg, size_t size) +{ + int sock = (int)(uintptr_t)cookie; + const char *buffer = buffer_arg; + int nwritten; + + if (write_server (sock, buffer, size)) + { + gpg_err_set_errno (EIO); + nwritten = -1; + } + else + nwritten = size; + + return (gpgrt_ssize_t)nwritten; +} +#endif /*HAVE_W32_SYSTEM*/ + + #ifdef HTTP_USE_GNUTLS /* Wrapper for gnutls_bye used by my_socket_unref. */ static void ----------------------------------------------------------------------- Summary of changes: dirmngr/http.c | 127 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 27 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 23 10:43:09 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 23 Feb 2017 10:43:09 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-131-gc2f02ea Message-ID: This is an 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 c2f02ea4ff1b74be66b4221e3ec83ab0351c2746 (commit) from a42bf00b4edce789999aa3bdfce235cf726463ae (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c2f02ea4ff1b74be66b4221e3ec83ab0351c2746 Author: Werner Koch Date: Thu Feb 23 10:33:07 2017 +0100 speedo,w32: Install gpg-wks-client. -- Signed-off-by: Werner Koch diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi index d117495..5ecd633 100644 --- a/build-aux/speedo/w32/inst.nsi +++ b/build-aux/speedo/w32/inst.nsi @@ -581,6 +581,7 @@ Section "GnuPG" SEC_gnupg File "bin/gpg-connect-agent.exe" File "bin/gpgtar.exe" File "libexec/gpg-preset-passphrase.exe" + File "libexec/gpg-wks-client" ClearErrors SetOverwrite try @@ -1263,6 +1264,7 @@ Section "-un.gnupg" Delete "$INSTDIR\bin\gpg-connect-agent.exe" Delete "$INSTDIR\bin\gpgtar.exe" Delete "$INSTDIR\bin\gpg-preset-passphrase.exe" + Delete "$INSTDIR\bin\gpg-wks-client.exe" Delete "$INSTDIR\share\gnupg\dirmngr-conf.skel" Delete "$INSTDIR\share\gnupg\distsigkey.gpg" ----------------------------------------------------------------------- Summary of changes: build-aux/speedo/w32/inst.nsi | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 23 20:17:54 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 23 Feb 2017 20:17:54 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-135-g22b69b9 Message-ID: This is an 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 22b69b9edfdf6e6172239cbd1075ffe29077d339 (commit) via d30e17ac62dea8913b7f353971d546b6b1a09bd5 (commit) via a2090250829fe8989be2afc8cf41ba2a022072fc (commit) via effa80e0b5fd8cf9e31a984afe391c2406edee8b (commit) from c2f02ea4ff1b74be66b4221e3ec83ab0351c2746 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 22b69b9edfdf6e6172239cbd1075ffe29077d339 Author: Werner Koch Date: Thu Feb 23 20:14:16 2017 +0100 dirmngr: Add new debug flag "extprog" * dirmngr/dirmngr.h (DBG_EXTPROG_VALUE, DBG_EXTPROG): New macros. * dirmngr/dirmngr.c (debug_flags): Add flag "extprog". (handle_connections): Use a macro instead of -1 for an invalid socket. * dirmngr/loadswdb.c (verify_status_cb): Debug the gpgv call. Signed-off-by: Werner Koch diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 6b4cbcf..c877a9b 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -267,6 +267,7 @@ static struct debug_flags_s debug_flags [] = { DBG_DNS_VALUE , "dns" }, { DBG_NETWORK_VALUE, "network" }, { DBG_LOOKUP_VALUE , "lookup" }, + { DBG_EXTPROG_VALUE, "extprog" }, { 77, NULL } /* 77 := Do not exit on "help" or "?". */ }; @@ -2215,7 +2216,7 @@ handle_connections (assuan_fd_t listen_fd) close (my_inotify_fd); #endif /*HAVE_INOTIFY_INIT*/ npth_attr_destroy (&tattr); - if (listen_fd != -1) + if (listen_fd != GNUPG_INVALID_FD) assuan_sock_close (fd); cleanup (); log_info ("%s %s stopped\n", strusage(11), strusage(13)); diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index b0b603f..b269865 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -144,6 +144,7 @@ struct #define DBG_IPC_VALUE 1024 /* debug assuan communication */ #define DBG_NETWORK_VALUE 2048 /* debug network I/O. */ #define DBG_LOOKUP_VALUE 8192 /* debug lookup details */ +#define DBG_EXTPROG_VALUE 16384 /* debug external program calls */ #define DBG_X509 (opt.debug & DBG_X509_VALUE) #define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) @@ -154,6 +155,7 @@ struct #define DBG_IPC (opt.debug & DBG_IPC_VALUE) #define DBG_NETWORK (opt.debug & DBG_NETWORK_VALUE) #define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE) +#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE) /* A simple list of certificate references. FIXME: Better use certlist_t also for references (Store NULL at .cert) */ diff --git a/dirmngr/http.c b/dirmngr/http.c index e5e36b2..890f5f6 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -382,7 +382,7 @@ _my_socket_new (int lnr, assuan_fd_t fd) so->refcount = 1; if (opt_debug) log_debug ("http.c:%d:socket_new: object %p for fd %d created\n", - lnr, (int)so, so->fd); + lnr, so, so->fd); return so; } #define my_socket_new(a) _my_socket_new (__LINE__, (a)) @@ -394,7 +394,7 @@ _my_socket_ref (int lnr, my_socket_t so) so->refcount++; if (opt_debug > 1) log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n", - lnr, (int)so, so->fd, so->refcount); + lnr, so, so->fd, so->refcount); return so; } #define my_socket_ref(a) _my_socket_ref (__LINE__,(a)) @@ -412,7 +412,7 @@ _my_socket_unref (int lnr, my_socket_t so, so->refcount--; if (opt_debug > 1) log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n", - lnr, (int)so, so->fd, so->refcount); + lnr, so, so->fd, so->refcount); if (!so->refcount) { diff --git a/dirmngr/loadswdb.c b/dirmngr/loadswdb.c index 2d6bdc1..5a7778d 100644 --- a/dirmngr/loadswdb.c +++ b/dirmngr/loadswdb.c @@ -191,6 +191,9 @@ verify_status_cb (void *opaque, const char *keyword, char *args) { struct verify_status_parm_s *parm = opaque; + if (DBG_EXTPROG) + log_debug ("gpgv status: %s %s\n", keyword, args); + /* We care only about the first valid signature. */ if (!strcmp (keyword, "VALIDSIG") && !parm->anyvalid) { @@ -302,12 +305,16 @@ dirmngr_load_swdb (ctrl_t ctrl, int force) goto leave; } + if (DBG_EXTPROG) + log_debug ("starting gpgv\n"); err = gnupg_exec_tool_stream (gnupg_module_name (GNUPG_MODULE_NAME_GPGV), argv, swdb, swdb_sig, NULL, verify_status_cb, &verify_status_parm); if (!err && verify_status_parm.sigtime == (time_t)(-1)) err = gpg_error (verify_status_parm.anyvalid? GPG_ERR_BAD_SIGNATURE /**/ : GPG_ERR_INV_TIME ); + if (DBG_EXTPROG) + log_debug ("gpgv finished: err=%d\n", err); if (err) goto leave; commit d30e17ac62dea8913b7f353971d546b6b1a09bd5 Author: Werner Koch Date: Thu Feb 23 20:10:59 2017 +0100 wks: Make sure that the draft 2 request is correctly detected. * tools/gpg-wks.h (WKS_DRAFT_VERSION): New. * tools/wks-receive.c (new_part): Move test wks draft version to ... (t2body): new callback. (wks_receive): Register this callback. * tools/gpg-wks-server.c (send_confirmation_request): Emit draft version header. (send_congratulation_message): Ditto. * tools/gpg-wks-client.c (decrypt_stream_parm_s): New. (decrypt_stream_status_cb): Check DECRYTPION_KEY status. (decrypt_stream): Get infor from new callback. (process_confirmation_request): New arg 'mainfpr'. Check that it matches the decryption key. (read_confirmation_request): Check that the decryption key has been generated by us. (command_send): Use macro from draft version header. (send_confirmation_response): Emit draft version header. -- This patch also adds a check to only send a confirmation when the decryption has been done by an ultimately trusted (self-generated) key. Signed-off-by: Werner Koch diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index fa19fc1..c31e3a1 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -373,6 +373,7 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec) log_error ("error allocating memory buffer: %s\n", gpg_strerror (err)); goto leave; } + /* Prefix the key with the MIME content type. */ es_fputs ("Content-Type: application/pgp-keys\n" "\n", key); @@ -437,20 +438,38 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec) +struct decrypt_stream_parm_s +{ + char *fpr; + char *mainfpr; + int otrust; +}; + static void decrypt_stream_status_cb (void *opaque, const char *keyword, char *args) { - (void)opaque; + struct decrypt_stream_parm_s *decinfo = opaque; if (DBG_CRYPTO) log_debug ("gpg status: %s %s\n", keyword, args); -} + if (!strcmp (keyword, "DECRYPTION_KEY") && !decinfo->fpr) + { + char *fields[3]; + if (split_fields (args, fields, DIM (fields)) >= 3) + { + decinfo->fpr = xstrdup (fields[0]); + decinfo->mainfpr = xstrdup (fields[1]); + decinfo->otrust = *fields[2]; + } + } +} /* Decrypt the INPUT stream to a new stream which is stored at success * at R_OUTPUT. */ static gpg_error_t -decrypt_stream (estream_t *r_output, estream_t input) +decrypt_stream (estream_t *r_output, struct decrypt_stream_parm_s *decinfo, + estream_t input) { gpg_error_t err; ccparray_t ccp; @@ -458,6 +477,7 @@ decrypt_stream (estream_t *r_output, estream_t input) estream_t output; *r_output = NULL; + memset (decinfo, 0, sizeof *decinfo); output = es_fopenmem (0, "w+b"); if (!output) @@ -492,7 +512,9 @@ decrypt_stream (estream_t *r_output, estream_t input) } err = gnupg_exec_tool_stream (opt.gpg_program, argv, input, NULL, output, - decrypt_stream_status_cb, NULL); + decrypt_stream_status_cb, decinfo); + if (!err && (!decinfo->fpr || !decinfo->mainfpr || !decinfo->otrust)) + err = gpg_error (GPG_ERR_INV_ENGINE); if (err) { log_error ("decryption failed: %s\n", gpg_strerror (err)); @@ -506,6 +528,12 @@ decrypt_stream (estream_t *r_output, estream_t input) output = NULL; leave: + if (err) + { + xfree (decinfo->fpr); + xfree (decinfo->mainfpr); + memset (decinfo, 0, sizeof *decinfo); + } es_fclose (output); xfree (argv); return err; @@ -749,8 +777,9 @@ command_send (const char *fingerprint, char *userid) if (err) goto leave; - /* Tell server that we support draft version 3. */ - err = mime_maker_add_header (mime, "Wks-Draft-Version", "3"); + /* Tell server which draft we support. */ + err = mime_maker_add_header (mime, "Wks-Draft-Version", + STR2(WKS_DRAFT_VERSION)); if (err) goto leave; @@ -948,6 +977,10 @@ send_confirmation_response (const char *sender, const char *address, err = mime_maker_add_header (mime, "Subject", "Key publication confirmation"); if (err) goto leave; + err = mime_maker_add_header (mime, "Wks-Draft-Version", + STR2(WKS_DRAFT_VERSION)); + if (err) + goto leave; if (encrypt) { @@ -998,9 +1031,11 @@ send_confirmation_response (const char *sender, const char *address, /* Reply to a confirmation request. The MSG has already been - * decrypted and we only need to send the nonce back. */ + * decrypted and we only need to send the nonce back. MAINFPR is + * either NULL or the primary key fingerprint of the key used to + * decrypt the request. */ static gpg_error_t -process_confirmation_request (estream_t msg) +process_confirmation_request (estream_t msg, const char *mainfpr) { gpg_error_t err; nvc_t nvc; @@ -1044,8 +1079,20 @@ process_confirmation_request (estream_t msg) } fingerprint = value; - /* FIXME: Check that the fingerprint matches the key used to decrypt the - * message. */ + /* Check that the fingerprint matches the key used to decrypt the + * message. In --read mode or with the old format we don't have the + * decryption key; thus we can't bail out. */ + if (!mainfpr || ascii_strcasecmp (mainfpr, fingerprint)) + { + log_info ("target fingerprint: %s\n", fingerprint); + log_info ("but decrypted with: %s\n", mainfpr); + log_error ("confirmation request not decrypted with target key\n"); + if (mainfpr) + { + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + } /* Get the address. */ if (!((item = nvc_lookup (nvc, "address:")) && (value = nve_value (item)) @@ -1058,10 +1105,7 @@ process_confirmation_request (estream_t msg) } address = value; /* FIXME: Check that the "address" matches the User ID we want to - * publish. Also get the "fingerprint" and compare that to our to - * be published key. Further we should make sure that we actually - * decrypted using that fingerprint (which is a bit problematic if - * --read is used). */ + * publish. */ /* Get the sender. */ if (!((item = nvc_lookup (nvc, "sender:")) && (value = nve_value (item)) @@ -1130,14 +1174,24 @@ read_confirmation_request (estream_t msg) } if (c != '-') - err = process_confirmation_request (msg); + err = process_confirmation_request (msg, NULL); else { - err = decrypt_stream (&plaintext, msg); + struct decrypt_stream_parm_s decinfo; + + err = decrypt_stream (&plaintext, &decinfo, msg); if (err) log_error ("decryption failed: %s\n", gpg_strerror (err)); + else if (decinfo.otrust != 'u') + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + log_error ("key used to decrypt the confirmation request" + " was not generated by us\n"); + } else - err = process_confirmation_request (plaintext); + err = process_confirmation_request (plaintext, decinfo.mainfpr); + xfree (decinfo.fpr); + xfree (decinfo.mainfpr); } es_fclose (plaintext); diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index c17c1cf..0376cce 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -916,7 +916,12 @@ send_confirmation_request (server_ctx_t ctx, if (err) goto leave; - /* Help Enigmail to identify messages. Note that this is on no way + err = mime_maker_add_header (mime, "Wks-Draft-Version", + STR2(WKS_DRAFT_VERSION)); + if (err) + goto leave; + + /* Help Enigmail to identify messages. Note that this is in no way * secured. */ err = mime_maker_add_header (mime, "WKS-Phase", "confirm"); if (err) @@ -1015,7 +1020,7 @@ send_confirmation_request (server_ctx_t ctx, if (err) goto leave; - mime_maker_dump_tree (mime); + /* mime_maker_dump_tree (mime); */ err = mime_maker_get_part (mime, partid, &signeddata); if (err) goto leave; @@ -1213,6 +1218,10 @@ send_congratulation_message (const char *mbox, const char *keyfile) err = mime_maker_add_header (mime, "Subject", "Your key has been published"); if (err) goto leave; + err = mime_maker_add_header (mime, "Wks-Draft-Version", + STR2(WKS_DRAFT_VERSION)); + if (err) + goto leave; err = mime_maker_add_header (mime, "WKS-Phase", "done"); if (err) goto leave; diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h index 62ceb34..3b28af4 100644 --- a/tools/gpg-wks.h +++ b/tools/gpg-wks.h @@ -24,6 +24,10 @@ #include "../common/strlist.h" #include "mime-maker.h" +/* The draft version we implement. */ +#define WKS_DRAFT_VERSION 3 + + /* We keep all global options in the structure OPT. */ struct { diff --git a/tools/wks-receive.c b/tools/wks-receive.c index 12ec089..94f8bc6 100644 --- a/tools/wks-receive.c +++ b/tools/wks-receive.c @@ -255,6 +255,38 @@ collect_signature (void *cookie, const char *data) } +/* The callback for the transition from header to body. We use it to + * look at some header values. */ +static gpg_error_t +t2body (void *cookie, int level) +{ + receive_ctx_t ctx = cookie; + rfc822parse_t msg; + char *value; + size_t valueoff; + + log_info ("t2body for level %d\n", level); + if (!level) + { + /* This is the outermost header. */ + msg = mime_parser_rfc822parser (ctx->parser); + if (msg) + { + value = rfc822parse_get_field (msg, "Wks-Draft-Version", + -1, &valueoff); + if (value) + { + if (atoi(value+valueoff) >= 2 ) + ctx->draft_version_2 = 1; + free (value); + } + } + } + + return 0; +} + + static gpg_error_t new_part (void *cookie, const char *mediatype, const char *mediasubtype) { @@ -275,22 +307,6 @@ new_part (void *cookie, const char *mediatype, const char *mediasubtype) } else { - rfc822parse_t msg = mime_parser_rfc822parser (ctx->parser); - if (msg) - { - char *value; - size_t valueoff; - - value = rfc822parse_get_field (msg, "Wks-Draft-Version", - -1, &valueoff); - if (value) - { - if (atoi(value+valueoff) >= 2 ) - ctx->draft_version_2 = 1; - free (value); - } - } - ctx->key_data = es_fopenmem (0, "w+b"); if (!ctx->key_data) { @@ -413,6 +429,7 @@ wks_receive (estream_t fp, goto leave; if (DBG_PARSER) mime_parser_set_verbose (parser, 1); + mime_parser_set_t2body (parser, t2body); mime_parser_set_new_part (parser, new_part); mime_parser_set_part_data (parser, part_data); mime_parser_set_collect_encrypted (parser, collect_encrypted); commit a2090250829fe8989be2afc8cf41ba2a022072fc Author: Werner Koch Date: Thu Feb 23 20:01:30 2017 +0100 wks: New callback for the mime parser. * tools/mime-parser.c (mime_parser_context_s): New field 't2body'. (parse_message_cb): Call that callback. (mime_parser_set_t2body): New. -- This callback allows to process header values even on the outer level. Signed-off-by: Werner Koch diff --git a/tools/mime-parser.c b/tools/mime-parser.c index 264353c..169ea2b 100644 --- a/tools/mime-parser.c +++ b/tools/mime-parser.c @@ -49,6 +49,9 @@ struct mime_parser_context_s { void *cookie; /* Cookie passed to all callbacks. */ + /* The callback to announce the transation from header to body. */ + gpg_error_t (*t2body) (void *cookie, int level); + /* The callback to announce a new part. */ gpg_error_t (*new_part) (void *cookie, const char *mediatype, @@ -224,6 +227,14 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) ctx->want_part = 0; ctx->decode_part = 0; + + if (ctx->t2body) + { + rc = ctx->t2body (ctx->cookie, ctx->nesting_level); + if (rc) + goto t2body_leave; + } + field = rfc822parse_parse_field (msg, "Content-Type", -1); if (field) { @@ -412,6 +423,7 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) } } + t2body_leave: ctx->show.header = 0; ctx->show.data = 1; ctx->show.n_skip = 1; @@ -541,6 +553,19 @@ mime_parser_set_verbose (mime_parser_t ctx, int level) } +/* Set a callback for the transition from header to body. LEVEL is + * the current nesting level, starting with 0. This callback can be + * used to evaluate headers before any other action is done. Note + * that if a new NEW_PART callback needs to be called it is done after + * this T2BODY callback. */ +void +mime_parser_set_t2body (mime_parser_t ctx, + gpg_error_t (*fnc) (void *cookie, int level)) +{ + ctx->t2body = fnc; +} + + /* Set the callback used to announce a new part. It will be called * with the media type and media subtype of the part. If no * Content-type header was given both values are the empty string. diff --git a/tools/mime-parser.h b/tools/mime-parser.h index 37a74a1..b9bb465 100644 --- a/tools/mime-parser.h +++ b/tools/mime-parser.h @@ -27,6 +27,8 @@ gpg_error_t mime_parser_new (mime_parser_t *r_ctx, void *cookie); void mime_parser_release (mime_parser_t ctx); void mime_parser_set_verbose (mime_parser_t ctx, int level); +void mime_parser_set_t2body (mime_parser_t ctx, + gpg_error_t (*fnc) (void *cookie, int level)); void mime_parser_set_new_part (mime_parser_t ctx, gpg_error_t (*fnc) (void *cookie, const char *mediatype, commit effa80e0b5fd8cf9e31a984afe391c2406edee8b Author: Werner Koch Date: Thu Feb 23 19:59:21 2017 +0100 gpg: Emit new status DECRYPTION_KEY * common/status.h (STATUS_DECRYPTION_KEY): New. * g10/pubkey-enc.c (get_it): Emit that status. Signed-off-by: Werner Koch diff --git a/common/status.h b/common/status.h index 3de4aa5..8831a0f 100644 --- a/common/status.h +++ b/common/status.h @@ -57,6 +57,7 @@ enum STATUS_NO_PUBKEY, STATUS_NO_SECKEY, STATUS_NEED_PASSPHRASE_SYM, + STATUS_DECRYPTION_KEY, STATUS_DECRYPTION_INFO, STATUS_DECRYPTION_FAILED, STATUS_DECRYPTION_OKAY, diff --git a/doc/DETAILS b/doc/DETAILS index d9b1fa6..8c11872 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -486,6 +486,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: *** END_DECRYPTION Mark the end of the actual decryption process. This are also emitted when in --list-only mode. +*** DECRYPTION_KEY + This line is emitted when a public key decryption succeeded in + providing a session key. is the hexified fingerprint of the + actual key used for descryption. is the fingerprint of the + primary key. is the letter with the ownertrust; this is + in general a 'u' which stands for ultimately trusted. *** DECRYPTION_INFO Print information about the symmetric encryption algorithm and the MDC method. This will be emitted even if the decryption fails. diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index de98d99..1772936 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -335,9 +335,11 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (DBG_CRYPTO) log_printhex ("DEK is:", dek->key, dek->keylen); - /* Check that the algo is in the preferences and whether it has expired. */ + /* Check that the algo is in the preferences and whether it has + * expired. Also print a status line with the key's fingerprint. */ { PKT_public_key *pk = NULL; + PKT_public_key *mainpk = NULL; KBNODE pkb = get_pubkeyblock (keyid); if (!pkb) @@ -351,9 +353,11 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo)) log_info (_("WARNING: cipher algorithm %s not found in recipient" " preferences\n"), openpgp_cipher_algo_name (dek->algo)); + if (!err) { - KBNODE k; + kbnode_t k; + int first = 1; for (k = pkb; k; k = k->next) { @@ -361,8 +365,14 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) || k->pkt->pkttype == PKT_PUBLIC_SUBKEY) { u32 aki[2]; - keyid_from_pk (k->pkt->pkt.public_key, aki); + if (first) + { + first = 0; + mainpk = k->pkt->pkt.public_key; + } + + keyid_from_pk (k->pkt->pkt.public_key, aki); if (aki[0] == keyid[0] && aki[1] == keyid[1]) { pk = k->pkt->pkt.public_key; @@ -386,6 +396,19 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) show_revocation_reason (pk, 1); } + if (is_status_enabled () && pk && mainpk) + { + char pkhex[MAX_FINGERPRINT_LEN*2+1]; + char mainpkhex[MAX_FINGERPRINT_LEN*2+1]; + + hexfingerprint (pk, pkhex, sizeof pkhex); + hexfingerprint (mainpk, mainpkhex, sizeof mainpkhex); + + write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c", + pkhex, mainpkhex, get_ownertrust_info (mainpk)); + + } + release_kbnode (pkb); err = 0; } ----------------------------------------------------------------------- Summary of changes: common/status.h | 1 + dirmngr/dirmngr.c | 3 +- dirmngr/dirmngr.h | 2 ++ dirmngr/http.c | 6 ++-- dirmngr/loadswdb.c | 7 ++++ doc/DETAILS | 6 ++++ g10/pubkey-enc.c | 29 +++++++++++++++-- tools/gpg-wks-client.c | 88 ++++++++++++++++++++++++++++++++++++++++---------- tools/gpg-wks-server.c | 13 ++++++-- tools/gpg-wks.h | 4 +++ tools/mime-parser.c | 25 ++++++++++++++ tools/mime-parser.h | 2 ++ tools/wks-receive.c | 49 +++++++++++++++++++--------- 13 files changed, 193 insertions(+), 42 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 23 20:19:06 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 23 Feb 2017 20:19:06 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-12-gc9e44c9 Message-ID: This is an 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 c9e44c92e08187626e878d826cdedf4cd4e931fe (commit) from 3a2ee6df5911728938a2fb56237b08f790841a0c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c9e44c92e08187626e878d826cdedf4cd4e931fe Author: Werner Koch Date: Thu Feb 23 15:20:44 2017 +0100 w32: Replace gpgrt locks in w32-streams by native critical sections. * src/w32-estream.c (TRACE_ERR): Also print the error number. This is in particular useful on non-english systems. (reader_context_s, writer_context_s): Replace the gpgrt mutex by a native critical section. Change all calls to gpgrt_lock_ fucntions by the EnterCriticalSection et al. (_gpgrt_w32_poll): Make CODE unsigned which is what WFMO returns. Remove the then useless condition. -- The locking code here is self-contained and may badly interact with the possible nPth "clamped" gpgrt lock functions. Signed-off-by: Werner Koch diff --git a/src/w32-estream.c b/src/w32-estream.c index 516b238..1603d30 100644 --- a/src/w32-estream.c +++ b/src/w32-estream.c @@ -65,8 +65,8 @@ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \ (LPTSTR) &error_message, \ sizeof error_message, NULL ); \ - fprintf (stderr, "%p: " msg ": %s\n", ctx, \ - ## __VA_ARGS__, error_message); \ + fprintf (stderr, "%p: " msg ": %d (%s)\n", ctx, \ + ## __VA_ARGS__, (int)(err), error_message); \ } while (0) #else #define TRACE(msg, ...) (void) 0 @@ -92,7 +92,7 @@ struct reader_context_s estream_cookie_w32_pollable_t pcookie; HANDLE thread_hd; - gpgrt_lock_t mutex; + CRITICAL_SECTION mutex; int stop_me; int eof; @@ -116,7 +116,7 @@ struct writer_context_s estream_cookie_w32_pollable_t pcookie; HANDLE thread_hd; - gpgrt_lock_t mutex; + CRITICAL_SECTION mutex; int stop_me; int error; @@ -179,7 +179,7 @@ reader (void *arg) for (;;) { - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); /* Leave a 1 byte gap so that we can see whether it is empty or full. */ while ((ctx->writepos + 1) % READBUF_SIZE == ctx->readpos) @@ -187,16 +187,16 @@ reader (void *arg) /* Wait for space. */ if (!ResetEvent (ctx->have_space_ev)) TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); TRACE_CTX (ctx, "waiting for space"); WaitForSingleObject (ctx->have_space_ev, INFINITE); TRACE_CTX (ctx, "got space"); - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); } assert (((ctx->writepos + 1) % READBUF_SIZE != ctx->readpos)); if (ctx->stop_me) { - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); break; } nbytes = (ctx->readpos + READBUF_SIZE @@ -204,7 +204,7 @@ reader (void *arg) assert (nbytes); if (nbytes > READBUF_SIZE - ctx->writepos) nbytes = READBUF_SIZE - ctx->writepos; - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); TRACE_CTX (ctx, "reading up to %d bytes", nbytes); @@ -229,17 +229,17 @@ reader (void *arg) break; } - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); if (ctx->stop_me) { - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); break; } if (!nread) { ctx->eof = 1; TRACE_CTX (ctx, "got eof"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); break; } @@ -247,7 +247,7 @@ reader (void *arg) if (!SetEvent (ctx->have_data_ev)) TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed", ctx->have_data_ev); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); } /* Indicate that we have an error or EOF. */ if (!SetEvent (ctx->have_data_ev)) @@ -261,7 +261,7 @@ reader (void *arg) CloseHandle (ctx->have_data_ev); CloseHandle (ctx->have_space_ev); CloseHandle (ctx->thread_hd); - _gpgrt_lock_destroy (&ctx->mutex); + DeleteCriticalSection (&ctx->mutex); _gpgrt_free (ctx); return 0; @@ -306,7 +306,7 @@ create_reader (estream_cookie_w32_pollable_t pcookie) } ctx->have_data_ev = set_synchronize (ctx->have_data_ev); - _gpgrt_lock_init (&ctx->mutex); + InitializeCriticalSection (&ctx->mutex); #ifdef HAVE_W32CE_SYSTEM ctx->thread_hd = CreateThread (&sec_attr, 64 * 1024, reader, ctx, @@ -318,7 +318,7 @@ create_reader (estream_cookie_w32_pollable_t pcookie) if (!ctx->thread_hd) { TRACE_ERR (ctx, GetLastError (), "CreateThread failed"); - _gpgrt_lock_destroy (&ctx->mutex); + DeleteCriticalSection (&ctx->mutex); if (ctx->have_data_ev) CloseHandle (ctx->have_data_ev); if (ctx->have_space_ev) @@ -348,11 +348,11 @@ create_reader (estream_cookie_w32_pollable_t pcookie) static void destroy_reader (struct reader_context_s *ctx) { - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); ctx->stop_me = 1; if (ctx->have_space_ev) SetEvent (ctx->have_space_ev); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); #ifdef HAVE_W32CE_SYSTEM /* Scenario: We never create a full pipe, but already started @@ -402,13 +402,14 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) if (ctx->eof_shortcut) return 0; - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); TRACE_CTX (ctx, "readpos: %d, writepos %d", ctx->readpos, ctx->writepos); if (ctx->readpos == ctx->writepos && !ctx->error) { /* No data available. */ int eof = ctx->eof; - _gpgrt_lock_unlock (&ctx->mutex); + + LeaveCriticalSection (&ctx->mutex); if (pcookie->modeflags & O_NONBLOCK && ! eof) { @@ -419,12 +420,12 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) TRACE_CTX (ctx, "waiting for data"); WaitForSingleObject (ctx->have_data_ev, INFINITE); TRACE_CTX (ctx, "data available"); - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); } if (ctx->readpos == ctx->writepos || ctx->error) { - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); ctx->eof_shortcut = 1; if (ctx->eof) return 0; @@ -449,7 +450,7 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) if (!ResetEvent (ctx->have_data_ev)) { TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; @@ -459,12 +460,12 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) { TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed", ctx->have_space_ev); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; } - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); return nread; } @@ -483,10 +484,10 @@ writer (void *arg) for (;;) { - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); if (ctx->stop_me && !ctx->nbytes) { - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); break; } if (!ctx->nbytes) @@ -495,18 +496,18 @@ writer (void *arg) TRACE_ERR (ctx, GetLastError (), "SetEvent failed"); if (!ResetEvent (ctx->have_data)) TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); TRACE_CTX (ctx, "idle"); WaitForSingleObject (ctx->have_data, INFINITE); TRACE_CTX (ctx, "got data to write"); - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); } if (ctx->stop_me && !ctx->nbytes) { - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); break; } - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); TRACE_CTX (ctx, "writing up to %d bytes", ctx->nbytes); @@ -529,9 +530,9 @@ writer (void *arg) break; } - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); ctx->nbytes -= nwritten; - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); } /* Indicate that we have an error. */ if (!SetEvent (ctx->is_empty)) @@ -547,7 +548,7 @@ writer (void *arg) CloseHandle (ctx->have_data); CloseHandle (ctx->is_empty); CloseHandle (ctx->thread_hd); - _gpgrt_lock_destroy (&ctx->mutex); + DeleteCriticalSection (&ctx->mutex); _gpgrt_free (ctx); return 0; @@ -592,7 +593,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie) } ctx->is_empty = set_synchronize (ctx->is_empty); - _gpgrt_lock_init (&ctx->mutex); + InitializeCriticalSection (&ctx->mutex); #ifdef HAVE_W32CE_SYSTEM ctx->thread_hd = CreateThread (&sec_attr, 64 * 1024, writer, ctx, @@ -604,7 +605,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie) if (!ctx->thread_hd) { TRACE_ERR (ctx, GetLastError (), "CreateThread failed"); - _gpgrt_lock_destroy (&ctx->mutex); + DeleteCriticalSection (&ctx->mutex); if (ctx->have_data) CloseHandle (ctx->have_data); if (ctx->is_empty) @@ -631,11 +632,11 @@ create_writer (estream_cookie_w32_pollable_t pcookie) static void destroy_writer (struct writer_context_s *ctx) { - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); ctx->stop_me = 1; if (ctx->have_data) SetEvent (ctx->have_data); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); /* Give the writer a chance to flush the buffer. */ WaitForSingleObject (ctx->is_empty, INFINITE); @@ -678,7 +679,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) return -1; } - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); TRACE_CTX (ctx, "pollable write buffer: %p, count: %d, nbytes: %d", buffer, count, ctx->nbytes); if (!ctx->error && ctx->nbytes) @@ -689,12 +690,12 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) if (!ResetEvent (ctx->is_empty)) { TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; } - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); if (pcookie->modeflags & O_NONBLOCK) { @@ -706,12 +707,12 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) TRACE_CTX (ctx, "waiting for empty buffer"); WaitForSingleObject (ctx->is_empty, INFINITE); TRACE_CTX (ctx, "buffer is empty"); - _gpgrt_lock_lock (&ctx->mutex); + EnterCriticalSection (&ctx->mutex); } if (ctx->error) { - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); if (ctx->error_code == ERROR_NO_DATA) _gpg_err_set_errno (EPIPE); else @@ -733,7 +734,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) if (!ResetEvent (ctx->is_empty)) { TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; @@ -741,12 +742,12 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) if (!SetEvent (ctx->have_data)) { TRACE_ERR (ctx, GetLastError (), "SetEvent failed"); - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; } - _gpgrt_lock_unlock (&ctx->mutex); + LeaveCriticalSection (&ctx->mutex); return (int) count; } @@ -757,7 +758,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) { HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS]; int waitidx[MAXIMUM_WAIT_OBJECTS]; - int code; + unsigned int code; int nwait; int i; int any; @@ -850,7 +851,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) code = WaitForMultipleObjects (nwait, waitbuf, 0, timeout == -1 ? INFINITE : timeout); - if (code >= WAIT_OBJECT_0 && code < WAIT_OBJECT_0 + nwait) + if (code < WAIT_OBJECT_0 + nwait) { /* This WFMO is a really silly function: It does return either the index of the signaled object or if 2 objects have been @@ -908,7 +909,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) } else { - TRACE ("WFMO returned %d\n", code); + TRACE ("WFMO returned %u\n", code); count = -1; } ----------------------------------------------------------------------- Summary of changes: src/w32-estream.c | 99 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 49 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 24 10:35:39 2017 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 24 Feb 2017 10:35:39 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-136-g49b4a67 Message-ID: This is an 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 49b4a676148523b51beca3ae929e9d78ed7ba110 (commit) from 22b69b9edfdf6e6172239cbd1075ffe29077d339 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 49b4a676148523b51beca3ae929e9d78ed7ba110 Author: Andre Heinecke Date: Fri Feb 24 10:34:06 2017 +0100 speedo,w32: Fix gpg-wks-client installation * build-aux/speedo/w32/inst.nsi: gpg-wks-client is an exe. -- Signed-off-by: Andre Heinecke diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi index 5ecd633..fa4be56 100644 --- a/build-aux/speedo/w32/inst.nsi +++ b/build-aux/speedo/w32/inst.nsi @@ -581,7 +581,7 @@ Section "GnuPG" SEC_gnupg File "bin/gpg-connect-agent.exe" File "bin/gpgtar.exe" File "libexec/gpg-preset-passphrase.exe" - File "libexec/gpg-wks-client" + File "libexec/gpg-wks-client.exe" ClearErrors SetOverwrite try ----------------------------------------------------------------------- Summary of changes: build-aux/speedo/w32/inst.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 24 13:23:49 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 24 Feb 2017 13:23:49 +0100 Subject: [git] GPA - branch, master, updated. gpa-0.9.10-6-g0a78795 Message-ID: This is an 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 Assistant". The branch, master has been updated via 0a78795146661234070681737b3e08228616441f (commit) via 710b734dffc8f896ed36e287355b55adfac9342f (commit) from 26443b0c76b24b9a4d60d8d015461b0f4e7536e3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0a78795146661234070681737b3e08228616441f Author: Werner Koch Date: Fri Feb 24 13:20:36 2017 +0100 Change license of card application modules to LGPLv3+/GPLv2+. All code was written by me and Moritz Schulte who was at that time an employee of g10 Code GmbH. I am CEO of that company. Signed-off-by: Werner Koch diff --git a/src/cm-dinsig.c b/src/cm-dinsig.c index a8d1e14..3d9ba71 100644 --- a/src/cm-dinsig.c +++ b/src/cm-dinsig.c @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY diff --git a/src/cm-dinsig.h b/src/cm-dinsig.h index 35ed749..a77b601 100644 --- a/src/cm-dinsig.h +++ b/src/cm-dinsig.h @@ -3,6 +3,21 @@ * * This file is part of GPA. * + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. + * * GPA 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 @@ -14,7 +29,7 @@ * License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ #ifndef CM_DINSIG_H diff --git a/src/cm-geldkarte.c b/src/cm-geldkarte.c index 577b4c8..4c56abe 100644 --- a/src/cm-geldkarte.c +++ b/src/cm-geldkarte.c @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY diff --git a/src/cm-geldkarte.h b/src/cm-geldkarte.h index 6fff652..d8ab6bf 100644 --- a/src/cm-geldkarte.h +++ b/src/cm-geldkarte.h @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -14,7 +24,7 @@ * License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ #ifndef CM_GELDKARTE_H diff --git a/src/cm-netkey.c b/src/cm-netkey.c index 5f027cc..405c105 100644 --- a/src/cm-netkey.c +++ b/src/cm-netkey.c @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY diff --git a/src/cm-netkey.h b/src/cm-netkey.h index e5d3719..68140b1 100644 --- a/src/cm-netkey.h +++ b/src/cm-netkey.h @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -14,7 +24,7 @@ * License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ #ifndef CM_NETKEY_H diff --git a/src/cm-object.c b/src/cm-object.c index 28e36b0..be3d7fe 100644 --- a/src/cm-object.c +++ b/src/cm-object.c @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -14,7 +24,7 @@ * License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ #ifdef HAVE_CONFIG_H @@ -26,7 +36,7 @@ #include #include -#include "gpa.h" +#include "gpa.h" #include "cm-object.h" @@ -52,14 +62,14 @@ static void gpa_cm_object_finalize (GObject *object); -/************************************************************ +/************************************************************ ******************* Implementation ********************* ************************************************************/ -/************************************************************ +/************************************************************ ****************** Object Management ******************** ************************************************************/ @@ -102,10 +112,10 @@ gpa_cm_object_init (GTypeInstance *instance, void *class_ptr) static void gpa_cm_object_finalize (GObject *object) -{ +{ /* GpaCMObject *card = GPA_CM_OBJECT (object); */ - + parent_class->finalize (object); } @@ -115,7 +125,7 @@ GType gpa_cm_object_get_type (void) { static GType this_type = 0; - + if (!this_type) { static const GTypeInfo this_info = @@ -130,17 +140,17 @@ gpa_cm_object_get_type (void) 0, /* n_preallocs */ gpa_cm_object_init }; - + this_type = g_type_register_static (GTK_TYPE_VBOX, "GpaCMObject", &this_info, 0); } - + return this_type; } -/************************************************************ +/************************************************************ ********************** Public API ************************ ************************************************************/ @@ -151,7 +161,7 @@ gpa_cm_object_update_status (GpaCMObject *obj, const char *text) { g_return_if_fail (obj); g_return_if_fail (GPA_CM_OBJECT (obj)); - + if (!text) text = ""; @@ -164,6 +174,6 @@ gpa_cm_object_alert_dialog (GpaCMObject *obj, const gchar *messageg) { g_return_if_fail (obj); g_return_if_fail (GPA_CM_OBJECT (obj)); - + g_signal_emit (obj, signals[ALERT_DIALOG], 0, messageg); } diff --git a/src/cm-object.h b/src/cm-object.h index dbe3118..ab22894 100644 --- a/src/cm-object.h +++ b/src/cm-object.h @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -14,7 +24,7 @@ * License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ #ifndef CM_OBJECT_H @@ -49,7 +59,7 @@ GType gpa_cm_object_get_type (void) G_GNUC_CONST; /* Object's class definition. */ -struct _GpaCMObjectClass +struct _GpaCMObjectClass { GtkVBoxClass parent_class; diff --git a/src/cm-openpgp.c b/src/cm-openpgp.c index 0c81bf7..857baed 100644 --- a/src/cm-openpgp.c +++ b/src/cm-openpgp.c @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY diff --git a/src/cm-openpgp.h b/src/cm-openpgp.h index e34c359..0c82003 100644 --- a/src/cm-openpgp.h +++ b/src/cm-openpgp.h @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -14,7 +24,7 @@ * License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ #ifndef CM_OPENPGP_H diff --git a/src/cm-unknown.c b/src/cm-unknown.c index db27058..e560b84 100644 --- a/src/cm-unknown.c +++ b/src/cm-unknown.c @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -17,7 +27,7 @@ * along with this program; if not, see . */ -/* UNKNOWN is a dummy application used for, weel, unknown cards. It +/* UNKNOWN is a dummy application used for, well, unknown cards. It does only print the the ATR of the card. */ #ifdef HAVE_CONFIG_H diff --git a/src/cm-unknown.h b/src/cm-unknown.h index 41f44ff..352cd97 100644 --- a/src/cm-unknown.h +++ b/src/cm-unknown.h @@ -3,10 +3,20 @@ * * This file is part of GPA. * - * GPA 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. + * GPA is free software; you can redistribute and/or modify this part + * of GPA 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. * * GPA is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY commit 710b734dffc8f896ed36e287355b55adfac9342f Author: Werner Koch Date: Thu Feb 9 09:48:28 2017 +0100 Add mimetimes to gpa.desktop -- Suggested-by: Olivier Mehani Signed-off-by: Werner Koch diff --git a/gpa.desktop b/gpa.desktop index 789ce7c..abeffe5 100644 --- a/gpa.desktop +++ b/gpa.desktop @@ -5,8 +5,9 @@ Name[en_US.ISO8859-1]=gpa GenericName=GNU Privacy Assistant GenericName[sv]=GNU Integritets-hj?lpreda GenericName[en_US.ISO8859-1]=GNU Privacy Assistant -Exec=gpa +Exec=gpa %f Icon=gpa Terminal=false Type=Application Categories=GTK;Application;Security;Utility; +MimeType=application/pgp-encrypted;application/pgp-signature ----------------------------------------------------------------------- Summary of changes: gpa.desktop | 3 ++- src/cm-dinsig.c | 18 ++++++++++++++---- src/cm-dinsig.h | 17 ++++++++++++++++- src/cm-geldkarte.c | 18 ++++++++++++++---- src/cm-geldkarte.h | 20 +++++++++++++++----- src/cm-netkey.c | 18 ++++++++++++++---- src/cm-netkey.h | 20 +++++++++++++++----- src/cm-object.c | 42 ++++++++++++++++++++++++++---------------- src/cm-object.h | 22 ++++++++++++++++------ src/cm-openpgp.c | 18 ++++++++++++++---- src/cm-openpgp.h | 20 +++++++++++++++----- src/cm-unknown.c | 20 +++++++++++++++----- src/cm-unknown.h | 18 ++++++++++++++---- 13 files changed, 190 insertions(+), 64 deletions(-) hooks/post-receive -- The GNU Privacy Assistant http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 24 13:53:21 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 24 Feb 2017 13:53:21 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-138-g55b6c25 Message-ID: This is an 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 55b6c2595a97346895ed42bcc8b72151792f5bd8 (commit) via 7af5d61c6e210210c777be9e6e87720dd4a055d9 (commit) from 49b4a676148523b51beca3ae929e9d78ed7ba110 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 55b6c2595a97346895ed42bcc8b72151792f5bd8 Author: Werner Koch Date: Fri Feb 24 13:48:28 2017 +0100 Clarify text of LGPLv2+/GPLv2+ licensed files. -- diff --git a/common/argparse.c b/common/argparse.c index fbe8a37..2540894 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/argparse.h b/common/argparse.h index 81e881d..d75b49f 100644 --- a/common/argparse.h +++ b/common/argparse.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/dotlock.c b/common/dotlock.c index 5fe652e..cbbd0f3 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/dotlock.h b/common/dotlock.h index 78a7e73..03131bb 100644 --- a/common/dotlock.h +++ b/common/dotlock.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/dynload.h b/common/dynload.h index 61930d2..54a47b2 100644 --- a/common/dynload.h +++ b/common/dynload.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/logging.c b/common/logging.c index 97f0813..18c40b3 100644 --- a/common/logging.c +++ b/common/logging.c @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/logging.h b/common/logging.h index 515d850..e1bf56b 100644 --- a/common/logging.h +++ b/common/logging.h @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/mischelp.c b/common/mischelp.c index fd8f675..75ba607 100644 --- a/common/mischelp.c +++ b/common/mischelp.c @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/mischelp.h b/common/mischelp.h index 1ad146e..18ec96e 100644 --- a/common/mischelp.h +++ b/common/mischelp.h @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/stringhelp.c b/common/stringhelp.c index dea2212..341dd52 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -6,8 +6,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/stringhelp.h b/common/stringhelp.h index d0156d5..3852d0f 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -5,8 +5,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/strlist.c b/common/strlist.c index 02881cd..6feb3a4 100644 --- a/common/strlist.c +++ b/common/strlist.c @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/strlist.h b/common/strlist.h index d74bc4d..641ea06 100644 --- a/common/strlist.h +++ b/common/strlist.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index d86d896..a105ad1 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/t-strlist.c b/common/t-strlist.c index bd835ca..fdbeb9b 100644 --- a/common/t-strlist.c +++ b/common/t-strlist.c @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/t-support.c b/common/t-support.c index 8ed0a62..fc4bd4b 100644 --- a/common/t-support.c +++ b/common/t-support.c @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/t-support.h b/common/t-support.h index 5449a56..7aa46c0 100644 --- a/common/t-support.h +++ b/common/t-support.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/t-timestuff.c b/common/t-timestuff.c index 1e524f5..6a75925 100644 --- a/common/t-timestuff.c +++ b/common/t-timestuff.c @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/t-w32-reg.c b/common/t-w32-reg.c index 48ea0d4..01816db 100644 --- a/common/t-w32-reg.c +++ b/common/t-w32-reg.c @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/types.h b/common/types.h index 7d85a35..8e551df 100644 --- a/common/types.h +++ b/common/types.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/utf8conv.c b/common/utf8conv.c index d26eff0..d2c2820 100644 --- a/common/utf8conv.c +++ b/common/utf8conv.c @@ -4,8 +4,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/utf8conv.h b/common/utf8conv.h index 1c6c584..8b76e11 100644 --- a/common/utf8conv.h +++ b/common/utf8conv.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/util.h b/common/util.h index f7a53e1..4e871d2 100644 --- a/common/util.h +++ b/common/util.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/w32-reg.c b/common/w32-reg.c index 2d64215..d8d94b9 100644 --- a/common/w32-reg.c +++ b/common/w32-reg.c @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 diff --git a/common/w32help.h b/common/w32help.h index e495e34..177efbc 100644 --- a/common/w32help.h +++ b/common/w32help.h @@ -3,8 +3,8 @@ * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of either + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG 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 commit 7af5d61c6e210210c777be9e6e87720dd4a055d9 Author: Werner Koch Date: Fri Feb 24 10:20:41 2017 +0100 gpgv: New options --log-file and --debug * g10/gpgv.c (oLoggerFile, oDebug): New consts. (opts): Add options --log-file and --debug. (main): Implement options. Signed-off-by: Werner Koch diff --git a/doc/gpgv.texi b/doc/gpgv.texi index 0608a3f..5336c98 100644 --- a/doc/gpgv.texi +++ b/doc/gpgv.texi @@ -111,6 +111,11 @@ file DETAILS in the documentation for a listing of them. @opindex logger-fd Write log output to file descriptor @code{n} and not to stderr. + at item --log-file @code{file} + at opindex log-file +Same as @option{--logger-fd}, except the logger data is written to +file @code{file}. Use @file{socket://} to log to socket. + @item --ignore-time-conflict @opindex ignore-time-conflict GnuPG normally checks that the timestamps associated with keys and diff --git a/g10/gpgv.c b/g10/gpgv.c index bd16b39..ab6f530 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -61,9 +61,11 @@ enum cmd_and_opt_values { oIgnoreTimeConflict, oStatusFD, oLoggerFD, + oLoggerFile, oHomedir, oWeakDigest, oEnableSpecialFilenames, + oDebug, aTest }; @@ -81,15 +83,37 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_s (oLoggerFile, "log-file", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oWeakDigest, "weak-digest", N_("|ALGO|reject signatures made with ALGO")), ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), + ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_end () }; +/* The list of supported debug flags. */ +static struct debug_flags_s debug_flags [] = + { + { DBG_PACKET_VALUE , "packet" }, + { DBG_MPI_VALUE , "mpi" }, + { DBG_CRYPTO_VALUE , "crypto" }, + { DBG_FILTER_VALUE , "filter" }, + { DBG_IOBUF_VALUE , "iobuf" }, + { DBG_MEMORY_VALUE , "memory" }, + { DBG_CACHE_VALUE , "cache" }, + { DBG_MEMSTAT_VALUE, "memstat" }, + { DBG_TRUST_VALUE , "trust" }, + { DBG_HASHING_VALUE, "hashing" }, + { DBG_IPC_VALUE , "ipc" }, + { DBG_CLOCK_VALUE , "clock" }, + { DBG_LOOKUP_VALUE , "lookup" }, + { DBG_EXTPROG_VALUE, "extprog" }, + { 0, NULL } + }; + int g10_errors_seen = 0; @@ -192,12 +216,25 @@ main( int argc, char **argv ) opt.list_sigs=1; gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); break; + case oDebug: + if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags)) + { + pargs.r_opt = ARGPARSE_INVALID_ARG; + pargs.err = ARGPARSE_PRINT_ERROR; + } + break; case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oOutput: opt.outfile = pargs.r.ret_str; break; case oStatusFD: set_status_fd( pargs.r.ret_int ); break; case oLoggerFD: log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; + case oLoggerFile: + log_set_file (pargs.r.ret_str); + log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX + | GPGRT_LOG_WITH_TIME + | GPGRT_LOG_WITH_PID) ); + break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oWeakDigest: additional_weak_digest(pargs.r.ret_str); ----------------------------------------------------------------------- Summary of changes: common/argparse.c | 4 ++-- common/argparse.h | 4 ++-- common/dotlock.c | 4 ++-- common/dotlock.h | 4 ++-- common/dynload.h | 4 ++-- common/logging.c | 4 ++-- common/logging.h | 4 ++-- common/mischelp.c | 4 ++-- common/mischelp.h | 4 ++-- common/stringhelp.c | 4 ++-- common/stringhelp.h | 4 ++-- common/strlist.c | 4 ++-- common/strlist.h | 4 ++-- common/t-stringhelp.c | 4 ++-- common/t-strlist.c | 4 ++-- common/t-support.c | 4 ++-- common/t-support.h | 4 ++-- common/t-timestuff.c | 4 ++-- common/t-w32-reg.c | 4 ++-- common/types.h | 4 ++-- common/utf8conv.c | 4 ++-- common/utf8conv.h | 4 ++-- common/util.h | 4 ++-- common/w32-reg.c | 4 ++-- common/w32help.h | 4 ++-- doc/gpgv.texi | 5 +++++ g10/gpgv.c | 37 +++++++++++++++++++++++++++++++++++++ 27 files changed, 92 insertions(+), 50 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 26 07:44:39 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Sun, 26 Feb 2017 07:44:39 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.8.0-86-g5b49095 Message-ID: This is an 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 5b49095b89b07591c69827df3973ffabfb3e97b8 (commit) from a7c6353edab57b67180aa127ec77d9353c2366fb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5b49095b89b07591c69827df3973ffabfb3e97b8 Author: Daniel Kahn Gillmor Date: Sat Feb 25 16:08:11 2017 -0500 doc: Correct documentation for recp arg of gpgme_op_encrypt_sign_start * doc/gpgme.texi (gpgme_op_encrypt_sign_start): recp is an array of gpgme_key_t, not a single element. Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 1e2cde7..d32a124 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -5609,7 +5609,7 @@ The combined encrypt and sign operation is currently only available for the OpenPGP crypto engine. @end deftypefun - at deftypefun gpgme_error_t gpgme_op_encrypt_sign_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{recp}}, @w{gpgme_encrypt_flags_t @var{flags}}, @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}}) + at deftypefun gpgme_error_t gpgme_op_encrypt_sign_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{recp}[]}, @w{gpgme_encrypt_flags_t @var{flags}}, @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}}) The function @code{gpgme_op_encrypt_sign_start} initiates a @code{gpgme_op_encrypt_sign} operation. It can be completed by calling @code{gpgme_wait} on the context. @xref{Waiting For ----------------------------------------------------------------------- Summary of changes: doc/gpgme.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 26 10:33:59 2017 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Sun, 26 Feb 2017 10:33:59 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-141-gf5782e1 Message-ID: This is an 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 f5782e11a560fd590221042391254c810a42e45f (commit) via ddf01a67d6388d988f1db50a06facb21c14d9426 (commit) via 64ec21bebd3f136722e608649906b59c6add6947 (commit) from 55b6c2595a97346895ed42bcc8b72151792f5bd8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f5782e11a560fd590221042391254c810a42e45f Author: Daniel Kahn Gillmor Date: Sat Feb 25 22:54:47 2017 -0800 dirmngr: Avoid warnings during non-ntbtls build. * dirmngr/t-http.c (my_http_tls_verify_cb): Avoid warnings when not using ntbtls. -- Without this patch, when building without ntbtls, we see the following warnings during "make check": t-http.c: In function ?my_http_tls_verify_cb?: t-http.c:141:16: warning: implicit declaration of function ?ntbtls_x509_get_peer_cert? [-Wimplicit-function-declaration] (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++) ^~~~~~~~~~~~~~~~~~~~~~~~~ t-http.c:141:14: warning: assignment makes pointer from integer without a cast -Wint-conversion] (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++) ^ At top level: t-http.c:123:1: warning: ?my_http_tls_verify_cb? defined but not used [-Wunused-function] my_http_tls_verify_cb (void *opaque, ^~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Daniel Kahn Gillmor diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 68818de..35f5947 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -118,7 +118,7 @@ my_gnutls_log (int level, const char *text) } #endif - +#if HTTP_USE_NTBTLS static gpg_error_t my_http_tls_verify_cb (void *opaque, http_t http, @@ -165,6 +165,7 @@ my_http_tls_verify_cb (void *opaque, log_info ("my_http_tls_verify_cb returns: %s\n", gpg_strerror (err)); return err; } +#endif /*HTTP_USE_NTBTLS*/ commit ddf01a67d6388d988f1db50a06facb21c14d9426 Author: Daniel Kahn Gillmor Date: Sat Feb 25 18:02:27 2017 -0500 trustdb: Respect --quiet during --import-ownertrust. * g10/tdbdump.c (import_ownertrust): If opt.quiet is set, do not send log_info messages. Signed-off-by: Daniel Kahn Gillmor diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 41a0258..be9d1f2 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -193,18 +193,22 @@ import_ownertrust( const char *fname ) if( !rc ) { /* found: update */ if (rec.r.trust.ownertrust != otrust) { - if( rec.r.trust.ownertrust ) - log_info("changing ownertrust from %u to %u\n", - rec.r.trust.ownertrust, otrust ); - else - log_info("setting ownertrust to %u\n", otrust ); + if (!opt.quiet) + { + if( rec.r.trust.ownertrust ) + log_info("changing ownertrust from %u to %u\n", + rec.r.trust.ownertrust, otrust ); + else + log_info("setting ownertrust to %u\n", otrust ); + } rec.r.trust.ownertrust = otrust; write_record (&rec ); any = 1; } } else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) { /* insert */ - log_info("inserting ownertrust of %u\n", otrust ); + if (!opt.quiet) + log_info("inserting ownertrust of %u\n", otrust ); memset (&rec, 0, sizeof rec); rec.recnum = tdbio_new_recnum (); rec.rectype = RECTYPE_TRUST; commit 64ec21bebd3f136722e608649906b59c6add6947 Author: Manish Goregaokar Date: Fri Feb 24 22:05:15 2017 -0800 g10: fix typo I already have copyright assignment with the FSF for GDB. I don't think I'll need to do the DCO thing. Signed-off-by: Manish Goregaokar diff --git a/g10/keygen.c b/g10/keygen.c index 844d38d..226cabd 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -5149,7 +5149,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock, node = find_kbnode (pub_keyblock, PKT_PUBLIC_KEY); if (!node) { - log_error ("Oops; publkic key lost!\n"); + log_error ("Oops; public key lost!\n"); err = gpg_error (GPG_ERR_INTERNAL); goto leave; } ----------------------------------------------------------------------- Summary of changes: dirmngr/t-http.c | 3 ++- g10/keygen.c | 2 +- g10/tdbdump.c | 16 ++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 27 00:29:32 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 27 Feb 2017 00:29:32 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-16-g84aaa84 Message-ID: This is an 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 84aaa84d41f17d6f5e2bb31930e101568df554e2 (commit) via a52f12cc1879d171ddf309b5ac461bab06c8b5e2 (commit) via be49b02a56e8b405eeb0c07c80eb24e71e841b4a (commit) via 915e1bf2ad1b23239b17843755376344e59a3110 (commit) from c9e44c92e08187626e878d826cdedf4cd4e931fe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 84aaa84d41f17d6f5e2bb31930e101568df554e2 Author: Werner Koch Date: Mon Feb 27 00:26:06 2017 +0100 Use the new tracing ramework for estream. * src/estream.c: Add trace calls to some functions. * src/w32-estream.c: Replace existing trace calls by the new framework. -- Signed-off-by: Werner Koch diff --git a/src/estream.c b/src/estream.c index f3d2269..c6c9a52 100644 --- a/src/estream.c +++ b/src/estream.c @@ -1,6 +1,6 @@ /* estream.c - Extended Stream I/O Library * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011, - * 2014, 2015, 2016 g10 Code GmbH + * 2014, 2015, 2016, 2017 g10 Code GmbH * * This file is part of Libestream. * @@ -92,12 +92,15 @@ # include #endif +/* Enable tracing. The value is the module name to be printed. */ +/*#define ENABLE_TRACING "estream"*/ #include "gpgrt-int.h" #include "estream-printf.h" #include "thread.h" #include "lock.h" + #ifndef O_BINARY # define O_BINARY 0 #endif @@ -910,6 +913,8 @@ func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) estream_cookie_fd_t fd_cookie; int err; + trace (("enter: fd=%d mf=%u nc=%d", fd, modeflags, no_close)); + fd_cookie = mem_alloc (sizeof (*fd_cookie)); if (! fd_cookie) err = -1; @@ -927,6 +932,7 @@ func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) err = 0; } + trace_errno (("leave: cookie=%p err=%d", *cookie, err)); return err; } @@ -941,6 +947,8 @@ func_fd_read (void *cookie, void *buffer, size_t size) estream_cookie_fd_t file_cookie = cookie; gpgrt_ssize_t bytes_read; + trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size)); + if (!size) bytes_read = -1; /* We don't know whether anything is pending. */ else if (IS_INVALID_FD (file_cookie->fd)) @@ -961,6 +969,7 @@ func_fd_read (void *cookie, void *buffer, size_t size) post_syscall_func (); } + trace_errno (("leave: bytes_read=%d", (int)bytes_read)); return bytes_read; } @@ -974,6 +983,8 @@ func_fd_write (void *cookie, const void *buffer, size_t size) estream_cookie_fd_t file_cookie = cookie; gpgrt_ssize_t bytes_written; + trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size)); + if (IS_INVALID_FD (file_cookie->fd)) { _gpgrt_yield (); @@ -994,6 +1005,7 @@ func_fd_write (void *cookie, const void *buffer, size_t size) else bytes_written = size; /* Note that for a flush SIZE should be 0. */ + trace_errno (("leave: bytes_written=%d", (int)bytes_written)); return bytes_written; } @@ -1085,6 +1097,8 @@ func_fd_destroy (void *cookie) estream_cookie_fd_t fd_cookie = cookie; int err; + trace (("enter: cookie=%p", cookie)); + if (fd_cookie) { if (IS_INVALID_FD (fd_cookie->fd)) @@ -1096,6 +1110,7 @@ func_fd_destroy (void *cookie) else err = 0; + trace_errno (("leave: err=%d", err)); return err; } @@ -1141,6 +1156,8 @@ func_w32_create (void **cookie, HANDLE hd, estream_cookie_w32_t w32_cookie; int err; + trace (("enter: hd=%p mf=%u nc=%d nsc=%d", + hd, modeflags, no_close, no_syscall_clamp)); w32_cookie = mem_alloc (sizeof (*w32_cookie)); if (!w32_cookie) err = -1; @@ -1158,6 +1175,7 @@ func_w32_create (void **cookie, HANDLE hd, err = 0; } + trace_errno (("leave: cookie=%p err=%d", *cookie, err)); return err; } @@ -1173,6 +1191,8 @@ func_w32_read (void *cookie, void *buffer, size_t size) estream_cookie_w32_t w32_cookie = cookie; gpgrt_ssize_t bytes_read; + trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size)); + if (!size) bytes_read = -1; /* We don't know whether anything is pending. */ else if (w32_cookie->hd == INVALID_HANDLE_VALUE) @@ -1207,6 +1227,7 @@ func_w32_read (void *cookie, void *buffer, size_t size) post_syscall_func (); } + trace_errno (("leave: bytes_read=%d", (int)bytes_read)); return bytes_read; } @@ -1223,6 +1244,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size) estream_cookie_w32_t w32_cookie = cookie; gpgrt_ssize_t bytes_written; + trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size)); + if (w32_cookie->hd == INVALID_HANDLE_VALUE) { _gpgrt_yield (); @@ -1251,6 +1274,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size) else bytes_written = size; /* Note that for a flush SIZE should be 0. */ + trace_errno (("leave: bytes_written=%d", (int)bytes_written)); + return bytes_written; } @@ -1321,6 +1346,8 @@ func_w32_destroy (void *cookie) estream_cookie_w32_t w32_cookie = cookie; int err; + trace (("enter: cookie=%p", cookie)); + if (w32_cookie) { if (w32_cookie->hd == INVALID_HANDLE_VALUE) @@ -1342,6 +1369,7 @@ func_w32_destroy (void *cookie) else err = 0; + trace_errno (("leave: err=%d", err)); return err; } @@ -2164,6 +2192,8 @@ do_close (estream_t stream, int with_locked_list) { int err; + trace (("stream %p %s", stream, with_locked_list? "(with locked list)":"")); + if (stream) { do_list_remove (stream, with_locked_list); @@ -2185,6 +2215,7 @@ do_close (estream_t stream, int with_locked_list) else err = 0; + trace_errno (("stream %p err=%d", stream, err)); return err; } @@ -4734,18 +4765,21 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) { gpgrt_poll_t *item; int count = 0; -#ifndef _WIN32 + int idx; +#ifndef HAVE_W32_SYSTEM fd_set readfds, writefds, exceptfds; int any_readfd, any_writefd, any_exceptfd; int max_fd; int fd, ret, any; -#endif - int idx; +#endif /*HAVE_W32_SYSTEM*/ + + trace (("enter: nfds=%u timeout=%d", nfds, timeout)); if (!fds) { _set_errno (EINVAL); - return -1; + count = -1; + goto leave; } /* Clear all response fields (even for ignored items). */ @@ -4785,7 +4819,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) } if (count) - return count; /* Early return without waiting. */ + goto leave; /* Early return without waiting. */ /* Now do the real select. */ #ifdef HAVE_W32_SYSTEM @@ -4864,10 +4898,18 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) post_syscall_func (); if (ret == -1) - return -1; + { + trace_errno (("select failed: ")); + count = -1; + goto leave; + } if (!ret) - return 0; /* Timeout. Note that in this case we can't return - got_err for an invalid stream. */ + { + /* Timeout. Note that in this case we can't return got_err for + * an invalid stream. */ + count = 0; + goto leave; + } for (item = fds, idx = 0; idx < nfds; item++, idx++) { @@ -4908,6 +4950,31 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) } #endif /*!HAVE_W32_SYSTEM*/ + leave: +#ifdef ENABLE_TRACING + trace (("leave: count=%d", count)); + if (count > 0) + { + for (item = fds, idx = 0; idx < nfds; item++, idx++) + { + trace ((" %3d %c%c%c%c%c %c%c%c%c%c%c%c", + idx, + fds[idx].want_read? 'r':'-', + fds[idx].want_write? 'w':'-', + fds[idx].want_oob? 'o':'-', + fds[idx].want_rdhup? 'h':'-', + fds[idx].ignore? 'i':'-', + fds[idx].got_read? 'r':'-', + fds[idx].got_write? 'w':'-', + fds[idx].got_oob? 'o':'-', + fds[idx].got_rdhup? 'h':'-', + fds[idx].got_hup? 'H':'-', + fds[idx].got_err? 'e':'-', + fds[idx].got_nval? 'n':'-' + )); + } + } +#endif /*ENABLE_TRACING*/ return count; } diff --git a/src/w32-estream.c b/src/w32-estream.c index 1603d30..722cb69 100644 --- a/src/w32-estream.c +++ b/src/w32-estream.c @@ -40,6 +40,9 @@ #include #include +/* Enable tracing. The value is the module name to be printed. */ +/*#define ENABLE_TRACING "estream" */ + #include "gpgrt-int.h" /* @@ -48,33 +51,6 @@ * writer threads that use the original I/O functions. */ - - -/* Tracing/debugging support. */ -#if 0 -#define TRACE(msg, ...) \ - fprintf (stderr, msg, ## __VA_ARGS__) -#define TRACE_CTX(ctx, msg, ...) \ - fprintf (stderr, "%p: " msg "\n", ctx, ## __VA_ARGS__) -#define TRACE_ERR(ctx, err, msg, ...) do { \ - char error_message[128]; \ - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM \ - | FORMAT_MESSAGE_IGNORE_INSERTS, \ - NULL, \ - err, \ - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \ - (LPTSTR) &error_message, \ - sizeof error_message, NULL ); \ - fprintf (stderr, "%p: " msg ": %d (%s)\n", ctx, \ - ## __VA_ARGS__, (int)(err), error_message); \ - } while (0) -#else -#define TRACE(msg, ...) (void) 0 -#define TRACE_CTX(ctx, msg, ...) (void) 0 -#define TRACE_ERR(ctx, err, msg, ...) (void) 0 -#endif - - /* Calculate array dimension. */ #ifndef DIM @@ -157,7 +133,7 @@ set_synchronize (HANDLE hd) GetCurrentProcess (), &new_hd, EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) { - TRACE_ERR (NULL, GetLastError (), "DuplicateHandle failed"); + trace_errno (("DuplicateHandle failed: ec=%d", (int)GetLastError ())); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return INVALID_HANDLE_VALUE; @@ -175,7 +151,8 @@ reader (void *arg) struct reader_context_s *ctx = arg; int nbytes; ssize_t nread; - TRACE_CTX (ctx, "reader starting"); + + trace (("%p: reader starting", ctx)); for (;;) { @@ -186,11 +163,11 @@ reader (void *arg) { /* Wait for space. */ if (!ResetEvent (ctx->have_space_ev)) - TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); + trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError())); LeaveCriticalSection (&ctx->mutex); - TRACE_CTX (ctx, "waiting for space"); + trace (("%p: waiting for space", ctx)); WaitForSingleObject (ctx->have_space_ev, INFINITE); - TRACE_CTX (ctx, "got space"); + trace (("%p: got space", ctx)); EnterCriticalSection (&ctx->mutex); } assert (((ctx->writepos + 1) % READBUF_SIZE != ctx->readpos)); @@ -206,11 +183,11 @@ reader (void *arg) nbytes = READBUF_SIZE - ctx->writepos; LeaveCriticalSection (&ctx->mutex); - TRACE_CTX (ctx, "reading up to %d bytes", nbytes); + trace (("%p: reading up to %d bytes", ctx, nbytes)); nread = ctx->pcookie->next_functions.public.func_read (ctx->pcookie->next_cookie, ctx->buffer + ctx->writepos, nbytes); - TRACE_CTX (ctx, "got %d bytes", nread); + trace (("%p: got %d bytes", ctx, nread)); if (nread < 0) { ctx->error_code = (int) errno; @@ -219,12 +196,12 @@ reader (void *arg) if (ctx->error_code == ERROR_BROKEN_PIPE) { ctx->eof = 1; - TRACE_CTX (ctx, "got EOF (broken pipe)"); + trace (("%p: got EOF (broken pipe)", ctx)); } else { ctx->error = 1; - TRACE_ERR (ctx, ctx->error_code, "read error"); + trace (("%p: read error: ec=%d", ctx, ctx->error_code)); } break; } @@ -238,23 +215,23 @@ reader (void *arg) if (!nread) { ctx->eof = 1; - TRACE_CTX (ctx, "got eof"); + trace (("%p: got eof", ctx)); LeaveCriticalSection (&ctx->mutex); break; } ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE; if (!SetEvent (ctx->have_data_ev)) - TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed", - ctx->have_data_ev); + trace (("%p: SetEvent (%p) failed: ec=%d", + ctx, ctx->have_data_ev, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); } /* Indicate that we have an error or EOF. */ if (!SetEvent (ctx->have_data_ev)) - TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed", - ctx->have_data_ev); + trace (("%p: SetEvent (%p) failed: ec=%d", + ctx, ctx->have_data_ev, (int)GetLastError ())); - TRACE_CTX (ctx, "waiting for close"); + trace (("%p: waiting for close", ctx)); WaitForSingleObject (ctx->close_ev, INFINITE); CloseHandle (ctx->close_ev); @@ -294,7 +271,7 @@ create_reader (estream_cookie_w32_pollable_t pcookie) ctx->close_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL); if (!ctx->have_data_ev || !ctx->have_space_ev || !ctx->close_ev) { - TRACE_ERR (ctx, GetLastError (), "CreateEvent failed"); + trace (("%p: CreateEvent failed: ec=%d", ctx, (int)GetLastError ())); if (ctx->have_data_ev) CloseHandle (ctx->have_data_ev); if (ctx->have_space_ev) @@ -317,7 +294,7 @@ create_reader (estream_cookie_w32_pollable_t pcookie) if (!ctx->thread_hd) { - TRACE_ERR (ctx, GetLastError (), "CreateThread failed"); + trace (("%p: CreateThread failed: ec=%d", ctx, (int)GetLastError ())); DeleteCriticalSection (&ctx->mutex); if (ctx->have_data_ev) CloseHandle (ctx->have_data_ev); @@ -364,7 +341,8 @@ destroy_reader (struct reader_context_s *ctx) if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK, NULL, 0, NULL, 0, NULL, NULL)) { - TRACE_ERR (ctx, GetLastError (), "unblock control call failed"); + trace (("%p: unblock control call failed: ec=%d", + ctx, (int)GetLastError ())); } } #endif @@ -397,13 +375,13 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) } } - TRACE_CTX (ctx, "pollable read buffer=%p, count=%u", buffer, count); + trace (("%p: read buffer=%p, count=%u", ctx, buffer, count)); if (ctx->eof_shortcut) return 0; EnterCriticalSection (&ctx->mutex); - TRACE_CTX (ctx, "readpos: %d, writepos %d", ctx->readpos, ctx->writepos); + trace (("%p: readpos: %d, writepos %d", ctx, ctx->readpos, ctx->writepos)); if (ctx->readpos == ctx->writepos && !ctx->error) { /* No data available. */ @@ -417,9 +395,9 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) return -1; } - TRACE_CTX (ctx, "waiting for data"); + trace (("%p: waiting for data", ctx)); WaitForSingleObject (ctx->have_data_ev, INFINITE); - TRACE_CTX (ctx, "data available"); + trace (("%p: data available", ctx)); EnterCriticalSection (&ctx->mutex); } @@ -431,8 +409,8 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) return 0; if (!ctx->error) { - TRACE_CTX (ctx, "EOF but ctx->eof flag not set"); - return 0; + trace (("%p: EOF but ctx->eof flag not set", ctx)); + return 0; } _gpg_err_set_errno (ctx->error_code); return -1; @@ -449,7 +427,7 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) { if (!ResetEvent (ctx->have_data_ev)) { - TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); + trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); @@ -458,8 +436,8 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) } if (!SetEvent (ctx->have_space_ev)) { - TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed", - ctx->have_space_ev); + trace (("%p: SetEvent (%p) failed: ec=%d", + ctx, ctx->have_space_ev, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); @@ -480,7 +458,7 @@ writer (void *arg) struct writer_context_s *ctx = arg; ssize_t nwritten; - TRACE_CTX (ctx, "writer starting"); + trace (("%p: writer starting", ctx)); for (;;) { @@ -493,13 +471,13 @@ writer (void *arg) if (!ctx->nbytes) { if (!SetEvent (ctx->is_empty)) - TRACE_ERR (ctx, GetLastError (), "SetEvent failed"); + trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ())); if (!ResetEvent (ctx->have_data)) - TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); + trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); - TRACE_CTX (ctx, "idle"); + trace (("%p: idle", ctx)); WaitForSingleObject (ctx->have_data, INFINITE); - TRACE_CTX (ctx, "got data to write"); + trace (("%p: got data to write", ctx)); EnterCriticalSection (&ctx->mutex); } if (ctx->stop_me && !ctx->nbytes) @@ -509,24 +487,24 @@ writer (void *arg) } LeaveCriticalSection (&ctx->mutex); - TRACE_CTX (ctx, "writing up to %d bytes", ctx->nbytes); + trace (("%p: writing up to %d bytes", ctx, ctx->nbytes)); nwritten = ctx->pcookie->next_functions.public.func_write (ctx->pcookie->next_cookie, ctx->buffer, ctx->nbytes); - TRACE_CTX (ctx, "wrote %d bytes", nwritten); + trace (("%p: wrote %d bytes", ctx, nwritten)); if (nwritten < 1) { /* XXX */ if (errno == ERROR_BUSY) { /* Probably stop_me is set now. */ - TRACE_CTX (ctx, "pipe busy (unblocked?)"); + trace (("%p: pipe busy (unblocked?)", ctx)); continue; } ctx->error_code = errno; ctx->error = 1; - TRACE_ERR (ctx, ctx->error_code, "write error"); + trace (("%p: write error: ec=%d", ctx, ctx->error_code)); break; } @@ -536,19 +514,20 @@ writer (void *arg) } /* Indicate that we have an error. */ if (!SetEvent (ctx->is_empty)) - TRACE_ERR (ctx, GetLastError (), "SetEvent failed"); + trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ())); - TRACE_CTX (ctx, "waiting for close"); + trace (("%p: waiting for close", ctx)); WaitForSingleObject (ctx->close_ev, INFINITE); if (ctx->nbytes) - TRACE_CTX (ctx, "still %d bytes in buffer at close time", ctx->nbytes); + trace (("%p: still %d bytes in buffer at close time", ctx, ctx->nbytes)); CloseHandle (ctx->close_ev); CloseHandle (ctx->have_data); CloseHandle (ctx->is_empty); CloseHandle (ctx->thread_hd); DeleteCriticalSection (&ctx->mutex); + trace (("%p: writer is destroyed", ctx)); _gpgrt_free (ctx); return 0; @@ -581,7 +560,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie) ctx->close_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL); if (!ctx->have_data || !ctx->is_empty || !ctx->close_ev) { - TRACE_ERR (ctx, GetLastError (), "CreateEvent failed"); + trace (("%p: CreateEvent failed: ec=%d", ctx, (int)GetLastError ())); if (ctx->have_data) CloseHandle (ctx->have_data); if (ctx->is_empty) @@ -604,7 +583,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie) if (!ctx->thread_hd) { - TRACE_ERR (ctx, GetLastError (), "CreateThread failed"); + trace (("%p: CreateThread failed: ec=%d", ctx, (int)GetLastError ())); DeleteCriticalSection (&ctx->mutex); if (ctx->have_data) CloseHandle (ctx->have_data); @@ -632,12 +611,16 @@ create_writer (estream_cookie_w32_pollable_t pcookie) static void destroy_writer (struct writer_context_s *ctx) { + trace (("%p: enter pollable_destroy_writer", ctx)); EnterCriticalSection (&ctx->mutex); + trace (("%p: setting stopme", ctx)); ctx->stop_me = 1; if (ctx->have_data) SetEvent (ctx->have_data); LeaveCriticalSection (&ctx->mutex); + trace (("%p: waiting for empty", ctx)); + /* Give the writer a chance to flush the buffer. */ WaitForSingleObject (ctx->is_empty, INFINITE); @@ -650,12 +633,15 @@ destroy_writer (struct writer_context_s *ctx) if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK, NULL, 0, NULL, 0, NULL, NULL)) { - TRACE_ERR (ctx, GetLastError (), "unblock control call failed"); + trace (("%p: unblock control call failed: ec=%d", + ctx, (int)GetLastError ())); } #endif /* After setting this event CTX is void. */ + trace (("%p: set close_ev", ctx)); SetEvent (ctx->close_ev); + trace (("%p: leave pollable_destroy_writer", ctx)); } @@ -666,12 +652,12 @@ static gpgrt_ssize_t func_w32_pollable_write (void *cookie, const void *buffer, size_t count) { estream_cookie_w32_pollable_t pcookie = cookie; - struct writer_context_s *ctx; + struct writer_context_s *ctx = pcookie->writer; + trace (("%p: buffer: %p count: %d", ctx, buffer, count)); if (count == 0) return 0; - ctx = pcookie->writer; if (ctx == NULL) { pcookie->writer = ctx = create_writer (pcookie); @@ -680,8 +666,8 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) } EnterCriticalSection (&ctx->mutex); - TRACE_CTX (ctx, "pollable write buffer: %p, count: %d, nbytes: %d", - buffer, count, ctx->nbytes); + trace (("%p: buffer: %p, count: %d, nbytes: %d", + ctx, buffer, count, ctx->nbytes)); if (!ctx->error && ctx->nbytes) { /* Bytes are pending for send. */ @@ -689,7 +675,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) /* Reset the is_empty event. Better safe than sorry. */ if (!ResetEvent (ctx->is_empty)) { - TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); + trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); @@ -699,14 +685,14 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) if (pcookie->modeflags & O_NONBLOCK) { - TRACE_CTX (ctx, "would block"); + trace (("%p: would block", ctx)); _gpg_err_set_errno (EAGAIN); return -1; } - TRACE_CTX (ctx, "waiting for empty buffer"); + trace (("%p: waiting for empty buffer", ctx)); WaitForSingleObject (ctx->is_empty, INFINITE); - TRACE_CTX (ctx, "buffer is empty"); + trace (("%p: buffer is empty", ctx)); EnterCriticalSection (&ctx->mutex); } @@ -733,7 +719,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) used by the select() implementation to probe the channel. */ if (!ResetEvent (ctx->is_empty)) { - TRACE_ERR (ctx, GetLastError (), "ResetEvent failed"); + trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); @@ -741,13 +727,15 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) } if (!SetEvent (ctx->have_data)) { - TRACE_ERR (ctx, GetLastError (), "SetEvent failed"); + trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; } + trace (("%p: nwritten=%d", ctx, count)); LeaveCriticalSection (&ctx->mutex); + trace (("%p: pollable write buffer - leave", ctx)); return (int) count; } @@ -768,7 +756,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) restart: #endif - TRACE ("poll on [ "); + trace_start (("poll on [ ")); any = 0; nwait = 0; count = 0; @@ -794,7 +782,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) if (fds[i].want_read) { struct reader_context_s *ctx = pcookie->reader; - TRACE ("%d/read ", i); + trace_append (("%d/read ", i)); if (ctx == NULL) { pcookie->reader = ctx = create_reader (pcookie); @@ -808,7 +796,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) if (nwait >= DIM (waitbuf)) { - TRACE ("oops ]: Too many objects for WFMO!\n"); + trace_finish (("oops ]: Too many objects for WFMO!")); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; @@ -820,12 +808,13 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) else if (fds[i].want_write) { struct writer_context_s *ctx = pcookie->writer; - TRACE ("%d/write ", i); + trace_append (("%d/write ", i)); if (ctx == NULL) { pcookie->writer = ctx = create_writer (pcookie); if (!ctx) { + trace_finish (("oops ]: create writer failed")); /* FIXME: Is the error code appropriate? */ _gpg_err_set_errno (EBADF); return -1; @@ -834,7 +823,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) if (nwait >= DIM (waitbuf)) { - TRACE ("oops ]: Too many objects for WFMO!"); + trace_finish (("oops ]: Too many objects for WFMO")); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; @@ -845,7 +834,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) } } } - TRACE ("]\n"); + trace_finish (("]")); if (!any) return 0; @@ -878,22 +867,22 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) } if (!any) { - TRACE ("no signaled objects found after WFMO\n"); + trace (("no signaled objects found after WFMO")); count = -1; } } else if (code == WAIT_TIMEOUT) - TRACE ("WFMO timed out\n"); + trace (("WFMO timed out")); else if (code == WAIT_FAILED) { - TRACE_ERR (NULL, GetLastError (), "WFMO failed"); + trace (("WFMO failed: ec=%d", (int)GetLastError ())); #if 0 if (GetLastError () == ERROR_INVALID_HANDLE) { int k; int j = handle_to_fd (waitbuf[i]); - TRACE ("WFMO invalid handle %d removed\n", j); + trace (("WFMO invalid handle %d removed", j)); for (k = 0 ; k < nfds; k++) { if (fds[k].fd == j) @@ -902,28 +891,28 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) goto restart; } } - TRACE (" oops, or not???\n"); + trace ((" oops, or not???")); } #endif count = -1; } else { - TRACE ("WFMO returned %u\n", code); + trace (("WFMO returned %u", code)); count = -1; } if (count > 0) { - TRACE ("poll OK [ "); + trace_start (("poll OK [ ")); for (i = 0; i < nfds; i++) { if (fds[i].ignore) continue; if (fds[i].got_read || fds[i].got_write) - TRACE ("%c%d ", fds[i].want_read ? 'r' : 'w', i); + trace_append (("%c%d ", fds[i].want_read ? 'r' : 'w', i)); } - TRACE ("]\n"); + trace_finish (("]")); } if (count < 0) commit a52f12cc1879d171ddf309b5ac461bab06c8b5e2 Author: Werner Koch Date: Mon Feb 27 00:22:26 2017 +0100 Add a tracing framework. * src/init.c (trace_save_errno, trace_arg_module) (trace_arg_file, trace_arg_line): New module vars. (do_internal_trace): New. (_gpgrt_internal_trace_printf): New. (_gpgrt_internal_trace): New. (_gpgrt_internal_trace_errno): New. (_gpgrt_internal_trace_end): New. * src/gpgrt-int.h (trace): New macro. (trace_errno): New macro. (trace_start): New macro. (trace_append): New macro. (trace_finish): New macro. -- We want to be abale to use libgpg-error also with pre-c99 compilers and thus we can use the __VA_ARGS__ but resort to the common macro trick. diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index 8a2dae7..e1cf50b 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -49,6 +49,50 @@ gpg_err_code_t _gpgrt_lock_unlock (gpgrt_lock_t *lockhd); gpg_err_code_t _gpgrt_lock_destroy (gpgrt_lock_t *lockhd); gpg_err_code_t _gpgrt_yield (void); +/* Trace support. */ + +void _gpgrt_internal_trace_begin (const char *mod, const char *file, int line); +void _gpgrt_internal_trace (const char *format, + ...) GPGRT_ATTR_PRINTF(1,2); +void _gpgrt_internal_trace_errno (const char *format, + ...) GPGRT_ATTR_PRINTF(1,2); +void _gpgrt_internal_trace_printf (const char *format, + ...) GPGRT_ATTR_PRINTF(1,2); +void _gpgrt_internal_trace_end (void); + +#ifdef ENABLE_TRACING +# define trace(X) do { \ + _gpgrt_internal_trace_begin \ + (ENABLE_TRACING, __func__, __LINE__); \ + _gpgrt_internal_trace X; \ + _gpgrt_internal_trace_end (); \ + } while (0) +# define trace_errno(X) do { \ + _gpgrt_internal_trace_begin \ + (ENABLE_TRACING, __func__, __LINE__); \ + _gpgrt_internal_trace_errno X; \ + _gpgrt_internal_trace_end (); \ + } while (0) +# define trace_start(X) do { \ + _gpgrt_internal_trace_begin \ + (ENABLE_TRACING, __func__, __LINE__); \ + _gpgrt_internal_trace_printf X; \ + } while (0) +# define trace_append(X) do { \ + _gpgrt_internal_trace_printf X; \ + } while (0) +# define trace_finish(X) do { \ + _gpgrt_internal_trace_printf X; \ + _gpgrt_internal_trace_end (); \ + } while (0) +#else +# define trace(X) do { } while (0) +# define trace_errno(X) do { } while (0) +# define trace_start(X) do { } while (0) +# define trace_append(X) do { } while (0) +# define trace_finish(X) do { } while (0) +#endif /*!ENABLE_TRACING*/ + /* Local definitions for estream. */ diff --git a/src/init.c b/src/init.c index f7207fe..e90bec5 100644 --- a/src/init.c +++ b/src/init.c @@ -214,6 +214,83 @@ _gpg_err_set_errno (int err) +/* Internal tracing functions. We use flockfile and funlockfile to + * protect their use. */ +static int trace_save_errno; +static const char *trace_arg_module; +static const char *trace_arg_file; +static int trace_arg_line; + +void +_gpgrt_internal_trace_begin (const char *module, const char *file, int line) +{ + int save_errno = errno; +#ifdef HAVE_FLOCKFILE + flockfile (stderr); +#endif + trace_save_errno = save_errno; + trace_arg_module = module; + trace_arg_file = file; + trace_arg_line = line; +} + + +static void +do_internal_trace (const char *format, va_list arg_ptr, int with_errno) +{ + fprintf (stderr, "%s:%s:%d: ", + trace_arg_module, trace_arg_file, trace_arg_line); + vfprintf (stderr, format, arg_ptr); + if (with_errno) + fprintf (stderr, " errno=%s", strerror (trace_save_errno)); + fputc ('\n', stderr); +} + +void +_gpgrt_internal_trace_printf (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format) ; + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + + +void +_gpgrt_internal_trace (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format) ; + do_internal_trace (format, arg_ptr, 0); + va_end (arg_ptr); +} + + +void +_gpgrt_internal_trace_errno (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format) ; + do_internal_trace (format, arg_ptr, 1); + va_end (arg_ptr); +} + + +void +_gpgrt_internal_trace_end (void) +{ + int save_errno = trace_save_errno; +#ifdef HAVE_FLOCKFILE + funlockfile (stderr); +#endif + errno = save_errno; +} + + + #ifdef HAVE_W32_SYSTEM /***************************************** ******** Below is only Windows code. **** commit be49b02a56e8b405eeb0c07c80eb24e71e841b4a Author: Werner Koch Date: Sun Feb 26 18:47:21 2017 +0100 Rename internal functions of estream. * src/estream.c (_gpgrt_es_init): Rename to _gpgrt_estream_init. (es_fill): Rename to fill_stream. (es_fflush): Rename to flush_stream. (es_deinitialize): Rename to deinit_stream_obj. (es_create): Rename to create_stream (es_read_nbf): Rename to do_read_nbf. (es_read_lbf): Rename to do_read_lbf. (es_read_fbf): Rename to do_read_fbf. (es_peek): Rename to peek_stream. (es_skip): Rename to skip_stream. (es_print): Rename to do_print_stream. -- The use of the "es_" was confusing. Avoid that. Signed-off-by: Werner Koch diff --git a/src/estream.c b/src/estream.c index db9de01..f3d2269 100644 --- a/src/estream.c +++ b/src/estream.c @@ -503,7 +503,7 @@ do_deinit (void) * Initialization of the estream module. */ int -_gpgrt_es_init (void) +_gpgrt_estream_init (void) { static int initialized; @@ -1825,7 +1825,7 @@ parse_mode (const char *modestr, */ static int -es_fill (estream_t stream) +fill_stream (estream_t stream) { size_t bytes_read = 0; int err; @@ -1880,7 +1880,7 @@ es_fill (estream_t stream) } static int -es_flush (estream_t stream) +flush_stream (estream_t stream) { gpgrt_cookie_write_function_t func_write = stream->intern->func_write; int err; @@ -2022,10 +2022,11 @@ init_stream_obj (estream_t stream, /* - * Deinitialize STREAM. + * Deinitialize the STREAM object. This does _not_ free the memory, + * destroys the lock, or closes the underlying descriptor. */ static int -es_deinitialize (estream_t stream) +deinit_stream_obj (estream_t stream) { gpgrt_cookie_close_function_t func_close; int err, tmp_err; @@ -2035,7 +2036,7 @@ es_deinitialize (estream_t stream) err = 0; if (stream->flags.writing) { - tmp_err = es_flush (stream); + tmp_err = flush_stream (stream); if (!err) err = tmp_err; } @@ -2061,13 +2062,15 @@ es_deinitialize (estream_t stream) /* - * Create a new stream object and initialize it. + * Create a new stream and initialize it. On success the new stream + * handle is tsored at R_STREAM. On failure NULL is stored at + * R_STREAM. */ static int -es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, - gpgrt_stream_backend_kind_t kind, - struct cookie_io_functions_s functions, unsigned int modeflags, - unsigned int xmode, int with_locked_list) +create_stream (estream_t *r_stream, void *cookie, es_syshd_t *syshd, + gpgrt_stream_backend_kind_t kind, + struct cookie_io_functions_s functions, unsigned int modeflags, + unsigned int xmode, int with_locked_list) { estream_internal_t stream_internal_new; estream_t stream_new; @@ -2134,7 +2137,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, if (err) goto out; - *stream = stream_new; + *r_stream = stream_new; out: @@ -2142,7 +2145,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, { if (stream_new) { - es_deinitialize (stream_new); + deinit_stream_obj (stream_new); destroy_stream_lock (stream_new); mem_free (stream_new->intern); mem_free (stream_new); @@ -2174,7 +2177,7 @@ do_close (estream_t stream, int with_locked_list) mem_free (stream->intern->onclose); stream->intern->onclose = tmp; } - err = es_deinitialize (stream); + err = deinit_stream_obj (stream); destroy_stream_lock (stream); mem_free (stream->intern); mem_free (stream); @@ -2221,7 +2224,7 @@ do_onclose (estream_t stream, int mode, * unbuffered-mode, storing the amount of bytes read at BYTES_READ. */ static int -es_read_nbf (estream_t _GPGRT__RESTRICT stream, +do_read_nbf (estream_t _GPGRT__RESTRICT stream, unsigned char *_GPGRT__RESTRICT buffer, size_t bytes_to_read, size_t *_GPGRT__RESTRICT bytes_read) { @@ -2280,7 +2283,7 @@ check_pending_nbf (estream_t _GPGRT__RESTRICT stream) * BYTES_READ. */ static int -es_read_fbf (estream_t _GPGRT__RESTRICT stream, +do_read_fbf (estream_t _GPGRT__RESTRICT stream, unsigned char *_GPGRT__RESTRICT buffer, size_t bytes_to_read, size_t *_GPGRT__RESTRICT bytes_read) { @@ -2298,7 +2301,7 @@ es_read_fbf (estream_t _GPGRT__RESTRICT stream, { /* Nothing more to read in current container, try to fill container with new data. */ - err = es_fill (stream); + err = fill_stream (stream); if (! err) if (! stream->data_len) /* Filling did not result in any data read. */ @@ -2354,13 +2357,13 @@ check_pending_fbf (estream_t _GPGRT__RESTRICT stream) * line-buffered-mode, storing the amount of bytes read at BYTES_READ. */ static int -es_read_lbf (estream_t _GPGRT__RESTRICT stream, +do_read_lbf (estream_t _GPGRT__RESTRICT stream, unsigned char *_GPGRT__RESTRICT buffer, size_t bytes_to_read, size_t *_GPGRT__RESTRICT bytes_read) { int err; - err = es_read_fbf (stream, buffer, bytes_to_read, bytes_read); + err = do_read_fbf (stream, buffer, bytes_to_read, bytes_read); return err; } @@ -2386,7 +2389,7 @@ es_readn (estream_t _GPGRT__RESTRICT stream, if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ - err = es_flush (stream); + err = flush_stream (stream); if (err) goto out; stream->flags.writing = 0; @@ -2404,17 +2407,17 @@ es_readn (estream_t _GPGRT__RESTRICT stream, switch (stream->intern->strategy) { case _IONBF: - err = es_read_nbf (stream, + err = do_read_nbf (stream, buffer + data_read_unread, bytes_to_read - data_read_unread, &data_read); break; case _IOLBF: - err = es_read_lbf (stream, + err = do_read_lbf (stream, buffer + data_read_unread, bytes_to_read - data_read_unread, &data_read); break; case _IOFBF: - err = es_read_fbf (stream, + err = do_read_fbf (stream, buffer + data_read_unread, bytes_to_read - data_read_unread, &data_read); break; @@ -2441,7 +2444,7 @@ check_pending (estream_t _GPGRT__RESTRICT stream) if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ - if (es_flush (stream)) + if (flush_stream (stream)) return 0; /* Better return 0 on error. */ stream->flags.writing = 0; } @@ -2515,7 +2518,7 @@ es_seek (estream_t _GPGRT__RESTRICT stream, gpgrt_off_t offset, int whence, { /* Flush data first in order to prevent flushing it to the wrong offset. */ - err = es_flush (stream); + err = flush_stream (stream); if (err) goto out; stream->flags.writing = 0; @@ -2635,7 +2638,7 @@ es_write_fbf (estream_t _GPGRT__RESTRICT stream, { if (stream->data_offset == stream->buffer_size) /* Container full, flush buffer. */ - err = es_flush (stream); + err = flush_stream (stream); if (! err) { @@ -2677,7 +2680,7 @@ es_write_lbf (estream_t _GPGRT__RESTRICT stream, { /* Found a newline, directly write up to (including) this character. */ - err = es_flush (stream); + err = flush_stream (stream); if (!err) err = es_write_nbf (stream, buffer, nlp - buffer + 1, &data_flushed); } @@ -2751,16 +2754,16 @@ es_writen (estream_t _GPGRT__RESTRICT stream, static int -es_peek (estream_t _GPGRT__RESTRICT stream, - unsigned char **_GPGRT__RESTRICT data, - size_t *_GPGRT__RESTRICT data_len) +peek_stream (estream_t _GPGRT__RESTRICT stream, + unsigned char **_GPGRT__RESTRICT data, + size_t *_GPGRT__RESTRICT data_len) { int err; if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ - err = es_flush (stream); + err = flush_stream (stream); if (err) goto out; stream->flags.writing = 0; @@ -2769,7 +2772,7 @@ es_peek (estream_t _GPGRT__RESTRICT stream, if (stream->data_offset == stream->data_len) { /* Refill container. */ - err = es_fill (stream); + err = fill_stream (stream); if (err) goto out; } @@ -2788,7 +2791,7 @@ es_peek (estream_t _GPGRT__RESTRICT stream, /* Skip SIZE bytes of input data contained in buffer. */ static int -es_skip (estream_t stream, size_t size) +skip_stream (estream_t stream, size_t size) { int err; @@ -2835,8 +2838,9 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length, goto out; memset (&syshd, 0, sizeof syshd); - err = es_create (&line_stream, line_stream_cookie, &syshd, BACKEND_MEM, - estream_functions_mem, O_RDWR, 1, 0); + err = create_stream (&line_stream, line_stream_cookie, + &syshd, BACKEND_MEM, + estream_functions_mem, O_RDWR, 1, 0); if (err) goto out; @@ -2849,7 +2853,7 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length, if (max_length && (space_left == 1)) break; - err = es_peek (stream, &data, &data_len); + err = peek_stream (stream, &data, &data_len); if (err || (! data_len)) break; @@ -2865,7 +2869,7 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length, { /* Not needed: space_left -= data_len */ line_size += data_len; - es_skip (stream, data_len); + skip_stream (stream, data_len); break; /* endless loop */ } } @@ -2876,7 +2880,7 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length, { space_left -= data_len; line_size += data_len; - es_skip (stream, data_len); + skip_stream (stream, data_len); } } if (err) @@ -2956,8 +2960,8 @@ print_writer (void *outfncarg, const char *buf, size_t buflen) /* The core of our printf function. This is called in locked state. */ static int -es_print (estream_t _GPGRT__RESTRICT stream, - const char *_GPGRT__RESTRICT format, va_list ap) +do_print_stream (estream_t _GPGRT__RESTRICT stream, + const char *_GPGRT__RESTRICT format, va_list ap) { int rc; @@ -2978,7 +2982,7 @@ es_set_buffering (estream_t _GPGRT__RESTRICT stream, /* Flush or empty buffer depending on mode. */ if (stream->flags.writing) { - err = es_flush (stream); + err = flush_stream (stream); if (err) goto out; } @@ -3086,8 +3090,8 @@ _gpgrt_fopen (const char *_GPGRT__RESTRICT path, syshd.type = ES_SYSHD_FD; syshd.u.fd = fd; create_called = 1; - err = es_create (&stream, cookie, &syshd, BACKEND_FD, - estream_functions_fd, modeflags, xmode, 0); + err = create_stream (&stream, cookie, &syshd, BACKEND_FD, + estream_functions_fd, modeflags, xmode, 0); if (err) goto out; @@ -3143,8 +3147,8 @@ _gpgrt_mopen (void *_GPGRT__RESTRICT data, size_t data_n, size_t data_len, memset (&syshd, 0, sizeof syshd); create_called = 1; - err = es_create (&stream, cookie, &syshd, BACKEND_MEM, - estream_functions_mem, modeflags, xmode, 0); + err = create_stream (&stream, cookie, &syshd, BACKEND_MEM, + estream_functions_mem, modeflags, xmode, 0); out: @@ -3177,8 +3181,8 @@ _gpgrt_fopenmem (size_t memlimit, const char *_GPGRT__RESTRICT mode) return NULL; memset (&syshd, 0, sizeof syshd); - if (es_create (&stream, cookie, &syshd, BACKEND_MEM, - estream_functions_mem, modeflags, xmode, 0)) + if (create_stream (&stream, cookie, &syshd, BACKEND_MEM, + estream_functions_mem, modeflags, xmode, 0)) (*estream_functions_mem.public.func_close) (cookie); return stream; @@ -3239,8 +3243,8 @@ _gpgrt_fopencookie (void *_GPGRT__RESTRICT cookie, goto out; memset (&syshd, 0, sizeof syshd); - err = es_create (&stream, cookie, &syshd, BACKEND_USER, io_functions, - modeflags, xmode, 0); + err = create_stream (&stream, cookie, &syshd, BACKEND_USER, io_functions, + modeflags, xmode, 0); if (err) goto out; @@ -3253,17 +3257,13 @@ _gpgrt_fopencookie (void *_GPGRT__RESTRICT cookie, static estream_t do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list) { + int create_called = 0; + estream_t stream = NULL; + void *cookie = NULL; unsigned int modeflags, xmode; - int create_called; - estream_t stream; - void *cookie; int err; es_syshd_t syshd; - stream = NULL; - cookie = NULL; - create_called = 0; - err = parse_mode (mode, &modeflags, &xmode, NULL); if (err) goto out; @@ -3282,8 +3282,9 @@ do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list) syshd.type = ES_SYSHD_FD; syshd.u.fd = filedes; create_called = 1; - err = es_create (&stream, cookie, &syshd, BACKEND_FD, estream_functions_fd, - modeflags, xmode, with_locked_list); + err = create_stream (&stream, cookie, &syshd, + BACKEND_FD, estream_functions_fd, + modeflags, xmode, with_locked_list); if (!err && stream) { @@ -3318,16 +3319,12 @@ static estream_t do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list) { unsigned int modeflags, cmode, xmode; - int create_called; - estream_t stream; - void *cookie; + int create_called = 0; + estream_t stream = NULL; + void *cookie = NULL; int err; es_syshd_t syshd; - stream = NULL; - cookie = NULL; - create_called = 0; - err = parse_mode (mode, &modeflags, &xmode, &cmode); if (err) goto out; @@ -3348,11 +3345,11 @@ do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list) syshd.type = ES_SYSHD_FD; syshd.u.fd = fp? fileno (fp): -1; create_called = 1; - err = es_create (&stream, cookie, &syshd, BACKEND_FP, estream_functions_fp, - modeflags, xmode, with_locked_list); + err = create_stream (&stream, cookie, &syshd, + BACKEND_FP, estream_functions_fp, + modeflags, xmode, with_locked_list); out: - if (err && create_called) (*estream_functions_fp.public.func_close) (cookie); @@ -3412,8 +3409,9 @@ do_w32open (HANDLE hd, const char *mode, syshd.type = ES_SYSHD_HANDLE; syshd.u.handle = hd; create_called = 1; - err = es_create (&stream, cookie, &syshd, BACKEND_W32, - estream_functions_w32, modeflags, xmode, with_locked_list); + err = create_stream (&stream, cookie, &syshd, + BACKEND_W32, estream_functions_w32, + modeflags, xmode, with_locked_list); leave: if (err && create_called) @@ -3554,7 +3552,9 @@ _gpgrt__get_std_stream (int fd) } /* Note: A "samethread" keyword given in "mode" is ignored and the - value used by STREAM is used instead. */ + * value used by STREAM is used instead. Note that this function is + * the reasons why some of the init and deinit code is split up into + * several functions. */ estream_t _gpgrt_freopen (const char *_GPGRT__RESTRICT path, const char *_GPGRT__RESTRICT mode, @@ -3577,7 +3577,7 @@ _gpgrt_freopen (const char *_GPGRT__RESTRICT path, lock_stream (stream); - es_deinitialize (stream); + deinit_stream_obj (stream); err = parse_mode (mode, &modeflags, &dummy, &cmode); if (err) @@ -3615,7 +3615,7 @@ _gpgrt_freopen (const char *_GPGRT__RESTRICT path, { /* FIXME? We don't support re-opening at the moment. */ _set_errno (EINVAL); - es_deinitialize (stream); + deinit_stream_obj (stream); do_close (stream, 0); stream = NULL; } @@ -3668,7 +3668,7 @@ _gpgrt_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen) if (stream->flags.writing) { - err = es_flush (stream); + err = flush_stream (stream); if (err) goto leave; stream->flags.writing = 0; @@ -3909,7 +3909,7 @@ do_fflush (estream_t stream) int err; if (stream->flags.writing) - err = es_flush (stream); + err = flush_stream (stream); else { es_empty (stream); @@ -4403,7 +4403,7 @@ _gpgrt_vfprintf_unlocked (estream_t _GPGRT__RESTRICT stream, const char *_GPGRT__RESTRICT format, va_list ap) { - return es_print (stream, format, ap); + return do_print_stream (stream, format, ap); } @@ -4415,7 +4415,7 @@ _gpgrt_vfprintf (estream_t _GPGRT__RESTRICT stream, int ret; lock_stream (stream); - ret = es_print (stream, format, ap); + ret = do_print_stream (stream, format, ap); unlock_stream (stream); return ret; @@ -4430,7 +4430,7 @@ _gpgrt_fprintf_unlocked (estream_t _GPGRT__RESTRICT stream, va_list ap; va_start (ap, format); - ret = es_print (stream, format, ap); + ret = do_print_stream (stream, format, ap); va_end (ap); return ret; @@ -4446,7 +4446,7 @@ _gpgrt_fprintf (estream_t _GPGRT__RESTRICT stream, va_list ap; va_start (ap, format); lock_stream (stream); - ret = es_print (stream, format, ap); + ret = do_print_stream (stream, format, ap); unlock_stream (stream); va_end (ap); @@ -4559,17 +4559,14 @@ estream_t _gpgrt_tmpfile (void) { unsigned int modeflags; - int create_called; - estream_t stream; - void *cookie; + int create_called = 0; + estream_t stream = NULL; + void *cookie = NULL; int err; int fd; es_syshd_t syshd; - create_called = 0; - stream = NULL; modeflags = O_RDWR | O_TRUNC | O_CREAT; - cookie = NULL; fd = tmpfd (); if (fd == -1) @@ -4585,8 +4582,9 @@ _gpgrt_tmpfile (void) syshd.type = ES_SYSHD_FD; syshd.u.fd = fd; create_called = 1; - err = es_create (&stream, cookie, &syshd, BACKEND_FD, estream_functions_fd, - modeflags, 0, 0); + err = create_stream (&stream, cookie, &syshd, + BACKEND_FD, estream_functions_fd, + modeflags, 0, 0); out: if (err) @@ -4790,7 +4788,8 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) return count; /* Early return without waiting. */ /* Now do the real select. */ -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM + if (pre_syscall_func) pre_syscall_func (); @@ -4798,7 +4797,9 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) if (post_syscall_func) post_syscall_func (); -#else + +#else /*!HAVE_W32_SYSTEM*/ + any_readfd = any_writefd = any_exceptfd = 0; max_fd = 0; for (item = fds, idx = 0; idx < nfds; item++, idx++) @@ -4905,7 +4906,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) if (any) count++; } -#endif +#endif /*!HAVE_W32_SYSTEM*/ return count; } diff --git a/src/estream.h b/src/estream.h index 91f2bc0..2f2b11e 100644 --- a/src/estream.h +++ b/src/estream.h @@ -23,7 +23,7 @@ #include "gpg-error.h" /* Local prototypes for estream. */ -int _gpgrt_es_init (void); +int _gpgrt_estream_init (void); diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index d624e84..8a2dae7 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -147,7 +147,7 @@ typedef struct _gpgrt_stream_internal *estream_internal_t; /* Local prototypes for estream. */ -int _gpgrt_es_init (void); +int _gpgrt_estream_init (void); void _gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void)); void _gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void)); diff --git a/src/init.c b/src/init.c index 8de54b6..f7207fe 100644 --- a/src/init.c +++ b/src/init.c @@ -80,7 +80,7 @@ real_init (void) drop_locale_dir (locale_dir); } #endif - _gpgrt_es_init (); + _gpgrt_estream_init (); } /* Initialize the library. This function should be run early. */ commit 915e1bf2ad1b23239b17843755376344e59a3110 Author: Werner Koch Date: Fri Feb 24 12:17:15 2017 +0100 w32: Do not use the syscall clamps in pollable mode. * src/estream.c (estream_cookie_w32): Add flag no_syscall_clamp. (func_w32_create): Add arg no_syscall_clamp. (func_w32_read): Do not call pre/post_syscall_clamp when flag is set. (func_w32_write): Ditto. (func_w32_seek): Ditto. (do_w32open): Set NO_SYSCALL_CLAMP in pollable mode. (es_create) [W32]: Make sure that pollable-mode is unly used with the W32 backend. Signed-off-by: Werner Koch diff --git a/src/estream.c b/src/estream.c index 045182b..db9de01 100644 --- a/src/estream.c +++ b/src/estream.c @@ -1127,6 +1127,7 @@ typedef struct estream_cookie_w32 { HANDLE hd; /* The handle we are using for actual output. */ int no_close; /* If set we won't close the handle. */ + int no_syscall_clamp; /* Do not use the syscall clamp. */ } *estream_cookie_w32_t; @@ -1135,7 +1136,7 @@ typedef struct estream_cookie_w32 */ static int func_w32_create (void **cookie, HANDLE hd, - unsigned int modeflags, int no_close) + unsigned int modeflags, int no_close, int no_syscall_clamp) { estream_cookie_w32_t w32_cookie; int err; @@ -1152,6 +1153,7 @@ func_w32_create (void **cookie, HANDLE hd, w32_cookie->hd = hd; w32_cookie->no_close = no_close; + w32_cookie->no_syscall_clamp = no_syscall_clamp; *cookie = w32_cookie; err = 0; } @@ -1161,6 +1163,9 @@ func_w32_create (void **cookie, HANDLE hd, /* * Read function for W32 handle objects. + * + * Note that this function may also be used by the reader thread of + * w32-stream. In that case the NO_SYSCALL_CLAMP is set. */ static gpgrt_ssize_t func_w32_read (void *cookie, void *buffer, size_t size) @@ -1177,7 +1182,7 @@ func_w32_read (void *cookie, void *buffer, size_t size) } else { - if (pre_syscall_func) + if (pre_syscall_func && !w32_cookie->no_syscall_clamp) pre_syscall_func (); do { @@ -1198,7 +1203,7 @@ func_w32_read (void *cookie, void *buffer, size_t size) bytes_read = (int)nread; } while (bytes_read == -1 && errno == EINTR); - if (post_syscall_func) + if (post_syscall_func && !w32_cookie->no_syscall_clamp) post_syscall_func (); } @@ -1208,6 +1213,9 @@ func_w32_read (void *cookie, void *buffer, size_t size) /* * Write function for W32 handle objects. + * + * Note that this function may also be used by the writer thread of + * w32-stream. In that case the NO_SYSCALL_CLAMP is set. */ static gpgrt_ssize_t func_w32_write (void *cookie, const void *buffer, size_t size) @@ -1222,7 +1230,7 @@ func_w32_write (void *cookie, const void *buffer, size_t size) } else if (buffer) { - if (pre_syscall_func) + if (pre_syscall_func && !w32_cookie->no_syscall_clamp) pre_syscall_func (); do { @@ -1237,7 +1245,7 @@ func_w32_write (void *cookie, const void *buffer, size_t size) bytes_written = (int)nwritten; } while (bytes_written == -1 && errno == EINTR); - if (post_syscall_func) + if (post_syscall_func && !w32_cookie->no_syscall_clamp) post_syscall_func (); } else @@ -1286,7 +1294,7 @@ func_w32_seek (void *cookie, gpgrt_off_t *offset, int whence) #ifdef HAVE_W32CE_SYSTEM # warning need to use SetFilePointer #else - if (pre_syscall_func) + if (pre_syscall_func && !w32_cookie->no_syscall_clamp) pre_syscall_func (); if (!SetFilePointerEx (w32_cookie->hd, distance, &newoff, method)) { @@ -1295,7 +1303,7 @@ func_w32_seek (void *cookie, gpgrt_off_t *offset, int whence) post_syscall_func (); return -1; } - if (post_syscall_func) + if (post_syscall_func && !w32_cookie->no_syscall_clamp) post_syscall_func (); #endif /* Note that gpgrt_off_t is always 64 bit. */ @@ -1661,6 +1669,7 @@ func_file_create (void **cookie, int *filedes, * The object is opened in sysmode. On POSIX this is a NOP but * under Windows the direct W32 API functions (HANDLE) are used * instead of their libc counterparts (fd). + * FIXME: The functionality is not yet implemented. * * pollable * @@ -2067,6 +2076,19 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, stream_new = NULL; stream_internal_new = NULL; +#if HAVE_W32_SYSTEM + if ((xmode & X_POLLABLE) && kind != BACKEND_W32) + { + /* We require the W32 backend, because only that allows us to + * write directly using the native W32 API and to disable the + * system clamp. Note that func_w32_create has already been + * called with the flag to disable the system call clamp. */ + _set_errno (EINVAL); + err = -1; + goto out; + } +#endif /*HAVE_W32_SYSTEM*/ + stream_new = mem_alloc (sizeof (*stream_new)); if (! stream_new) { @@ -2087,7 +2109,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, stream_new->unread_buffer_size = sizeof (stream_internal_new->unread_buffer); stream_new->intern = stream_internal_new; -#if _WIN32 +#if HAVE_W32_SYSTEM if ((xmode & X_POLLABLE)) { void *new_cookie; @@ -2102,7 +2124,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, kind = BACKEND_W32_POLLABLE; functions = _gpgrt_functions_w32_pollable; } -#endif +#endif /*HAVE_W32_SYSTEM*/ init_stream_obj (stream_new, cookie, syshd, kind, functions, modeflags, xmode); @@ -3379,7 +3401,11 @@ do_w32open (HANDLE hd, const char *mode, if (err) goto leave; - err = func_w32_create (&cookie, hd, modeflags, no_close); + /* If we are pollable we create the function cookie with syscall + * clamp disabled. This is because functions are called from + * separatre reader and writer threads in w32-stream. */ + err = func_w32_create (&cookie, hd, modeflags, + no_close, !!(xmode & X_POLLABLE)); if (err) goto leave; ----------------------------------------------------------------------- Summary of changes: src/estream.c | 312 +++++++++++++++++++++++++++++++++++------------------- src/estream.h | 2 +- src/gpgrt-int.h | 46 +++++++- src/init.c | 79 +++++++++++++- src/w32-estream.c | 177 +++++++++++++++---------------- 5 files changed, 410 insertions(+), 206 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 09:44:23 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 28 Feb 2017 09:44:23 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-143-g8a67dc4 Message-ID: This is an 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 8a67dc4c4324b617b5a3fea51c59c674488544d6 (commit) via 1192449207f41b26be8950b04df84a52c8a2a886 (commit) from f5782e11a560fd590221042391254c810a42e45f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8a67dc4c4324b617b5a3fea51c59c674488544d6 Author: Werner Koch Date: Tue Feb 28 09:35:41 2017 +0100 gpgv,w32: Fix --status-fd. * g10/gpgv.c (main): Use translate_sys2libc_fd_int for --status-fd. Signed-off-by: Werner Koch diff --git a/g10/gpgv.c b/g10/gpgv.c index ab6f530..ef8d9e0 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -225,7 +225,9 @@ main( int argc, char **argv ) break; case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oOutput: opt.outfile = pargs.r.ret_str; break; - case oStatusFD: set_status_fd( pargs.r.ret_int ); break; + case oStatusFD: + set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + break; case oLoggerFD: log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; commit 1192449207f41b26be8950b04df84a52c8a2a886 Author: Werner Koch Date: Tue Feb 28 09:34:29 2017 +0100 w32: Make pipes really pollable. * common/exectool.c (gnupg_exec_tool_stream) [W32]: Use _get_osfhandle to print the fd for the command line. * common/exechelp-w32.c (create_pipe_and_estream): Use es_sysopen so that the streams are actually pollable. -- This addresses two bugs: - Using the "-&@INEXTRA@" kludges requires that we pass the value of the handle on the command line and not the libc fd. - gpgrt_poll requires the use of the ReadFile/WriteFile backend which is currently only used when the stream has been created with gpgrt_sysopen. Signed-off-by: Werner Koch diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index e79ee5b..2c44e2c 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -309,6 +309,7 @@ create_pipe_and_estream (int filedes[2], int flags, { gpg_error_t err = 0; HANDLE fds[2]; + es_syshd_t syshd; filedes[0] = filedes[1] = -1; err = my_error (GPG_ERR_GENERAL); @@ -337,10 +338,17 @@ create_pipe_and_estream (int filedes[2], int flags, if (! err && r_fp) { + syshd.type = ES_SYSHD_HANDLE; if (!outbound) - *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r"); + { + syshd.u.handle = fds[0]; + *r_fp = es_sysopen (&syshd, nonblock? "r,nonblock" : "r"); + } else - *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w"); + { + syshd.u.handle = fds[1]; + *r_fp = es_sysopen (&syshd, nonblock? "w,nonblock" : "w"); + } if (!*r_fp) { err = my_error_from_syserror (); diff --git a/common/exectool.c b/common/exectool.c index ed8225a..c9e0020 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -384,7 +384,12 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], /* Now find the argument marker and replace by the pipe's fd. Yeah, that is an ugly non-thread safe hack but it safes us to create a copy of the array. */ +#ifdef HAVE_W32_SYSTEM + snprintf (extrafdbuf, sizeof extrafdbuf, "-&%lu", + (unsigned long)(void*)_get_osfhandle (extrapipe[0])); +#else snprintf (extrafdbuf, sizeof extrafdbuf, "-&%d", extrapipe[0]); +#endif for (argsaveidx=0; argv[argsaveidx]; argsaveidx++) if (!strcmp (argv[argsaveidx], "-&@INEXTRA@")) { ----------------------------------------------------------------------- Summary of changes: common/exechelp-w32.c | 12 ++++++++++-- common/exectool.c | 5 +++++ g10/gpgv.c | 4 +++- 3 files changed, 18 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 10:13:49 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 28 Feb 2017 10:13:49 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-19-gf141fde Message-ID: This is an 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 f141fdee4015d36aec2122853ef55f3ae42197da (commit) via f27e516aabd27afeddecfde197eae1fd21a11395 (commit) via 07d5bd918d2185f79c7d61d56ee7f3090b6f5dcd (commit) from 84aaa84d41f17d6f5e2bb31930e101568df554e2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f141fdee4015d36aec2122853ef55f3ae42197da Author: Werner Koch Date: Tue Feb 28 10:04:55 2017 +0100 tests: New option --debug for t-poll. * tests/t-poll.c (test_poll): Add option. Signed-off-by: Werner Koch diff --git a/doc/errorref.txt b/doc/errorref.txt index 4bc0ebb..284123b 100644 --- a/doc/errorref.txt +++ b/doc/errorref.txt @@ -201,6 +201,8 @@ GPG_ERR_TRUSTDB Trust DB error GPG_ERR_BAD_CERT Bad certificate + NTBTLS: - No subject found in the certifciate. + GPG_ERR_INV_USER_ID Invalid user ID diff --git a/tests/t-poll.c b/tests/t-poll.c index d39797a..ec79416 100644 --- a/tests/t-poll.c +++ b/tests/t-poll.c @@ -241,7 +241,57 @@ test_poll (void) fail ("gpgrt_poll unexpectedly timed out\n"); continue; } + show ("gpgrt_poll detected %d events\n", ret); + if (debug) + show ("gpgrt_poll: r=%d" + " 0:%c%c%c%c%c%c%c%c%c%c%c%c" + " 1:%c%c%c%c%c%c%c%c%c%c%c%c" + " 2:%c%c%c%c%c%c%c%c%c%c%c%c" + "\n", + ret, + fds[0].want_read? 'r':'-', + fds[0].want_write? 'w':'-', + fds[0].want_oob? 'o':'-', + fds[0].want_rdhup? 'h':'-', + fds[0].ignore? '!':'=', + fds[0].got_read? 'r':'-', + fds[0].got_write? 'w':'-', + fds[0].got_oob? 'o':'-', + fds[0].got_rdhup? 'h':'-', + fds[0].got_hup? 'H':' ', + fds[0].got_err? 'e':' ', + fds[0].got_nval? 'n':' ', + + fds[1].want_read? 'r':'-', + fds[1].want_write? 'w':'-', + fds[1].want_oob? 'o':'-', + fds[1].want_rdhup? 'h':'-', + fds[1].ignore? '!':'=', + fds[1].got_read? 'r':'-', + fds[1].got_write? 'w':'-', + fds[1].got_oob? 'o':'-', + fds[1].got_rdhup? 'h':'-', + fds[1].got_hup? 'H':' ', + fds[1].got_err? 'e':' ', + fds[1].got_nval? 'n':' ', + + fds[2].want_read? 'r':'-', + fds[2].want_write? 'w':'-', + fds[2].want_oob? 'o':'-', + fds[2].want_rdhup? 'h':'-', + fds[2].ignore? '!':'=', + fds[2].got_read? 'r':'-', + fds[2].got_write? 'w':'-', + fds[2].got_oob? 'o':'-', + fds[2].got_rdhup? 'h':'-', + fds[2].got_hup? 'H':' ', + fds[2].got_err? 'e':' ', + fds[2].got_nval? 'n':' ' + ); + else + show ("gpgrt_poll detected %d events\n", ret); + if (fds[0].got_read) { /* Read from the producer. */ commit f27e516aabd27afeddecfde197eae1fd21a11395 Author: Werner Koch Date: Tue Feb 28 10:05:49 2017 +0100 Improve tracing of estream. * src/gpgrt-int.h (trace_errno): Add new parameter. Adjust all users. * src/init.c (trace_fp, trace_with_errno, trace_missing_lf) (trace_prefix_done): New vars. (_gpgrt_internal_trace_begin): Add arg WITH_ERRNO. Open a trace file on first use. Init new vars. (print_internal_trace_prefix): New. * src/estream.c, src/w32-estream.c: Improve tracing. Signed-off-by: Werner Koch diff --git a/src/estream.c b/src/estream.c index ee3a7df..9f227a6 100644 --- a/src/estream.c +++ b/src/estream.c @@ -913,7 +913,7 @@ func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) estream_cookie_fd_t fd_cookie; int err; - trace (("enter: fd=%d mf=%u nc=%d", fd, modeflags, no_close)); + trace (("enter: fd=%d mf=%x nc=%d", fd, modeflags, no_close)); fd_cookie = mem_alloc (sizeof (*fd_cookie)); if (! fd_cookie) @@ -932,7 +932,7 @@ func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) err = 0; } - trace_errno (("leave: cookie=%p err=%d", *cookie, err)); + trace_errno (err, ("leave: cookie=%p err=%d", *cookie, err)); return err; } @@ -969,7 +969,7 @@ func_fd_read (void *cookie, void *buffer, size_t size) post_syscall_func (); } - trace_errno (("leave: bytes_read=%d", (int)bytes_read)); + trace_errno (bytes_read == -1, ("leave: bytes_read=%d", (int)bytes_read)); return bytes_read; } @@ -1005,7 +1005,8 @@ func_fd_write (void *cookie, const void *buffer, size_t size) else bytes_written = size; /* Note that for a flush SIZE should be 0. */ - trace_errno (("leave: bytes_written=%d", (int)bytes_written)); + trace_errno (bytes_written == -1, + ("leave: bytes_written=%d", (int)bytes_written)); return bytes_written; } @@ -1110,7 +1111,7 @@ func_fd_destroy (void *cookie) else err = 0; - trace_errno (("leave: err=%d", err)); + trace_errno (err,("leave: err=%d", err)); return err; } @@ -1156,7 +1157,7 @@ func_w32_create (void **cookie, HANDLE hd, estream_cookie_w32_t w32_cookie; int err; - trace (("enter: hd=%p mf=%u nc=%d nsc=%d", + trace (("enter: hd=%p mf=%x nc=%d nsc=%d", hd, modeflags, no_close, no_syscall_clamp)); w32_cookie = mem_alloc (sizeof (*w32_cookie)); if (!w32_cookie) @@ -1175,7 +1176,7 @@ func_w32_create (void **cookie, HANDLE hd, err = 0; } - trace_errno (("leave: cookie=%p err=%d", *cookie, err)); + trace_errno (err, ("leave: cookie=%p err=%d", *cookie, err)); return err; } @@ -1208,9 +1209,11 @@ func_w32_read (void *cookie, void *buffer, size_t size) { DWORD nread, ec; + trace (("cookie=%p calling ReadFile", cookie)); if (!ReadFile (w32_cookie->hd, buffer, size, &nread, NULL)) { ec = GetLastError (); + trace (("cookie=%p ReadFile failed: ec=%ld", cookie,ec)); if (ec == ERROR_BROKEN_PIPE) bytes_read = 0; /* Like our pth_read we handle this as EOF. */ else @@ -1227,7 +1230,7 @@ func_w32_read (void *cookie, void *buffer, size_t size) post_syscall_func (); } - trace_errno (("leave: bytes_read=%d", (int)bytes_read)); + trace_errno (bytes_read==-1,("leave: bytes_read=%d", (int)bytes_read)); return bytes_read; } @@ -1259,9 +1262,12 @@ func_w32_write (void *cookie, const void *buffer, size_t size) { DWORD nwritten; + trace (("cookie=%p calling WriteFile", cookie)); if (!WriteFile (w32_cookie->hd, buffer, size, &nwritten, NULL)) { - _set_errno (map_w32_to_errno (GetLastError ())); + DWORD ec = GetLastError (); + trace (("cookie=%p WriteFile failed: ec=%ld", cookie, ec)); + _set_errno (map_w32_to_errno (ec)); bytes_written = -1; } else @@ -1274,8 +1280,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size) else bytes_written = size; /* Note that for a flush SIZE should be 0. */ - trace_errno (("leave: bytes_written=%d", (int)bytes_written)); - + trace_errno (bytes_written==-1, + ("leave: bytes_written=%d", (int)bytes_written)); return bytes_written; } @@ -1356,9 +1362,12 @@ func_w32_destroy (void *cookie) err = 0; else { + trace (("cookie=%p closing handle %p", cookie, w32_cookie->hd)); if (!CloseHandle (w32_cookie->hd)) { - _set_errno (map_w32_to_errno (GetLastError ())); + DWORD ec = GetLastError (); + trace (("cookie=%p CloseHandle failed: ec=%ld", cookie,ec)); + _set_errno (map_w32_to_errno (ec)); err = -1; } else @@ -1369,7 +1378,7 @@ func_w32_destroy (void *cookie) else err = 0; - trace_errno (("leave: err=%d", err)); + trace_errno (err, ("leave: err=%d", err)); return err; } @@ -2059,6 +2068,7 @@ deinit_stream_obj (estream_t stream) gpgrt_cookie_close_function_t func_close; int err, tmp_err; + trace (("enter: stream %p", stream)); func_close = stream->intern->func_close; err = 0; @@ -2070,6 +2080,7 @@ deinit_stream_obj (estream_t stream) } if (func_close) { + trace (("stream %p calling func_close", stream)); tmp_err = func_close (stream->intern->cookie); if (!err) err = tmp_err; @@ -2085,6 +2096,7 @@ deinit_stream_obj (estream_t stream) stream->intern->onclose = tmp; } + trace_errno (err, ("leave: stream %p err=%d", stream, err)); return err; } @@ -2103,6 +2115,9 @@ create_stream (estream_t *r_stream, void *cookie, es_syshd_t *syshd, estream_internal_t stream_internal_new; estream_t stream_new; int err; +#if HAVE_W32_SYSTEM + void *old_cookie = NULL; +#endif stream_new = NULL; stream_internal_new = NULL; @@ -2151,6 +2166,7 @@ create_stream (estream_t *r_stream, void *cookie, es_syshd_t *syshd, goto out; modeflags &= ~O_NONBLOCK; + old_cookie = cookie; cookie = new_cookie; kind = BACKEND_W32_POLLABLE; functions = _gpgrt_functions_w32_pollable; @@ -2171,6 +2187,7 @@ create_stream (estream_t *r_stream, void *cookie, es_syshd_t *syshd, if (err) { + trace_errno (err, ("leave: err=%d", err)); if (stream_new) { deinit_stream_obj (stream_new); @@ -2179,6 +2196,13 @@ create_stream (estream_t *r_stream, void *cookie, es_syshd_t *syshd, mem_free (stream_new); } } +#if HAVE_W32_SYSTEM + else if (old_cookie) + trace (("leave: success stream=%p cookie=%p,%p", + *r_stream, old_cookie, cookie)); +#endif + else + trace (("leave: success stream=%p cookie=%p", *r_stream, cookie)); return err; } @@ -2215,7 +2239,7 @@ do_close (estream_t stream, int with_locked_list) else err = 0; - trace_errno (("stream %p err=%d", stream, err)); + trace_errno (err, ("stream %p err=%d", stream, err)); return err; } @@ -4893,7 +4917,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) if (ret == -1) { - trace_errno (("select failed: ")); + trace_errno (1, ("select failed: ")); count = -1; goto leave; } diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index e1cf50b..701e1d4 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -51,31 +51,33 @@ gpg_err_code_t _gpgrt_yield (void); /* Trace support. */ -void _gpgrt_internal_trace_begin (const char *mod, const char *file, int line); -void _gpgrt_internal_trace (const char *format, - ...) GPGRT_ATTR_PRINTF(1,2); -void _gpgrt_internal_trace_errno (const char *format, - ...) GPGRT_ATTR_PRINTF(1,2); -void _gpgrt_internal_trace_printf (const char *format, - ...) GPGRT_ATTR_PRINTF(1,2); -void _gpgrt_internal_trace_end (void); - +/* The trace macro is used this way: + * trace (("enter - foo=%d bar=%s", foo, bar)); + * Note the double parenthesis, they are important. + * To append the current errno to the output, use + * trace_errno (EXTPR,("leave - baz=%d", faz)); + * If EXPR evaluates to true the output of strerror (errno) + * is appended to the output. Note that the trace function does + * not modify ERRNO. To enable tracing you need to have this + * #define ENABLE_TRACING "modulename" + * before you include gpgrt-int.h. + */ #ifdef ENABLE_TRACING # define trace(X) do { \ _gpgrt_internal_trace_begin \ - (ENABLE_TRACING, __func__, __LINE__); \ + (ENABLE_TRACING, __func__, __LINE__, 0); \ _gpgrt_internal_trace X; \ _gpgrt_internal_trace_end (); \ } while (0) -# define trace_errno(X) do { \ +# define trace_errno(C,X) do { \ _gpgrt_internal_trace_begin \ - (ENABLE_TRACING, __func__, __LINE__); \ - _gpgrt_internal_trace_errno X; \ + (ENABLE_TRACING, __func__, __LINE__, (C)); \ + _gpgrt_internal_trace X; \ _gpgrt_internal_trace_end (); \ } while (0) # define trace_start(X) do { \ _gpgrt_internal_trace_begin \ - (ENABLE_TRACING, __func__, __LINE__); \ + (ENABLE_TRACING, __func__, __LINE__, 0); \ _gpgrt_internal_trace_printf X; \ } while (0) # define trace_append(X) do { \ @@ -87,12 +89,21 @@ void _gpgrt_internal_trace_end (void); } while (0) #else # define trace(X) do { } while (0) -# define trace_errno(X) do { } while (0) +# define trace_errno(C,X) do { } while (0) # define trace_start(X) do { } while (0) # define trace_append(X) do { } while (0) # define trace_finish(X) do { } while (0) #endif /*!ENABLE_TRACING*/ +void _gpgrt_internal_trace_begin (const char *mod, const char *file, int line, + int with_errno); +void _gpgrt_internal_trace (const char *format, + ...) GPGRT_ATTR_PRINTF(1,2); +void _gpgrt_internal_trace_printf (const char *format, + ...) GPGRT_ATTR_PRINTF(1,2); +void _gpgrt_internal_trace_end (void); + + /* Local definitions for estream. */ diff --git a/src/init.c b/src/init.c index e90bec5..a1ee505 100644 --- a/src/init.c +++ b/src/init.c @@ -214,67 +214,88 @@ _gpg_err_set_errno (int err) -/* Internal tracing functions. We use flockfile and funlockfile to - * protect their use. */ +/* Internal tracing functions. Except for TARCE_FP we use flockfile + * and funlockfile to protect their use. */ +static FILE *trace_fp; static int trace_save_errno; +static int trace_with_errno; static const char *trace_arg_module; static const char *trace_arg_file; static int trace_arg_line; +static int trace_missing_lf; +static int trace_prefix_done; void -_gpgrt_internal_trace_begin (const char *module, const char *file, int line) +_gpgrt_internal_trace_begin (const char *module, const char *file, int line, + int with_errno) { int save_errno = errno; + + if (!trace_fp) + { + FILE *fp; + const char *s = getenv ("GPGRT_TRACE_FILE"); + + if (!s || !(fp = fopen (s, "wb"))) + fp = stderr; + trace_fp = fp; + } + #ifdef HAVE_FLOCKFILE - flockfile (stderr); + flockfile (trace_fp); #endif trace_save_errno = save_errno; + trace_with_errno = with_errno; trace_arg_module = module; trace_arg_file = file; trace_arg_line = line; + trace_missing_lf = 0; + trace_prefix_done = 0; } - static void -do_internal_trace (const char *format, va_list arg_ptr, int with_errno) +print_internal_trace_prefix (void) { - fprintf (stderr, "%s:%s:%d: ", - trace_arg_module, trace_arg_file, trace_arg_line); - vfprintf (stderr, format, arg_ptr); - if (with_errno) - fprintf (stderr, " errno=%s", strerror (trace_save_errno)); - fputc ('\n', stderr); + if (!trace_prefix_done) + { + trace_prefix_done = 1; + fprintf (trace_fp, "%s:%s:%d: ", + trace_arg_module,/* npth_is_protected ()?"":"^",*/ + trace_arg_file, trace_arg_line); + } } -void -_gpgrt_internal_trace_printf (const char *format, ...) +static void +do_internal_trace (const char *format, va_list arg_ptr) { - va_list arg_ptr; - - va_start (arg_ptr, format) ; - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); + print_internal_trace_prefix (); + vfprintf (trace_fp, format, arg_ptr); + if (trace_with_errno) + fprintf (trace_fp, " errno=%s", strerror (trace_save_errno)); + if (*format && format[strlen(format)-1] != '\n') + fputc ('\n', trace_fp); } - void -_gpgrt_internal_trace (const char *format, ...) +_gpgrt_internal_trace_printf (const char *format, ...) { va_list arg_ptr; + print_internal_trace_prefix (); va_start (arg_ptr, format) ; - do_internal_trace (format, arg_ptr, 0); + vfprintf (trace_fp, format, arg_ptr); va_end (arg_ptr); + trace_missing_lf = (*format && format[strlen(format)-1] != '\n'); } void -_gpgrt_internal_trace_errno (const char *format, ...) +_gpgrt_internal_trace (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format) ; - do_internal_trace (format, arg_ptr, 1); + do_internal_trace (format, arg_ptr); va_end (arg_ptr); } @@ -283,8 +304,11 @@ void _gpgrt_internal_trace_end (void) { int save_errno = trace_save_errno; + + if (trace_missing_lf) + fputc ('\n', trace_fp); #ifdef HAVE_FLOCKFILE - funlockfile (stderr); + funlockfile (trace_fp); #endif errno = save_errno; } diff --git a/src/w32-estream.c b/src/w32-estream.c index 722cb69..d9a4d36 100644 --- a/src/w32-estream.c +++ b/src/w32-estream.c @@ -133,7 +133,7 @@ set_synchronize (HANDLE hd) GetCurrentProcess (), &new_hd, EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) { - trace_errno (("DuplicateHandle failed: ec=%d", (int)GetLastError ())); + trace_errno (1, ("DuplicateHandle failed: ec=%d", (int)GetLastError ())); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return INVALID_HANDLE_VALUE; @@ -364,6 +364,10 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) gpgrt_ssize_t nread; struct reader_context_s *ctx; + trace (("%p: enter buffer=%p count=%u", cookie, buffer, count)); + + /* FIXME: implement pending check if COUNT==0 */ + ctx = pcookie->reader; if (ctx == NULL) { @@ -371,17 +375,20 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) if (!ctx) { _gpg_err_set_errno (EBADF); - return -1; + nread = -1; + goto leave; } + trace (("%p: new reader %p", cookie, pcookie->reader)); } - trace (("%p: read buffer=%p, count=%u", ctx, buffer, count)); - if (ctx->eof_shortcut) - return 0; + { + nread = 0; + goto leave; + } EnterCriticalSection (&ctx->mutex); - trace (("%p: readpos: %d, writepos %d", ctx, ctx->readpos, ctx->writepos)); + trace (("%p: readpos: %d, writepos %d", cookie, ctx->readpos, ctx->writepos)); if (ctx->readpos == ctx->writepos && !ctx->error) { /* No data available. */ @@ -392,12 +399,13 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) if (pcookie->modeflags & O_NONBLOCK && ! eof) { _gpg_err_set_errno (EAGAIN); - return -1; + nread = -1; + goto leave; } - trace (("%p: waiting for data", ctx)); + trace (("%p: waiting for data", cookie)); WaitForSingleObject (ctx->have_data_ev, INFINITE); - trace (("%p: data available", ctx)); + trace (("%p: data available", cookie)); EnterCriticalSection (&ctx->mutex); } @@ -409,8 +417,9 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) return 0; if (!ctx->error) { - trace (("%p: EOF but ctx->eof flag not set", ctx)); - return 0; + trace (("%p: EOF but ctx->eof flag not set", cookie)); + nread = 0; + goto leave; } _gpg_err_set_errno (ctx->error_code); return -1; @@ -427,24 +436,29 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count) { if (!ResetEvent (ctx->have_data_ev)) { - trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); + trace (("%p: ResetEvent failed: ec=%d", + cookie, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); - return -1; + nread = -1; + goto leave; } } if (!SetEvent (ctx->have_space_ev)) { trace (("%p: SetEvent (%p) failed: ec=%d", - ctx, ctx->have_space_ev, (int)GetLastError ())); + cookie, ctx->have_space_ev, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); - return -1; + nread = -1; + goto leave; } LeaveCriticalSection (&ctx->mutex); + leave: + trace_errno (nread==-1,("%p: leave nread=%d", cookie, (int)nread)); return nread; } @@ -653,21 +667,29 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) { estream_cookie_w32_pollable_t pcookie = cookie; struct writer_context_s *ctx = pcookie->writer; + int nwritten; - trace (("%p: buffer: %p count: %d", ctx, buffer, count)); + trace (("%p: enter buffer: %p count: %d", cookie, buffer, count)); if (count == 0) - return 0; + { + nwritten = 0; + goto leave; + } if (ctx == NULL) { pcookie->writer = ctx = create_writer (pcookie); if (!ctx) - return -1; + { + nwritten = -1; + goto leave; + } + trace (("%p: new writer %p", cookie, pcookie->writer)); } EnterCriticalSection (&ctx->mutex); trace (("%p: buffer: %p, count: %d, nbytes: %d", - ctx, buffer, count, ctx->nbytes)); + cookie, buffer, count, ctx->nbytes)); if (!ctx->error && ctx->nbytes) { /* Bytes are pending for send. */ @@ -675,24 +697,27 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) /* Reset the is_empty event. Better safe than sorry. */ if (!ResetEvent (ctx->is_empty)) { - trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); + trace (("%p: ResetEvent failed: ec=%d", + cookie, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); - return -1; + nwritten = -1; + goto leave; } LeaveCriticalSection (&ctx->mutex); if (pcookie->modeflags & O_NONBLOCK) { - trace (("%p: would block", ctx)); + trace (("%p: would block", cookie)); _gpg_err_set_errno (EAGAIN); - return -1; + nwritten = -1; + goto leave; } - trace (("%p: waiting for empty buffer", ctx)); + trace (("%p: waiting for empty buffer", cookie)); WaitForSingleObject (ctx->is_empty, INFINITE); - trace (("%p: buffer is empty", ctx)); + trace (("%p: buffer is empty", cookie)); EnterCriticalSection (&ctx->mutex); } @@ -703,7 +728,8 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) _gpg_err_set_errno (EPIPE); else _gpg_err_set_errno (EIO); - return -1; + nwritten = -1; + goto leave; } /* If no error occurred, the number of bytes in the buffer must be @@ -719,25 +745,29 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count) used by the select() implementation to probe the channel. */ if (!ResetEvent (ctx->is_empty)) { - trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ())); + trace (("%p: ResetEvent failed: ec=%d", cookie, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); - return -1; + nwritten = -1; + goto leave; } if (!SetEvent (ctx->have_data)) { - trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ())); + trace (("%p: SetEvent failed: ec=%d", cookie, (int)GetLastError ())); LeaveCriticalSection (&ctx->mutex); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); - return -1; + nwritten = -1; + goto leave; } - trace (("%p: nwritten=%d", ctx, count)); LeaveCriticalSection (&ctx->mutex); - trace (("%p: pollable write buffer - leave", ctx)); - return (int) count; + nwritten = count; + + leave: + trace_errno (nwritten==-1,("%p: leave nwritten=%d", cookie, nwritten)); + return nwritten; } @@ -746,6 +776,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) { HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS]; int waitidx[MAXIMUM_WAIT_OBJECTS]; + char waitinfo[MAXIMUM_WAIT_OBJECTS]; unsigned int code; int nwait; int i; @@ -756,7 +787,6 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) restart: #endif - trace_start (("poll on [ ")); any = 0; nwait = 0; count = 0; @@ -782,7 +812,6 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) if (fds[i].want_read) { struct reader_context_s *ctx = pcookie->reader; - trace_append (("%d/read ", i)); if (ctx == NULL) { pcookie->reader = ctx = create_reader (pcookie); @@ -792,48 +821,56 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout) _gpg_err_set_errno (EBADF); return -1; } + trace (("%p: new reader %p", pcookie, pcookie->reader)); } + trace (("%p: using reader %p", pcookie, pcookie->reader)); if (nwait >= DIM (waitbuf)) { - trace_finish (("oops ]: Too many objects for WFMO!")); + trace (("oops: too many objects for WFMO")); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; } waitidx[nwait] = i; + waitinfo[nwait] = 'r'; waitbuf[nwait++] = ctx->have_data_ev; any = 1; } else if (fds[i].want_write) { struct writer_context_s *ctx = pcookie->writer; - trace_append (("%d/write ", i)); if (ctx == NULL) { pcookie->writer = ctx = create_writer (pcookie); if (!ctx) { - trace_finish (("oops ]: create writer failed")); + trace (("oops: create writer failed")); /* FIXME: Is the error code appropriate? */ _gpg_err_set_errno (EBADF); return -1; } + trace (("%p: new writer %p", pcookie, pcookie->writer)); } + trace (("%p: using writer %p", pcookie, pcookie->writer)); if (nwait >= DIM (waitbuf)) { - trace_finish (("oops ]: Too many objects for WFMO")); + trace (("oops: Too many objects for WFMO")); /* FIXME: Should translate the error code. */ _gpg_err_set_errno (EIO); return -1; } waitidx[nwait] = i; + waitinfo[nwait] = 'w'; waitbuf[nwait++] = ctx->is_empty; any = 1; } } } + trace_start (("poll on [ ")); + for (i = 0; i < nwait; i++) + trace_append (("%d/%c ", waitidx[i], waitinfo[i])); trace_finish (("]")); if (!any) return 0; @@ -956,6 +993,7 @@ _gpgrt_w32_pollable_create (void *_GPGRT__RESTRICT *_GPGRT__RESTRICT cookie, err = 0; } + trace_errno (err,("cookie=%p", *cookie)); return err; } commit 07d5bd918d2185f79c7d61d56ee7f3090b6f5dcd Author: Werner Koch Date: Tue Feb 28 10:00:25 2017 +0100 w32: Fix gpgrt_poll for Windows. * src/estream.c (_gpgrt_poll) [W32]: Do not call the syscall clamp. -- The system call clamp may only be used directloy around system calls. We don't need them here because we use independent threads to implement non-blocking behaviour. In fact the clamp may lead to a deadlock. Signed-off-by: Werner Koch diff --git a/src/estream.c b/src/estream.c index c6c9a52..ee3a7df 100644 --- a/src/estream.c +++ b/src/estream.c @@ -4824,14 +4824,8 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) /* Now do the real select. */ #ifdef HAVE_W32_SYSTEM - if (pre_syscall_func) - pre_syscall_func (); - count = _gpgrt_w32_poll (fds, nfds, timeout); - if (post_syscall_func) - post_syscall_func (); - #else /*!HAVE_W32_SYSTEM*/ any_readfd = any_writefd = any_exceptfd = 0; ----------------------------------------------------------------------- Summary of changes: doc/errorref.txt | 2 + src/estream.c | 60 ++++++++++++++++++---------- src/gpgrt-int.h | 41 ++++++++++++------- src/init.c | 74 ++++++++++++++++++++++------------ src/w32-estream.c | 116 ++++++++++++++++++++++++++++++++++++------------------ tests/t-poll.c | 50 +++++++++++++++++++++++ 6 files changed, 243 insertions(+), 100 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 10:56:49 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 28 Feb 2017 10:56:49 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-144-g7cc57e2 Message-ID: This is an 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 7cc57e2c63d0fa97569736419db5c76117e7685b (commit) from 8a67dc4c4324b617b5a3fea51c59c674488544d6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7cc57e2c63d0fa97569736419db5c76117e7685b Author: Justus Winter Date: Tue Feb 28 09:40:01 2017 +0100 gpgscm: Track source locations in every kind of ports. * tests/gpgscm/scheme-private.h (struct port): Move location information out of the union. * tests/gpgscm/scheme.c (mark): All ports need marking now. (gc): Likewise all ports on the load stack. (port_clear_location): Adapt accordingly. Also, add an empty function for !SHOW_ERROR_LINE. (port_increment_current_line): Likewise. (port_reset_current_line): Drop function in favor of... (port_init_location): ... this new function. (file_push): Simplify. (file_pop): Likewise. (port_rep_from_filename): Likewise. (port_rep_from_file): Likewise. (port_rep_from_string): Also initialize the location. (port_rep_from_scratch): Likewise. (port_close): Simplify and generalize. (skipspace): Likewise. (token): Likewise. (_Error_1): Generalize. (opexe_5): Likewise. (scheme_deinit): Simplify and generalize. (scheme_load_named_file): Likewise. (scheme_load_string): Also initialize the location. -- This change tracks the location of source code loaded from non-file ports that is used in error messages. It also simplifies the code quite a bit. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/scheme-private.h b/tests/gpgscm/scheme-private.h index ad8f571..abd89e8 100644 --- a/tests/gpgscm/scheme-private.h +++ b/tests/gpgscm/scheme-private.h @@ -27,10 +27,6 @@ typedef struct port { struct { FILE *file; int closeit; -#if SHOW_ERROR_LINE - pointer curr_line; - pointer filename; -#endif } stdio; struct { char *start; @@ -38,6 +34,10 @@ typedef struct port { char *curr; } string; } rep; +#if SHOW_ERROR_LINE + pointer curr_line; + pointer filename; +#endif } port; /* cell structure */ diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index 1265c62..405dee4 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -1578,10 +1578,8 @@ E2: setmark(p); #if SHOW_ERROR_LINE else if (is_port(p)) { port *pt = p->_object._port; - if (pt->kind & port_file) { - mark(pt->rep.stdio.curr_line); - mark(pt->rep.stdio.filename); - } + mark(pt->curr_line); + mark(pt->filename); } #endif /* Mark tag if p has one. */ @@ -1650,11 +1648,8 @@ static void gc(scheme *sc, pointer a, pointer b) { mark(sc->outport); mark(sc->loadport); for (i = 0; i <= sc->file_i; i++) { - if (! (sc->load_stack[i].kind & port_file)) - continue; - - mark(sc->load_stack[i].rep.stdio.filename); - mark(sc->load_stack[i].rep.stdio.curr_line); + mark(sc->load_stack[i].filename); + mark(sc->load_stack[i].curr_line); } /* Mark recent objects the interpreter doesn't know about yet. */ @@ -1733,25 +1728,41 @@ static void finalize_cell(scheme *sc, pointer a) { static void port_clear_location (scheme *sc, port *p) { - assert(p->kind & port_file); - p->rep.stdio.curr_line = sc->NIL; - p->rep.stdio.filename = sc->NIL; + p->curr_line = sc->NIL; + p->filename = sc->NIL; +} + +static void +port_increment_current_line (scheme *sc, port *p, long delta) +{ + p->curr_line = + mk_integer(sc, ivalue_unchecked(p->curr_line) + delta); } static void -port_reset_current_line (scheme *sc, port *p) +port_init_location (scheme *sc, port *p, pointer name) +{ + p->curr_line = mk_integer(sc, 0); + p->filename = name ? name : mk_string(sc, ""); +} + +#else + +static void +port_clear_location (scheme *sc, port *p) { - assert(p->kind & port_file); - p->rep.stdio.curr_line = mk_integer(sc, 0); } static void port_increment_current_line (scheme *sc, port *p, long delta) { - assert(p->kind & port_file); - p->rep.stdio.curr_line = - mk_integer(sc, ivalue_unchecked(p->rep.stdio.curr_line) + delta); } + +static void +port_init_location (scheme *sc, port *p, pointer name) +{ +} + #endif /* ========== Routines for Reading ========== */ @@ -1769,11 +1780,7 @@ static int file_push(scheme *sc, pointer fname) { sc->load_stack[sc->file_i].rep.stdio.closeit=1; sc->nesting_stack[sc->file_i]=0; sc->loadport->_object._port=sc->load_stack+sc->file_i; - -#if SHOW_ERROR_LINE - port_reset_current_line(sc, &sc->load_stack[sc->file_i]); - sc->load_stack[sc->file_i].rep.stdio.filename = fname; -#endif + port_init_location(sc, &sc->load_stack[sc->file_i], fname); } return fin!=0; } @@ -1782,10 +1789,7 @@ static void file_pop(scheme *sc) { if(sc->file_i != 0) { sc->nesting=sc->nesting_stack[sc->file_i]; port_close(sc,sc->loadport,port_input); -#if SHOW_ERROR_LINE - if (sc->load_stack[sc->file_i].kind & port_file) - port_clear_location(sc, &sc->load_stack[sc->file_i]); -#endif + port_clear_location(sc, &sc->load_stack[sc->file_i]); sc->file_i--; sc->loadport->_object._port=sc->load_stack+sc->file_i; } @@ -1813,15 +1817,7 @@ static port *port_rep_from_filename(scheme *sc, const char *fn, int prop) { } pt=port_rep_from_file(sc,f,prop); pt->rep.stdio.closeit=1; - -#if SHOW_ERROR_LINE - if (fn) - pt->rep.stdio.filename = mk_string(sc, fn); - else - pt->rep.stdio.filename = mk_string(sc, ""); - - port_reset_current_line(sc, pt); -#endif + port_init_location(sc, pt, mk_string(sc, fn)); return pt; } @@ -1845,10 +1841,7 @@ static port *port_rep_from_file(scheme *sc, FILE *f, int prop) pt->kind = port_file | prop; pt->rep.stdio.file = f; pt->rep.stdio.closeit = 0; -#if SHOW_ERROR_LINE - pt->rep.stdio.filename = mk_string(sc, ""); - port_reset_current_line(sc, pt); -#endif + port_init_location(sc, pt, NULL); return pt; } @@ -1871,6 +1864,7 @@ static port *port_rep_from_string(scheme *sc, char *start, char *past_the_end, i pt->rep.string.start=start; pt->rep.string.curr=start; pt->rep.string.past_the_end=past_the_end; + port_init_location(sc, pt, NULL); return pt; } @@ -1902,6 +1896,7 @@ static port *port_rep_from_scratch(scheme *sc) { pt->rep.string.start=start; pt->rep.string.curr=start; pt->rep.string.past_the_end=start+BLOCK_SIZE-1; + port_init_location(sc, pt, NULL); return pt; } @@ -1918,13 +1913,9 @@ static void port_close(scheme *sc, pointer p, int flag) { port *pt=p->_object._port; pt->kind&=~flag; if((pt->kind & (port_input|port_output))==0) { + /* Cleanup is here so (close-*-port) functions could work too */ + port_clear_location(sc, pt); if(pt->kind&port_file) { - -#if SHOW_ERROR_LINE - /* Cleanup is here so (close-*-port) functions could work too */ - port_clear_location(sc, pt); -#endif - fclose(pt->rep.stdio.file); } pt->kind=port_free; @@ -2199,14 +2190,8 @@ static INLINE int skipspace(scheme *sc) { #endif } while (isspace(c)); -/* record it */ -#if SHOW_ERROR_LINE - { - port *p = &sc->load_stack[sc->file_i]; - if (p->kind & port_file) - port_increment_current_line(sc, p, curr_line); - } -#endif + /* record it */ + port_increment_current_line(sc, &sc->load_stack[sc->file_i], curr_line); if(c!=EOF) { backchar(sc,c); @@ -2243,10 +2228,8 @@ static int token(scheme *sc) { while ((c=inchar(sc)) != '\n' && c!=EOF) ; -#if SHOW_ERROR_LINE - if(c == '\n' && sc->load_stack[sc->file_i].kind & port_file) + if(c == '\n') port_increment_current_line(sc, &sc->load_stack[sc->file_i], 1); -#endif if(c == EOF) { return (TOK_EOF); } @@ -2271,10 +2254,8 @@ static int token(scheme *sc) { while ((c=inchar(sc)) != '\n' && c!=EOF) ; -#if SHOW_ERROR_LINE - if(c == '\n' && sc->load_stack[sc->file_i].kind & port_file) + if(c == '\n') port_increment_current_line(sc, &sc->load_stack[sc->file_i], 1); -#endif if(c == EOF) { return (TOK_EOF); } @@ -2828,8 +2809,8 @@ static pointer _Error_1(scheme *sc, const char *s, pointer a) { #if SHOW_ERROR_LINE /* make sure error is not in REPL */ - if (sc->load_stack[sc->file_i].kind & port_file && - sc->load_stack[sc->file_i].rep.stdio.file != stdin) { + if (((sc->load_stack[sc->file_i].kind & port_file) == 0 + || sc->load_stack[sc->file_i].rep.stdio.file != stdin)) { pointer tag; const char *fname; int ln; @@ -2840,8 +2821,8 @@ static pointer _Error_1(scheme *sc, const char *s, pointer a) { fname = string_value(car(tag)); ln = ivalue_unchecked(cdr(tag)); } else { - fname = string_value(sc->load_stack[sc->file_i].rep.stdio.filename); - ln = ivalue_unchecked(sc->load_stack[sc->file_i].rep.stdio.curr_line); + fname = string_value(sc->load_stack[sc->file_i].filename); + ln = ivalue_unchecked(sc->load_stack[sc->file_i].curr_line); } /* should never happen */ @@ -4986,18 +4967,18 @@ static pointer opexe_5(scheme *sc, enum scheme_opcodes op) { } else if (sc->tok == TOK_DOT) { Error_0(sc,"syntax error: illegal dot expression"); } else { +#if USE_TAGS && SHOW_ERROR_LINE + pointer filename; + pointer lineno; +#endif sc->nesting_stack[sc->file_i]++; #if USE_TAGS && SHOW_ERROR_LINE - if (sc->load_stack[sc->file_i].kind & port_file) { - pointer filename = - sc->load_stack[sc->file_i].rep.stdio.filename; - pointer lineno = - sc->load_stack[sc->file_i].rep.stdio.curr_line; - - s_save(sc, OP_TAG_VALUE, - cons(sc, filename, cons(sc, lineno, sc->NIL)), - sc->NIL); - } + filename = sc->load_stack[sc->file_i].filename; + lineno = sc->load_stack[sc->file_i].curr_line; + + s_save(sc, OP_TAG_VALUE, + cons(sc, filename, cons(sc, lineno, sc->NIL)), + sc->NIL); #endif s_save(sc,OP_RDLIST, sc->NIL, sc->NIL); s_thread_to(sc,OP_RDSEXPR); @@ -5064,11 +5045,8 @@ static pointer opexe_5(scheme *sc, enum scheme_opcodes op) { int c = inchar(sc); if (c != '\n') backchar(sc,c); -#if SHOW_ERROR_LINE - else if (sc->load_stack[sc->file_i].kind & port_file) - port_increment_current_line(sc, - &sc->load_stack[sc->file_i], 1); -#endif + port_increment_current_line(sc, + &sc->load_stack[sc->file_i], 1); sc->nesting_stack[sc->file_i]--; s_return(sc,reverse_in_place(sc, sc->NIL, sc->args)); } else if (sc->tok == TOK_DOT) { @@ -5759,12 +5737,9 @@ void scheme_deinit(scheme *sc) { } sc->loadport=sc->NIL; -#if SHOW_ERROR_LINE for(i=0; i<=sc->file_i; i++) { - if (sc->load_stack[i].kind & port_file) - port_clear_location(sc, &sc->load_stack[i]); + port_clear_location(sc, &sc->load_stack[i]); } -#endif sc->gc_verbose=0; gc(sc,sc->NIL,sc->NIL); @@ -5794,13 +5769,10 @@ void scheme_load_named_file(scheme *sc, FILE *fin, const char *filename) { sc->interactive_repl=1; } -#if SHOW_ERROR_LINE - port_reset_current_line(sc, &sc->load_stack[0]); - if(fin!=stdin && filename) - sc->load_stack[0].rep.stdio.filename = mk_string(sc, filename); - else - sc->load_stack[0].rep.stdio.filename = mk_string(sc, ""); -#endif + port_init_location(sc, &sc->load_stack[0], + (fin != stdin && filename) + ? mk_string(sc, filename) + : NULL); sc->inport=sc->loadport; sc->args = mk_integer(sc,sc->file_i); @@ -5810,9 +5782,7 @@ void scheme_load_named_file(scheme *sc, FILE *fin, const char *filename) { sc->retcode=sc->nesting!=0; } -#if SHOW_ERROR_LINE port_clear_location(sc, &sc->load_stack[0]); -#endif } void scheme_load_string(scheme *sc, const char *cmd) { @@ -5823,6 +5793,7 @@ void scheme_load_string(scheme *sc, const char *cmd) { sc->load_stack[0].rep.string.start=(char*)cmd; /* This func respects const */ sc->load_stack[0].rep.string.past_the_end=(char*)cmd+strlen(cmd); sc->load_stack[0].rep.string.curr=(char*)cmd; + port_init_location(sc, &sc->load_stack[0], NULL); sc->loadport=mk_port(sc,sc->load_stack); sc->retcode=0; sc->interactive_repl=0; @@ -5833,6 +5804,8 @@ void scheme_load_string(scheme *sc, const char *cmd) { if(sc->retcode==0) { sc->retcode=sc->nesting!=0; } + + port_clear_location(sc, &sc->load_stack[0]); } void scheme_define(scheme *sc, pointer envir, pointer symbol, pointer value) { ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/scheme-private.h | 8 +-- tests/gpgscm/scheme.c | 157 +++++++++++++++++------------------------- 2 files changed, 69 insertions(+), 96 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 13:19:54 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 28 Feb 2017 13:19:54 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-21-g77626a6 Message-ID: This is an 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 77626a6519bd3fe3fa74e539d9854e722c9d76ba (commit) via 012f1bdc87e9969131c72c5575af0851484a2196 (commit) from f141fdee4015d36aec2122853ef55f3ae42197da (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 77626a6519bd3fe3fa74e539d9854e722c9d76ba Author: Werner Koch Date: Tue Feb 28 12:47:51 2017 +0100 po: Update German translation -- Signed-off-by: Werner Koch diff --git a/po/de.po b/po/de.po index 1a8ebcc..b2b1e9a 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libgpg-error-1.19\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2016-11-14 17:12+0100\n" +"PO-Revision-Date: 2017-02-28 12:47+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: none\n" "Language: de\n" @@ -301,7 +301,7 @@ msgid "Invalid cipher mode" msgstr "Ung?ltiger Verschl?sselungsmodus" msgid "Invalid flag" -msgstr "Ung?ltiges Flag" +msgstr "Ung?ltige Flagge" msgid "Invalid handle" msgstr "Ung?ltiger Handle" @@ -951,6 +951,51 @@ msgstr "Objekt zu jung" msgid "Object is too old" msgstr "Objekt zu alt" +msgid "Unknown flag" +msgstr "Unbekannte Flagge" + +msgid "Invalid execution order" +msgstr "Ung?ltige Verarbeitungsreihenfolge" + +msgid "Already fetched" +msgstr "Bereits geholt" + +msgid "Try again later" +msgstr "Sp?ter erneut versuchen" + +msgid "Wrong name" +msgstr "Falscher Name" + +msgid "System bug detected" +msgstr "Fehler im System entdeckt" + +msgid "Unknown DNS error" +msgstr "Unbekannter DNS Fehler" + +msgid "Invalid DNS section" +msgstr "Ung?ltige DNS \"Section\"" + +msgid "Invalid textual address form" +msgstr "Ung?ltige Textadressenformat" + +# "in der Kette" ist part of the message because many users know about +# certificate chains and thus that keyword might give them a good hint +# what might be wrong. +msgid "Missing DNS query packet" +msgstr "Fehlendes DNS Anfragepaket" + +msgid "Missing DNS answer packet" +msgstr "Fehlendes DNS Antwortpaket" + +msgid "Connection closed in DNS" +msgstr "Verbindung im DNS geschlossen" + +msgid "Verification failed in DNS" +msgstr "Pr?fung im DNS fehlgeschlagen" + +msgid "DNS Timeout" +msgstr "DNS Zeit?berschreitung" + msgid "General LDAP error" msgstr "Allgemeiner LDAP Fehler" @@ -1268,9 +1313,6 @@ msgstr "%s: Warnung: %s konnte nicht erkannt werden\n" #~ msgid "LCUP Invalid data" #~ msgstr "LCUP Ung?ltige Daten" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "\"Assertion\" in LDAP fehlgeschlagen" - #~ msgid "LDAP Other general error" #~ msgstr "Sonstiger allgemeiner LDAP Fehler" commit 012f1bdc87e9969131c72c5575af0851484a2196 Author: Werner Koch Date: Tue Feb 28 12:29:41 2017 +0100 New public header gpgrt.h as alias for gpg-error.h * src/gpg-error.h.in (GPGRT_H): New double include protection. * src/Makefile.am (nodist_include_HEADERS): Add gpgrt.h. (BUILT_SOURCES): Ditto. (CLEANFILES): Ditto. (gpgrt.h): New rule. Signed-off-by: Werner Koch diff --git a/src/Makefile.am b/src/Makefile.am index 06ba1cd..4c77521 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,7 +80,7 @@ lock_obj_pub = \ lib_LTLIBRARIES = libgpg-error.la -nodist_include_HEADERS = gpg-error.h +nodist_include_HEADERS = gpg-error.h gpgrt.h bin_SCRIPTS = gpg-error-config m4datadir = $(datadir)/aclocal m4data_DATA = gpg-error.m4 @@ -95,13 +95,14 @@ EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \ $(lock_obj_pub) BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ - err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h \ + err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h gpgrt.h \ gpg-error.def mkw32errmap.map.c tmp_files = _mkerrcodes.h _gpg-error.def.h mkw32errmap.tab.h mkw32errmap.map.c CLEANFILES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ - gpg-error.h mkerrcodes mkerrcodes.h gpg-error.def mkw32errmap.tab.h \ + gpg-error.h gpgrt.h \ + mkerrcodes mkerrcodes.h gpg-error.def mkw32errmap.tab.h \ mkw32errmap.map.c err-sources-sym.h err-codes-sym.h errnos-sym.h \ gpg-extra/errno.h mkheader $(tmp_files) lock-obj-pub.native.h @@ -305,6 +306,8 @@ gpg-error.h: Makefile mkheader $(parts_of_gpg_error_h) \ ./mkheader $(host_os) $(host_triplet) $(srcdir)/gpg-error.h.in \ ../config.h $(PACKAGE_VERSION) $(VERSION_NUMBER) >$@ +gpgrt.h: gpg-error.h + cp gpg-error.h gpgrt.h install-data-local: if HAVE_W32CE_SYSTEM diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index 19bdeed..4c7ac45 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1,4 +1,4 @@ -/* gpg-error.h - Public interface to libgpg-error. -*- c -*- +/* gpg-error.h or gpgrt.h - Public interface to libgpg-error. -*- c -*- * Copyright (C) 2003, 2004, 2010, 2013, 2014, 2015, 2016 g10 Code GmbH * * This file is part of libgpg-error. @@ -21,6 +21,8 @@ #ifndef GPG_ERROR_H #define GPG_ERROR_H 1 +#ifndef GPGRT_H +#define GPGRT_H 1 #include #include @@ -867,4 +869,5 @@ gpg_error_t gpgrt_b64dec_finish (gpgrt_b64state_t state); #ifdef __cplusplus } #endif +#endif /* GPGRT_H */ #endif /* GPG_ERROR_H */ ----------------------------------------------------------------------- Summary of changes: po/de.po | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- src/Makefile.am | 9 ++++++--- src/gpg-error.h.in | 5 ++++- 3 files changed, 57 insertions(+), 9 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 13:28:11 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 28 Feb 2017 13:28:11 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-146-g4190017 Message-ID: This is an 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 41900175cf046dd9abe3d7a6805f6a403d68df15 (commit) via ebeccd73eb85f9027f0985d77dfe901266c6ddef (commit) from 7cc57e2c63d0fa97569736419db5c76117e7685b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 41900175cf046dd9abe3d7a6805f6a403d68df15 Author: Justus Winter Date: Tue Feb 28 13:20:57 2017 +0100 tests: Improve support for gpgconf. * tests/openpgp/defs.scm: Improve high-level inteface to gpgconf. * tests/openpgp/gpgconf.scm: Adapt. * tests/openpgp/tofu.scm: Use it to select the trust model. Signed-off-by: Justus Winter diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index a890d40..a06a570 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -149,14 +149,33 @@ (define :gc:c:name car) (define :gc:c:description cadr) (define :gc:c:pgmname caddr) +(define (:gc:o:name x) (list-ref x 0)) +(define (:gc:o:flags x) (string->number (list-ref x 1))) +(define (:gc:o:level x) (string->number (list-ref x 2))) +(define (:gc:o:description x) (list-ref x 3)) +(define (:gc:o:type x) (string->number (list-ref x 4))) +(define (:gc:o:alternate-type x) (string->number (list-ref x 5))) +(define (:gc:o:argument-name x) (list-ref x 6)) +(define (:gc:o:default-value x) (list-ref x 7)) +(define (:gc:o:default-argument x) (list-ref x 8)) +(define (:gc:o:value x) (if (< (length x) 10) "" (list-ref x 9))) (define (gpg-config component key) (package (define (value) - (assoc key (gpg-conf '--list-options component))) + (let* ((conf (assoc key (gpg-conf '--list-options component))) + (type (:gc:o:type conf)) + (value (:gc:o:value conf))) + (case type + ((0 2 3) (string->number value)) + ((1 32) (substring value 1 (string-length value)))))) (define (update value) - (gpg-conf' (string-append key ":0:" (percent-encode value)) - `(--change-options ,component))) + (let ((value' (cond + ((string? value) (string-append "\"" value)) + ((number? value) (number->string value)) + (else (throw "Unsupported value" value))))) + (gpg-conf' (string-append key ":0:" (percent-encode value')) + `(--change-options ,component)))) (define (clear) (gpg-conf' (string-append key ":16:") `(--change-options ,component))))) diff --git a/tests/openpgp/gpgconf.scm b/tests/openpgp/gpgconf.scm index b4cc9cb..33d04d8 100644 --- a/tests/openpgp/gpgconf.scm +++ b/tests/openpgp/gpgconf.scm @@ -31,21 +31,18 @@ (if value (begin (opt::update value) - (assert (string=? value (list-ref (opt::value) 9)))) + (assert (equal? value (opt::value)))) (begin (opt::clear) - (let ((v (opt::value))) - (assert (or (< (length v) 10) - (string=? "" (list-ref v 9)))))))) + (assert (or (not (opt::value)) (string=? "" (opt::value))))))) (progress "."))))) (lambda (name . rest) name) (list "keyserver" "verbose" "quiet") (list (gpg-config 'gpg "keyserver") (gpg-config 'gpg "verbose") (gpg-config 'gpg "quiet")) - (list (lambda (i) (if (even? i) "\"hkp://foo.bar" "\"hkps://bar.baz")) - (lambda (i) (number->string - ;; gpgconf: argument for option verbose of type 0 - ;; (none) must be positive - (+ 1 i))) - (lambda (i) (if (even? i) #f "1")))) + (list (lambda (i) (if (even? i) "hkp://foo.bar" "hkps://bar.baz")) + ;; gpgconf: argument for option verbose of type 0 (none) must + ;; be positive + (lambda (i) (+ 1 i)) + (lambda (i) (if (even? i) #f 1)))) diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm index 2e32765..f4eab41 100755 --- a/tests/openpgp/tofu.scm +++ b/tests/openpgp/tofu.scm @@ -33,6 +33,9 @@ (catch (skip "Tofu not supported") (call-check `(, at GPG --trust-model=tofu --list-config))) +(let ((trust-model (gpg-config 'gpg "trust-model"))) + (trust-model::update "tofu")) + (define KEYS '("1C005AF3" "BE04EB2B" "B662E42F")) ;; Import the test keys. @@ -51,7 +54,7 @@ (define (getpolicy keyid . args) (let ((policy (list-ref (assoc "tfs" (gpg-with-colons - `(--trust-model=tofu --with-tofu-info + `(--with-tofu-info , at args --list-keys ,keyid))) 5))) (unless (member policy '("auto" "good" "unknown" "bad" "ask")) @@ -75,8 +78,7 @@ (define (gettrust keyid . args) (let ((trust (list-ref (assoc "pub" (gpg-with-colons - `(--trust-model=tofu - , at args + `(, at args --list-keys ,keyid))) 1))) (unless (and (= 1 (string-length trust)) (member (string-ref trust 0) (string->list "oidreqnmfuws-"))) @@ -96,7 +98,7 @@ ;; Set key KEYID's policy to POLICY. Any remaining arguments are ;; passed as options to gpg. (define (setpolicy keyid policy . args) - (call-check `(, at GPG --trust-model=tofu , at args + (call-check `(, at GPG , at args --tofu-policy ,policy ,keyid))) (info "Checking tofu policies and trust...") @@ -106,8 +108,7 @@ ;; Verify a message. There should be no conflict and the trust ;; policy should be set to auto. -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/1C005AF3-1.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/1C005AF3-1.txt"))) (checkpolicy "1C005AF3" "auto") ;; Check default trust. @@ -161,8 +162,7 @@ ;; auto), but not affect 1C005AF3's policy. (setpolicy "BE04EB2B" "auto") (checkpolicy "BE04EB2B" "ask") -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/B662E42F-1.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/B662E42F-1.txt"))) (checkpolicy "BE04EB2B" "ask") (checkpolicy "1C005AF3" "bad") (checkpolicy "B662E42F" "ask") @@ -176,8 +176,7 @@ (let* ((tfs (assoc "tfs" (gpg-with-colons - `(--trust-model=tofu --with-tofu-info - , at args --list-keys ,keyid)))) + `(--with-tofu-info , at args --list-keys ,keyid)))) (sigs (string->number (list-ref tfs 3))) (sig-days (string->number (list-ref tfs 11))) (encs (string->number (list-ref tfs 4))) @@ -208,31 +207,26 @@ (check-counts "B662E42F" 0 0 0 0) ;; Verify a message. The signature count should increase by 1. -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/1C005AF3-1.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/1C005AF3-1.txt"))) (check-counts "1C005AF3" 1 1 0 0) ;; Verify the same message. The signature count should remain the ;; same. -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/1C005AF3-1.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/1C005AF3-1.txt"))) (check-counts "1C005AF3" 1 1 0 0) ;; Verify another message. -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/1C005AF3-2.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/1C005AF3-2.txt"))) (check-counts "1C005AF3" 2 1 0 0) ;; Verify another message. -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/1C005AF3-3.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/1C005AF3-3.txt"))) (check-counts "1C005AF3" 3 1 0 0) ;; Verify a message from a different sender. The signature count ;; should increase by 1 for that key. -(call-check `(, at GPG --trust-model=tofu - --verify ,(in-srcdir "tofu/conflicting/BE04EB2B-1.txt"))) +(call-check `(, at GPG --verify ,(in-srcdir "tofu/conflicting/BE04EB2B-1.txt"))) (check-counts "1C005AF3" 3 1 0 0) (check-counts "BE04EB2B" 1 1 0 0) (check-counts "B662E42F" 0 0 0 0) @@ -240,34 +234,34 @@ ;; Verify another message on a new day. (Recall: we are interested in ;; when the message was first verified, not when the signer claimed ;; that it was signed.) -(call-check `(, at GPG --trust-model=tofu ,(faketime (days->seconds 2)) +(call-check `(, at GPG ,(faketime (days->seconds 2)) --verify ,(in-srcdir "tofu/conflicting/1C005AF3-4.txt"))) (check-counts "1C005AF3" 4 2 0 0) (check-counts "BE04EB2B" 1 1 0 0) (check-counts "B662E42F" 0 0 0 0) ;; And another. -(call-check `(, at GPG --trust-model=tofu ,(faketime (days->seconds 2)) +(call-check `(, at GPG ,(faketime (days->seconds 2)) --verify ,(in-srcdir "tofu/conflicting/1C005AF3-5.txt"))) (check-counts "1C005AF3" 5 2 0 0) (check-counts "BE04EB2B" 1 1 0 0) (check-counts "B662E42F" 0 0 0 0) ;; Another, but for a different key. -(call-check `(, at GPG --trust-model=tofu ,(faketime (days->seconds 2)) +(call-check `(, at GPG ,(faketime (days->seconds 2)) --verify ,(in-srcdir "tofu/conflicting/BE04EB2B-2.txt"))) (check-counts "1C005AF3" 5 2 0 0) (check-counts "BE04EB2B" 2 2 0 0) (check-counts "B662E42F" 0 0 0 0) ;; And add a third day. -(call-check `(, at GPG --trust-model=tofu ,(faketime (days->seconds 4)) +(call-check `(, at GPG ,(faketime (days->seconds 4)) --verify ,(in-srcdir "tofu/conflicting/BE04EB2B-3.txt"))) (check-counts "1C005AF3" 5 2 0 0) (check-counts "BE04EB2B" 3 3 0 0) (check-counts "B662E42F" 0 0 0 0) -(call-check `(, at GPG --trust-model=tofu ,(faketime (days->seconds 4)) +(call-check `(, at GPG ,(faketime (days->seconds 4)) --verify ,(in-srcdir "tofu/conflicting/BE04EB2B-4.txt"))) (check-counts "1C005AF3" 5 2 0 0) (check-counts "BE04EB2B" 4 3 0 0) @@ -299,7 +293,7 @@ (for-each (lambda (i) (let ((fn (in-srcdir DIR (string-append key "-" i ".txt")))) - (call-check `(, at GPG --trust-model=tofu --verify ,fn)))) + (call-check `(, at GPG --verify ,fn)))) (list "1" "2"))) (list KEYIDA KEYIDB))) @@ -391,7 +385,7 @@ (for-each (lambda (i) (let ((fn (in-srcdir DIR (string-append key "-" i ".txt")))) - (call-check `(, at GPG --trust-model=tofu --verify ,fn)))) + (call-check `(, at GPG --verify ,fn)))) (list "1" "2"))) (list KEYIDA KEYIDB))) commit ebeccd73eb85f9027f0985d77dfe901266c6ddef Author: Justus Winter Date: Tue Feb 28 13:15:42 2017 +0100 gpg,tools: Make trust-model configurable via gpgconf. * g10/gpg.c (gpgconf_list): Add 'trust-model'. * tools/gpgconf-comp.c (gc_options_gpg): Likewise. GnuPG-bug-id: 2381 Signed-off-by: Justus Winter diff --git a/g10/gpg.c b/g10/gpg.c index 0c5a167..09bdf66 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1845,6 +1845,7 @@ gpgconf_list (const char *configfile) es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE); es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg"); es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("trust-model:%lu:\n", GC_OPT_FLAG_NONE); /* The next one is an info only item and should match the macros at the top of keygen.c */ diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index d1144b2..1840b8f 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -717,6 +717,10 @@ static gc_option_t gc_options_gpg[] = (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE, NULL, NULL, GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, + { "trust-model", + GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, { "Debug", ----------------------------------------------------------------------- Summary of changes: g10/gpg.c | 1 + tests/openpgp/defs.scm | 25 +++++++++++++++++++++--- tests/openpgp/gpgconf.scm | 17 +++++++---------- tests/openpgp/tofu.scm | 48 +++++++++++++++++++++-------------------------- tools/gpgconf-comp.c | 4 ++++ 5 files changed, 55 insertions(+), 40 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 15:01:06 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 28 Feb 2017 15:01:06 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-147-gd379a01 Message-ID: This is an 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 d379a0174cca595204b32da9a66c513a1304e6d0 (commit) from 41900175cf046dd9abe3d7a6805f6a403d68df15 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d379a0174cca595204b32da9a66c513a1304e6d0 Author: Justus Winter Date: Tue Feb 28 14:59:11 2017 +0100 gpg,tools: Make auto-key-retrieve configurable via gpgconf. * g10/gpg.c (gpgconf_list): Add 'auto-key-retrieve'. * tools/gpgconf-comp.c (gc_options_gpg): Likewise. GnuPG-bug-id: 2381 Signed-off-by: Justus Winter diff --git a/g10/gpg.c b/g10/gpg.c index 09bdf66..2a4a0ad 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1840,6 +1840,7 @@ gpgconf_list (const char *configfile) es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE); es_printf ("try-secret-key:%lu:\n", GC_OPT_FLAG_NONE); es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("auto-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE); diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 1840b8f..d53947e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -748,6 +748,8 @@ static gc_option_t gc_options_gpg[] = { "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"), GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, + { "auto-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, GC_OPTION_NULL ----------------------------------------------------------------------- Summary of changes: g10/gpg.c | 1 + tools/gpgconf-comp.c | 2 ++ 2 files changed, 3 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 15:24:14 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 28 Feb 2017 15:24:14 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-25-g2f4ccc1 Message-ID: This is an 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 2f4ccc1c179110de67ca38c48b489f71c175ea67 (commit) via c1668f61c58ea6f0439e5193d83b4e2ac622b286 (commit) via 98593a55107b2f6024f4055ffb3ccf56fd612cb5 (commit) via 8d45ec8f8f61268a74d9c40b840a8fbd6f805a07 (commit) from 77626a6519bd3fe3fa74e539d9854e722c9d76ba (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f4ccc1c179110de67ca38c48b489f71c175ea67 Author: Werner Koch Date: Tue Feb 28 15:21:26 2017 +0100 Post release updates -- Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 89920ca..bfea6e0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +Noteworthy changes in version 1.28 (unreleased) [C22/A22/R_] +----------------------------------------------- + + * Interface changes relative to the 1.27 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Noteworthy changes in version 1.27 (2017-02-28) [C22/A22/R0] ----------------------------------------------- diff --git a/configure.ac b/configure.ac index 6c5a76c..a44f0c8 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ min_automake_version="1.14" # See below for the LT versions. m4_define([mym4_package],[libgpg-error]) m4_define([mym4_major], [1]) -m4_define([mym4_minor], [27]) +m4_define([mym4_minor], [28]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit c1668f61c58ea6f0439e5193d83b4e2ac622b286 Author: Werner Koch Date: Tue Feb 28 14:58:27 2017 +0100 Release 1.27 * configure.ac: Bump LT version to C22/A22/R0. -- Note that C21/A21/R0 was used in 1.26 but later lost in the repo due to a merge. Signed-off-by: Werner Koch diff --git a/AUTHORS b/AUTHORS index 017fe97..a8e8abe 100644 --- a/AUTHORS +++ b/AUTHORS @@ -51,7 +51,7 @@ Thanks to Yukihiro Nakadaira for his public domain iconv implementation for Windows. - Copyright 2003-2007, 2013-2016 g10 Code GmbH + Copyright 2003-2007, 2013-2017 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/NEWS b/NEWS index 4901d99..89920ca 100644 --- a/NEWS +++ b/NEWS @@ -1,19 +1,24 @@ -Noteworthy changes in version 1.27 (unreleased) [C2_/A2_/R_] +Noteworthy changes in version 1.27 (2017-02-28) [C22/A22/R0] ----------------------------------------------- + * Added a Base64 decoder. + + * Added support for the sh3 architecture. + + * Added header gpgrt.h as an alias for gpg-error.h. + * Fixed macro GPGRT_GCC_VERSION. + * Fixed a race in non-blocking I/O on Windows. + * Interface changes relative to the 1.26 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgrt_b64state_t NEW type. gpgrt_b64dec_start NEW. gpgrt_b64dec_proc NEW. gpgrt_b64dec_finish NEW. - - - * Interface changes relative to the 1.26 release: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GPG_ERR_WRONG_NAME NEW. + gpgrt.h NEW header. Noteworthy changes in version 1.26 (2016-12-21) [C21/A21/R0] diff --git a/configure.ac b/configure.ac index 30a46bc..6c5a76c 100644 --- a/configure.ac +++ b/configure.ac @@ -48,8 +48,8 @@ AC_INIT([mym4_package],[mym4_version], [https://bugs.gnupg.org]) # (Interfaces added: AGE++) # (Interfaces removed: AGE=0) # Note that added error codes don't constitute an interface change. -LIBGPG_ERROR_LT_CURRENT=20 -LIBGPG_ERROR_LT_AGE=20 +LIBGPG_ERROR_LT_CURRENT=22 +LIBGPG_ERROR_LT_AGE=22 LIBGPG_ERROR_LT_REVISION=0 ################################################ diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index 4c7ac45..988898e 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1,5 +1,5 @@ /* gpg-error.h or gpgrt.h - Public interface to libgpg-error. -*- c -*- - * Copyright (C) 2003, 2004, 2010, 2013, 2014, 2015, 2016 g10 Code GmbH + * Copyright (C) 2003-2004, 2010, 2013-2017 g10 Code GmbH * * This file is part of libgpg-error. * diff --git a/src/version.c b/src/version.c index 64a9ac1..eaeedf8 100644 --- a/src/version.c +++ b/src/version.c @@ -39,7 +39,7 @@ cright_blurb (void) static const char blurb[] = "\n\n" "This is Libgpg-error " PACKAGE_VERSION " - An error code library\n" - "Copyright 2003, 2004, 2010, 2013, 2014, 2015, 2016 g10 Code GmbH\n" + "Copyright 2003-2004, 2010, 2013-2017 g10 Code GmbH\n" "\n" "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" "\n\n"; diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index 67599c6..0986a42 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -39,7 +39,7 @@ BEGIN VALUE "FileDescription", "libgpg-error - Common error codes\0" VALUE "FileVersion", "@LIBGPG_ERROR_LT_CURRENT at .@LIBGPG_ERROR_LT_AGE at .@LIBGPG_ERROR_LT_REVISION at .@BUILD_REVISION@\0" VALUE "InternalName", "libgpg-error\0" - VALUE "LegalCopyright", "Copyright ? 2016 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright ? 2017 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libgpg-error.dll\0" VALUE "PrivateBuild", "\0" commit 98593a55107b2f6024f4055ffb3ccf56fd612cb5 Author: Werner Koch Date: Tue Feb 28 14:53:42 2017 +0100 po: Auto update -- diff --git a/po/cs.po b/po/cs.po index 4ff6ef0..47ad00f 100644 --- a/po/cs.po +++ b/po/cs.po @@ -974,6 +974,66 @@ msgid "Object is too old" msgstr "Dodan?? objekt je p????li?? kr??tk??" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nezn??m?? jm??no" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Neplatn?? k??d operace" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Nezn??m?? jm??no" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Nezn??m?? chyba syst??mu" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Neplatn?? ??et??zec OID" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Neplatn?? S-v??raz" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Chyb?? certifik??t vydavatele" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "De??ifrov??n?? selhalo" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "??as vypr??el" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Obecn?? chyba IPC" @@ -1410,11 +1470,6 @@ msgstr "%s: pozor: %s nebylo mo??n?? rozpoznat\n" #~ msgstr "Neplatn?? data" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "De??ifrov??n?? selhalo" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Obecn?? chyba" diff --git a/po/da.po b/po/da.po index 61ba1e2..c685ea2 100644 --- a/po/da.po +++ b/po/da.po @@ -970,6 +970,66 @@ msgid "Object is too old" msgstr "Angivet objekt er for kort" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Ukendt navn" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Ugyldig handlingskode" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Ukendt navn" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Ukendt systemfejl" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Ugyldig OID-streng" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Ugyldigt S-udtryk" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Manglende udstedercertfikat" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Afkryptering mislykkedes" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Tidsudl??b" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Generel IPC-fejl" @@ -1405,11 +1465,6 @@ msgstr "%s: advarsel: kunne ikke genkende %s\n" #~ msgstr "Ugyldige data" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Afkryptering mislykkedes" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Generel fejl" diff --git a/po/eo.po b/po/eo.po index 5948f9a..bc3e987 100644 --- a/po/eo.po +++ b/po/eo.po @@ -1028,6 +1028,66 @@ msgid "Object is too old" msgstr "Provizita objekto tro mallongas" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nekonata nomo" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Malvalida operacia kodo" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Nekonata nomo" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Nekonata sistem-eraro" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Malvalida ??eno OID" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Malvalida S-esprimo" + +#, fuzzy +#| msgid "Missing certificate" +msgid "Missing DNS query packet" +msgstr "Mankas atestilo" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Mal??ifro fiaskis" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Tempofino" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "??enerala eraro de IPC" @@ -1459,11 +1519,6 @@ msgstr "%s: averto: ne eblis rekoni %s\n" #~ msgstr "Malvalida datumaro" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Mal??ifro fiaskis" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "??enerala eraro" diff --git a/po/fr.po b/po/fr.po index db1cdcb..3e7abba 100644 --- a/po/fr.po +++ b/po/fr.po @@ -967,6 +967,66 @@ msgid "Object is too old" msgstr "L'objet fourni est trop petit" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nom inconnu" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Code d'op??ration incorrect" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Nom inconnu" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Erreur syst??me inconnue" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Cha??ne OID incorrecte" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Expression symbolique incorrecte" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Certificat de l'??metteur manquant" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "??chec de d??chiffrement" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "D??lai d'attente d??pass??" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Erreur g??n??rale IPC" @@ -1402,11 +1462,6 @@ msgstr "%s??: attention??: impossible de reconna??tre %s\n" #~ msgstr "Donn??es incorrectes" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "??chec de d??chiffrement" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Erreur g??n??rale" diff --git a/po/hu.po b/po/hu.po index cb143e0..82f7098 100644 --- a/po/hu.po +++ b/po/hu.po @@ -1026,6 +1026,66 @@ msgid "Object is too old" msgstr "A megadott objektum t??l kicsi" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Ismeretlen n??v" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "??rv??nytelen m??veletk??d" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Ismeretlen n??v" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Ismeretlen rendszerhiba" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "??rv??nytelen OID karakterl??nc" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "??rv??nytelen S-kifejez??s" + +#, fuzzy +#| msgid "Missing certificate" +msgid "Missing DNS query packet" +msgstr "Hi??nyz?? tan??s??tv??ny" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Visszafejt??s sikertelen" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Id??t??ll??p??s" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "??ltal??nos IPC hiba" @@ -1457,11 +1517,6 @@ msgstr "%s: figyelmeztet??s: nem siker??lt felismerni: %s\n" #~ msgstr "??rv??nytelen adatok" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Visszafejt??s sikertelen" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "??ltal??nos hiba" diff --git a/po/it.po b/po/it.po index dc17bcb..2e7dc2b 100644 --- a/po/it.po +++ b/po/it.po @@ -965,6 +965,66 @@ msgid "Object is too old" msgstr "L'oggetto fornito ?? troppo piccolo" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nome sconosciuto" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Codice di operazione non valido" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Nome sconosciuto" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Errore di sistema sconosciuto" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Testo per l'OID non valido" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "S-expression non valida" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Manca il certificato dell'emittente" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Decifratura non riuscita" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Tempo scaduto" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Errore IPC generale" @@ -1400,11 +1460,6 @@ msgstr "%s: avviso: impossibile riconoscere %s\n" #~ msgstr "Dati non validi" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Decifratura non riuscita" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Errore generale" diff --git a/po/ja.po b/po/ja.po index a0262d6..17f2a55 100644 --- a/po/ja.po +++ b/po/ja.po @@ -125,8 +125,8 @@ msgstr "?????????????????????????????????" msgid "Invalid cipher algorithm" msgstr "???????????????????????????????????????" -msgid "Keyring open" -msgstr "????????????????????????" +msgid "Cannot open keyring" +msgstr "" msgid "Invalid packet" msgstr "???????????????????????????" @@ -728,6 +728,9 @@ msgstr "S??????????????????16?????????????????????????????????" msgid "Bad octal character in S-expression" msgstr "S??????????????????8?????????????????????????????????" +msgid "All subkeys are expired or revoked" +msgstr "" + msgid "Database is corrupted" msgstr "????????????????????????????????????????????????" @@ -917,6 +920,105 @@ msgstr "IPC??????????????????????????????" msgid "Unknown IPC inquire" msgstr "?????????IPC?????????????????????" +#, fuzzy +#| msgid "No crypto engine" +msgid "Crypto engine too old" +msgstr "????????????????????????????????????" + +msgid "Screen or window too small" +msgstr "" + +msgid "Screen or window too large" +msgstr "" + +msgid "Required environment variable not set" +msgstr "" + +#, fuzzy +#| msgid "Already exists (LDAP)" +msgid "User ID already exists" +msgstr "????????????????????? (LDAP)" + +#, fuzzy +#| msgid "Already exists (LDAP)" +msgid "Name already exists" +msgstr "????????????????????? (LDAP)" + +#, fuzzy +#| msgid "Duplicated value" +msgid "Duplicated name" +msgstr "?????????????????????" + +#, fuzzy +#| msgid "Certificate too young" +msgid "Object is too young" +msgstr "???????????????????????????" + +#, fuzzy +#| msgid "Provided object is too short" +msgid "Object is too old" +msgstr "??????????????????????????????????????????????????????" + +#, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "?????????????????????" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "??????????????????????????????" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "No name" +msgid "Wrong name" +msgstr "????????????????????????" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "??????????????????????????????" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "????????? OID ???????????????" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "????????? S-?????????" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "????????????????????????????????????" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "???????????????????????????" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "????????????????????????" + msgid "General LDAP error" msgstr "??????LDAP???????????????" @@ -1227,3 +1329,6 @@ msgstr "?????????: %s GPG-ERROR [...]\n" #, c-format msgid "%s: warning: could not recognize %s\n" msgstr "%s: ??????: %s ?????????????????????????????????\n" + +#~ msgid "Keyring open" +#~ msgstr "????????????????????????" diff --git a/po/nl.po b/po/nl.po index d90ac4f..a174ee1 100644 --- a/po/nl.po +++ b/po/nl.po @@ -966,6 +966,66 @@ msgid "Object is too old" msgstr "Geleverd object is te kort" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Onbekende naam" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Ongeldige bewerkingscode" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Onbekende naam" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Onbekende systeemfout" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Ongeldige OID-tekenreeks" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Ongeldige S-expressie" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Ontbrekend certificaat van uitgever" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Ontcijfering is mislukt" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Tijdslimiet" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Algemene IPC-fout" @@ -1401,11 +1461,6 @@ msgstr "%s: waarschuwing: kon %s niet herkennen\n" #~ msgstr "Ongeldige gegevens" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Ontcijfering is mislukt" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Algemene fout" diff --git a/po/pl.po b/po/pl.po index 66f66f2..3aee7e6 100644 --- a/po/pl.po +++ b/po/pl.po @@ -957,6 +957,66 @@ msgstr "Certyfikat zbyt m??ody" msgid "Object is too old" msgstr "Dostarczony obiekt jest zbyt ma??y" +#, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nieznana nazwa" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Niepoprawny kod operacji" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "No name" +msgid "Wrong name" +msgstr "Brak nazwy" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Nieznany b????d systemu" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Niepoprawny ??a??cuch OID" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Niepoprawne S-wyra??enie" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Brak certyfikatu wystawcy" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Odszyfrowywanie nie powiod??o si??" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Up??yn???? limit czasu" + msgid "General LDAP error" msgstr "B????d og??lny LDAP" diff --git a/po/pt.po b/po/pt.po index 822d307..7feb13b 100644 --- a/po/pt.po +++ b/po/pt.po @@ -966,6 +966,66 @@ msgid "Object is too old" msgstr "O objecto fornecido ?? demasiado curto" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nome desconhecido" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "C??digo de opera????o inv??lido" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Nome desconhecido" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Erro de sistema desconhecido" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Sequ??ncia OID inv??lida" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Express??o simb??lica inv??lida" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "Certificado do emissor em falta" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Desencripta????o falhada" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Tempo limite" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Erro gen??rico de IPC" @@ -1401,11 +1461,6 @@ msgstr "%s: aviso: n??o consegui reconhecer %s\n" #~ msgstr "Dados inv??lidos" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Desencripta????o falhada" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Erro gen??rico" diff --git a/po/ro.po b/po/ro.po index 6354580..72a52f7 100644 --- a/po/ro.po +++ b/po/ro.po @@ -1039,6 +1039,65 @@ msgid "Object is too old" msgstr "Obiectul furnizat e prea scurt" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Nume necunoscut" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Cod opera??ie invalid" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Nume necunoscut" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Eroare de sistem necunoscut??" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "??ir OID invalid" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Expresie-S invalid??" + +#, fuzzy +msgid "Missing DNS query packet" +msgstr "Certificat lips??" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Decriptarea a e??uat" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Pauz??" + +#, fuzzy msgid "General LDAP error" msgstr "Eroare general??" @@ -1454,11 +1513,6 @@ msgstr "%s: avertisment: nu am putut recunoa??te %s\n" #~ msgstr "Date invalide" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Decriptarea a e??uat" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Eroare general??" diff --git a/po/ru.po b/po/ru.po index 8ff628b..a511618 100644 --- a/po/ru.po +++ b/po/ru.po @@ -963,6 +963,66 @@ msgstr "???????????????????? ?????????????? ??????????" msgid "Object is too old" msgstr "?????????????????? ???????????? ?????????????? ??????" +#, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "?????????????????????? ??????" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "???????????????????????? ?????? ????????????????" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "?????????????????????? ??????" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "?????????????????????? ?????????????????? ????????????" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "???????????????????????? ???????????? OID" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "???????????????????????? S-??????????????????" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "???? ?????????????? ?????????????????????? ????????????????" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "???????? ??????????????????????" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "?????????? ??????????????" + msgid "General LDAP error" msgstr "?????????? ???????????? LDAP" diff --git a/po/sr.po b/po/sr.po index 1a0f4f4..4ddcf72 100644 --- a/po/sr.po +++ b/po/sr.po @@ -1025,6 +1025,66 @@ msgid "Object is too old" msgstr "???????????????????? ?????????????? ???? ??????????????????" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "???????????????? ??????????" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "???????????????????? ?????????? ??????????" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "???????????????? ??????????" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "?????????????????? ???????????? ??????????????" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "???????????????????? ?????? ??????????" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "???????????????????? ??-??????????" + +#, fuzzy +#| msgid "Missing certificate" +msgid "Missing DNS query packet" +msgstr "?????????????????? ??????????????" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "?????????????????????? ???????? ????????????" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "?????????? ???? ??????????????" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "?????????? ???????????? ??????-??" @@ -1456,11 +1516,6 @@ msgstr "%s: ??????????????????: ???? ???????? ???? ?????????????????? ???%s???\n #~ msgstr "???????????????????? ????????????" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "?????????????????????? ???????? ????????????" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "?????????? ????????????" diff --git a/po/sv.po b/po/sv.po index 5ed1db1..70d42db 100644 --- a/po/sv.po +++ b/po/sv.po @@ -1014,6 +1014,65 @@ msgid "Object is too old" msgstr "Tillhandah??llet objekt ??r f??r kort" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "Ok??nt namn" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "Ogiltig ??tg??rdskod" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "Ok??nt namn" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "Ok??nt systemfel" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Ogiltig OID-str??ng" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Ogiltigt S-uttryck" + +#, fuzzy +msgid "Missing DNS query packet" +msgstr "Saknar certifikat" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "Dekryptering misslyckades" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Tidsgr??ns" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "Allm??nt IPC-fel" @@ -1445,11 +1504,6 @@ msgstr "%s: varning: k??nde inte igen %s\n" #~ msgstr "Ogiltig data" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "Dekryptering misslyckades" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "Allm??nt fel" diff --git a/po/uk.po b/po/uk.po index 173bacd..9685110 100644 --- a/po/uk.po +++ b/po/uk.po @@ -974,6 +974,66 @@ msgstr "???????????????????? ?? ?????????? ??????????" msgid "Object is too old" msgstr "?????????????? ????????????? ?? ?????????? ????????????????" +#, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "???????????????? ??????????" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "?????????????????????? ?????? ??????" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "???????????????? ??????????" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "???????????????? ???????????????? ??????????????" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "?????????????????????? ?????????? OID" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "?????????????????????? S-??????????" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "???? ???????????????? ?????????????????????? ??????????????" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "???????????? ?????????????????????????? ?????????????? ??????????????" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "?????? ????????????????????" + msgid "General LDAP error" msgstr "???????????????? ?????????????? LDAP" @@ -1296,11 +1356,6 @@ msgstr "%s: ????????????????????????: ???? ?????????????? ???????????????????? % #~ msgstr "???????????????????? ????????" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "???????????? ?????????????????????????? ?????????????? ??????????????" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "???????????????? ??????????????" diff --git a/po/vi.po b/po/vi.po index 1179fca..da067f4 100644 --- a/po/vi.po +++ b/po/vi.po @@ -1016,6 +1016,65 @@ msgid "Object is too old" msgstr "???? cung c???p m???t ?????i t?????ng qu?? ng???n" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "T??n kh??ng r??" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "M?? thao t??c kh??ng h???p l???" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "T??n kh??ng r??" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "G???p l???i h??? th???ng kh??ng r??" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "Chu???i OID kh??ng h???p l???" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "Bi???u th???c S kh??ng h???p l???" + +#, fuzzy +msgid "Missing DNS query packet" +msgstr "Ch???ng nh???n c??n thi???u" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "L???i gi???i m???t m??" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "Qu?? gi???" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "L???i IPC chung" @@ -1447,11 +1506,6 @@ msgstr "%s: c???nh b??o : kh??ng th??? nh???n ra %s\n" #~ msgstr "D??? li???u kh??ng h???p l???" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "L???i gi???i m???t m??" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "L???i chung" diff --git a/po/zh_CN.po b/po/zh_CN.po index a65757e..0ddea6c 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -1013,6 +1013,63 @@ msgid "Object is too old" msgstr "??????????????????" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "????????????" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "??????????????????" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "????????????" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "?????????????????????" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "?????????OID ?????????" + +msgid "Invalid textual address form" +msgstr "" + +#, fuzzy +msgid "Missing DNS query packet" +msgstr "????????????" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "????????????" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "??????" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "??????IPC ??????" @@ -1444,11 +1501,6 @@ msgstr "%s???????????????????????? %s\n" #~ msgstr "???????????????" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "????????????" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "????????????" diff --git a/po/zh_TW.po b/po/zh_TW.po index afa8ae4..040f5ba 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -968,6 +968,66 @@ msgid "Object is too old" msgstr "?????????????????????" #, fuzzy +#| msgid "Unknown name" +msgid "Unknown flag" +msgstr "???????????????" + +#, fuzzy +#| msgid "Invalid operation code" +msgid "Invalid execution order" +msgstr "??????????????????" + +msgid "Already fetched" +msgstr "" + +msgid "Try again later" +msgstr "" + +#, fuzzy +#| msgid "Unknown name" +msgid "Wrong name" +msgstr "???????????????" + +msgid "System bug detected" +msgstr "" + +#, fuzzy +#| msgid "Unknown system error" +msgid "Unknown DNS error" +msgstr "?????????????????????" + +#, fuzzy +#| msgid "Invalid OID string" +msgid "Invalid DNS section" +msgstr "????????? OID ??????" + +#, fuzzy +#| msgid "Invalid S-expression" +msgid "Invalid textual address form" +msgstr "????????? S-?????????" + +#, fuzzy +#| msgid "Missing issuer certificate" +msgid "Missing DNS query packet" +msgstr "?????????????????????" + +msgid "Missing DNS answer packet" +msgstr "" + +msgid "Connection closed in DNS" +msgstr "" + +#, fuzzy +#| msgid "Decryption failed" +msgid "Verification failed in DNS" +msgstr "????????????" + +#, fuzzy +#| msgid "Timeout" +msgid "DNS Timeout" +msgstr "??????" + +#, fuzzy #| msgid "General IPC error" msgid "General LDAP error" msgstr "???????????? IPC ??????" @@ -1403,11 +1463,6 @@ msgstr "%s: ??????: ???????????? %s\n" #~ msgstr "???????????????" #, fuzzy -#~| msgid "Decryption failed" -#~ msgid "Assertion failed in lDAP" -#~ msgstr "????????????" - -#, fuzzy #~| msgid "General error" #~ msgid "LDAP Other general error" #~ msgstr "????????????" commit 8d45ec8f8f61268a74d9c40b840a8fbd6f805a07 Author: Werner Koch Date: Tue Feb 28 13:37:12 2017 +0100 Add support for armv7-unknown-linux-gnueabihf. * src/syscfg/lock-obj-pub.arm-unknown-linux-gnueabihf.h: Remove. * src/syscfg/lock-obj-pub.armv5-unknown-linux-musleabi.h: Remove. * src/syscfg/lock-obj-pub.armv6-unknown-linux-musleabihf.h: Remove. * src/Makefile.am (lock_obj_pub): Remove them. * src/mkheader.c (canon_host_triplet): Add removed as aliases. Addn alias for armv7-unknown-linux-gnueabihf. -- Info provided by Marvin Schmidt via gnupg-devel at gnupg.org on Tue, 14 Feb 2017 15:00:15 +0100 Consilidated arm syscfg file by aliasing them. Signed-off-by: Werner Koch diff --git a/src/Makefile.am b/src/Makefile.am index 4c77521..398ec5e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,10 +46,7 @@ lock_obj_pub = \ syscfg/lock-obj-pub.alpha-unknown-linux-gnu.h \ syscfg/lock-obj-pub.arm-unknown-linux-androideabi.h \ syscfg/lock-obj-pub.arm-unknown-linux-gnueabi.h \ - syscfg/lock-obj-pub.arm-unknown-linux-gnueabihf.h \ syscfg/lock-obj-pub.arm-apple-darwin.h \ - syscfg/lock-obj-pub.armv5-unknown-linux-musleabi.h \ - syscfg/lock-obj-pub.armv6-unknown-linux-musleabihf.h \ syscfg/lock-obj-pub.hppa-unknown-linux-gnu.h \ syscfg/lock-obj-pub.i386-apple-darwin.h \ syscfg/lock-obj-pub.i686-pc-gnu.h \ diff --git a/src/mkheader.c b/src/mkheader.c index 64d0904..5aeb1e7 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -81,9 +81,16 @@ canon_host_triplet (const char *triplet) {"i586-pc-gnu"}, {"i486-pc-kfreebsd-gnu", "i686-pc-kfreebsd-gnu"}, {"i586-pc-kfreebsd-gnu"}, + {"x86_64-pc-linux-gnuhardened1", "x86_64-pc-linux-gnu" }, + {"powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-gnu" }, + {"arm-unknown-linux-gnueabihf", "arm-unknown-linux-gnueabi" }, + {"armv7-unknown-linux-gnueabihf" }, + {"armv5-unknown-linux-musleabi" }, + {"armv6-unknown-linux-musleabihf" }, + { NULL } }; int i; diff --git a/src/syscfg/lock-obj-pub.arm-unknown-linux-gnueabihf.h b/src/syscfg/lock-obj-pub.arm-unknown-linux-gnueabihf.h deleted file mode 100644 index 6636400..0000000 --- a/src/syscfg/lock-obj-pub.arm-unknown-linux-gnueabihf.h +++ /dev/null @@ -1,23 +0,0 @@ -## lock-obj-pub.arm-unknown-linux-gnueabihf.h -## File created by gen-posix-lock-obj - DO NOT EDIT -## To be included by mkheader into gpg-error.h - -typedef struct -{ - long _vers; - union { - volatile char _priv[24]; - long _x_align; - long *_xp_align; - } u; -} gpgrt_lock_t; - -#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ - 0,0,0,0,0,0,0,0, \ - 0,0,0,0,0,0,0,0}}} -## -## Local Variables: -## mode: c -## buffer-read-only: t -## End: -## diff --git a/src/syscfg/lock-obj-pub.armv5-unknown-linux-musleabi.h b/src/syscfg/lock-obj-pub.armv5-unknown-linux-musleabi.h deleted file mode 100644 index c7b6165..0000000 --- a/src/syscfg/lock-obj-pub.armv5-unknown-linux-musleabi.h +++ /dev/null @@ -1,23 +0,0 @@ -## lock-obj-pub.armv5-unknown-linux-musleabi.h -## File created by gen-posix-lock-obj - DO NOT EDIT -## To be included by mkheader into gpg-error.h - -typedef struct -{ - long _vers; - union { - volatile char _priv[24]; - long _x_align; - long *_xp_align; - } u; -} gpgrt_lock_t; - -#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ - 0,0,0,0,0,0,0,0, \ - 0,0,0,0,0,0,0,0}}} -## -## Local Variables: -## mode: c -## buffer-read-only: t -## End: -## diff --git a/src/syscfg/lock-obj-pub.armv6-unknown-linux-musleabihf.h b/src/syscfg/lock-obj-pub.armv6-unknown-linux-musleabihf.h deleted file mode 100644 index 6535a9b..0000000 --- a/src/syscfg/lock-obj-pub.armv6-unknown-linux-musleabihf.h +++ /dev/null @@ -1,23 +0,0 @@ -## lock-obj-pub.armv6-unknown-linux-musleabihf.h -## File created by gen-posix-lock-obj - DO NOT EDIT -## To be included by mkheader into gpg-error.h - -typedef struct -{ - long _vers; - union { - volatile char _priv[24]; - long _x_align; - long *_xp_align; - } u; -} gpgrt_lock_t; - -#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ - 0,0,0,0,0,0,0,0, \ - 0,0,0,0,0,0,0,0}}} -## -## Local Variables: -## mode: c -## buffer-read-only: t -## End: -## ----------------------------------------------------------------------- Summary of changes: AUTHORS | 2 +- NEWS | 22 ++++- configure.ac | 6 +- po/cs.po | 65 +++++++++++- po/da.po | 65 +++++++++++- po/eo.po | 65 +++++++++++- po/fr.po | 65 +++++++++++- po/hu.po | 65 +++++++++++- po/it.po | 65 +++++++++++- po/ja.po | 109 ++++++++++++++++++++- po/nl.po | 65 +++++++++++- po/pl.po | 60 ++++++++++++ po/pt.po | 65 +++++++++++- po/ro.po | 64 +++++++++++- po/ru.po | 60 ++++++++++++ po/sr.po | 65 +++++++++++- po/sv.po | 64 +++++++++++- po/uk.po | 65 +++++++++++- po/vi.po | 64 +++++++++++- po/zh_CN.po | 62 +++++++++++- po/zh_TW.po | 65 +++++++++++- src/Makefile.am | 3 - src/gpg-error.h.in | 2 +- src/mkheader.c | 7 ++ .../lock-obj-pub.arm-unknown-linux-gnueabihf.h | 23 ----- .../lock-obj-pub.armv5-unknown-linux-musleabi.h | 23 ----- .../lock-obj-pub.armv6-unknown-linux-musleabihf.h | 23 ----- src/version.c | 2 +- src/versioninfo.rc.in | 2 +- 29 files changed, 1152 insertions(+), 161 deletions(-) delete mode 100644 src/syscfg/lock-obj-pub.arm-unknown-linux-gnueabihf.h delete mode 100644 src/syscfg/lock-obj-pub.armv5-unknown-linux-musleabi.h delete mode 100644 src/syscfg/lock-obj-pub.armv6-unknown-linux-musleabihf.h hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 15:28:48 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 28 Feb 2017 15:28:48 +0100 Subject: [git] gnupg-doc - branch, master, updated. 2adb2557b87eb05afe307c2acd6a245501f26f87 Message-ID: This is an 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 2adb2557b87eb05afe307c2acd6a245501f26f87 (commit) from c47eef0711fad9e4c6b3c23cf51ec65333f9acb9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2adb2557b87eb05afe307c2acd6a245501f26f87 Author: Werner Koch Date: Tue Feb 28 15:25:17 2017 +0100 swdb: Release libgpg-error 1.27 diff --git a/web/swdb.mac b/web/swdb.mac index af010dc..15877d3 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -110,11 +110,11 @@ # # LIBGPG-ERROR # -#+macro: libgpg_error_ver 1.26 -#+macro: libgpg_error_date 2016-12-21 -#+macro: libgpg_error_size 779k -#+macro: libgpg_error_sha1 9a926e7ee6309e539313443555535d49a2a5c9f1 -#+macro: libgpg_error_sha2 4c4bcbc90116932e3acd37b37812d8653b1b189c1904985898e860af818aee69 +#+macro: libgpg_error_ver 1.27 +#+macro: libgpg_error_date 2017-02-28 +#+macro: libgpg_error_size 794k +#+macro: libgpg_error_sha1 a428758999ff573e62d06892e3d2c0b0f335787c +#+macro: libgpg_error_sha2 4f93aac6fecb7da2b92871bb9ee33032be6a87b174f54abf8ddf0911a22d29d2 # @@ -128,6 +128,16 @@ # +# NTBTLS +# +#+macro: ntbtls_ver 0.1.0 +#+macro: ntbtls_date 2017-02-21 +#+macro: ntbtls_size 331k +#+macro: ntbtls_sha1 33cce3941e321b97f65b5e1f11b13fb25fb387b9 +#+macro: ntbtls_sha2 a9f99ba3af13e0b83818ce9581ebf7f82563ba30c418de37f1c53e85de1876ce + + +# # nPth # #+macro: npth_ver 1.3 ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 16:44:47 2017 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Tue, 28 Feb 2017 16:44:47 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-149-ge4583ae Message-ID: This is an 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 e4583ae14e52482ab390c102d071755f91ab211d (commit) via 058c97f9fc485405246b1adfcc905c1891550652 (commit) from d379a0174cca595204b32da9a66c513a1304e6d0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e4583ae14e52482ab390c102d071755f91ab211d Author: Justus Winter Date: Tue Feb 28 16:19:18 2017 +0100 gpgscm: Improve parsing. * tests/gpgscm/scheme.c (port_increment_current_line): Avoid creating the same integer if the delta is zero. This happens a lot during parsing, and puts pressure on the memory allocator. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index 0453754..b2ff721 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -1735,6 +1735,9 @@ port_clear_location (scheme *sc, port *p) static void port_increment_current_line (scheme *sc, port *p, long delta) { + if (delta == 0) + return; + p->curr_line = mk_integer(sc, ivalue_unchecked(p->curr_line) + delta); } commit 058c97f9fc485405246b1adfcc905c1891550652 Author: Justus Winter Date: Tue Feb 28 16:17:33 2017 +0100 gpgscm: Fix calculating the line number. * tests/gpgscm/scheme.c (opexe_5): Only increment the line number on newlines. Fixes-commit: 7cc57e2c63d0fa97569736419db5c76117e7685b Signed-off-by: Justus Winter diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index 405dee4..0453754 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -5045,8 +5045,8 @@ static pointer opexe_5(scheme *sc, enum scheme_opcodes op) { int c = inchar(sc); if (c != '\n') backchar(sc,c); - port_increment_current_line(sc, - &sc->load_stack[sc->file_i], 1); + else + port_increment_current_line(sc, &sc->load_stack[sc->file_i], 1); sc->nesting_stack[sc->file_i]--; s_return(sc,reverse_in_place(sc, sc->NIL, sc->args)); } else if (sc->tok == TOK_DOT) { ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/scheme.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 28 20:39:41 2017 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 28 Feb 2017 20:39:41 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.18-150-ge182542 Message-ID: This is an 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 e182542e90cbeff4f2ac6c8d71061356d7cdcdea (commit) from e4583ae14e52482ab390c102d071755f91ab211d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e182542e90cbeff4f2ac6c8d71061356d7cdcdea Author: Werner Koch Date: Tue Feb 28 20:28:56 2017 +0100 gpg: Do not require a trustdb for decryption. * g10/trustdb.c (init_trustdb): Add and implement arg NO_CREATE. Change to return an error code. Change all callers to to pass False for NO_CREATE. (tdb_get_ownertrust): New arg NO_CREATE. Call init_trustdb to test for a non-existing trustdb. Change all callers to to pass False for NO_CREATE. (tdb_get_min_ownertrust): Ditto. * g10/trust.c (get_ownertrust_with_min): Add arg NO_CREATE. Call init_trustdb for a quick check. (get_ownertrust_info): Add arg NO_CREATE. (get_ownertrust_string): Ditto. * g10/gpgv.c (get_ownertrust_info): Adjust stub. * g10/test-stubs.c (get_ownertrust_info): Ditto. * g10/mainproc.c (list_node): Call get_ownertrust_info with NO_CREATE set. * g10/pubkey-enc.c (get_it): Ditto. -- Fixes-commit: effa80e0b5fd8cf9e31a984afe391c2406edee8b For details see mails on Feb 27 and 28 by dkg, gniibe, and Justus to gnupg-devel 'test failure on git master with decrypt-session-key.scm (and: continuous integration?)' Signed-off-by: Werner Koch diff --git a/g10/gpgv.c b/g10/gpgv.c index ef8d9e0..a6d1add 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -371,9 +371,10 @@ uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid) } int -get_ownertrust_info (PKT_public_key *pk) +get_ownertrust_info (PKT_public_key *pk, int no_create) { (void)pk; + (void)no_create; return '?'; } diff --git a/g10/keyedit.c b/g10/keyedit.c index ab66d01..892da1a 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3679,7 +3679,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock) (ulong) pk->timestamp, (ulong) pk->expiredate); if (node->pkt->pkttype == PKT_PUBLIC_KEY && !(opt.fast_list_mode || opt.no_expensive_trust_checks)) - es_putc (get_ownertrust_info (pk), fp); + es_putc (get_ownertrust_info (pk, 0), fp); es_putc (':', fp); es_putc (':', fp); es_putc (':', fp); @@ -3896,7 +3896,7 @@ show_key_with_all_names (ctrl_t ctrl, estream_t fp, static int did_warn = 0; trust = get_validity_string (ctrl, pk, NULL); - otrust = get_ownertrust_string (pk); + otrust = get_ownertrust_string (pk, 0); /* Show a warning once */ if (!did_warn diff --git a/g10/keylist.c b/g10/keylist.c index abdcb9f..2684f59 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1232,7 +1232,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, } if (!opt.fast_list_mode && !opt.no_expensive_trust_checks) - ownertrust_print = get_ownertrust_info (pk); + ownertrust_print = get_ownertrust_info (pk, 0); else ownertrust_print = 0; diff --git a/g10/mainproc.c b/g10/mainproc.c index 8e29891..4f8d0be 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1032,7 +1032,7 @@ list_node (CTX c, kbnode_t node) colon_datestr_from_pk( pk ), colon_strtime (pk->expiredate) ); if (pk->flags.primary && !opt.fast_list_mode) - es_putc (get_ownertrust_info (pk), es_stdout); + es_putc (get_ownertrust_info (pk, 1), es_stdout); es_putc (':', es_stdout); es_putc ('\n', es_stdout); } diff --git a/g10/pkclist.c b/g10/pkclist.c index 4991d20..012f751 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -188,7 +188,7 @@ do_edit_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int mode, int show=0; int min_num; int did_help=defer_help; - unsigned int minimum = tdb_get_min_ownertrust (pk); + unsigned int minimum = tdb_get_min_ownertrust (pk, 0); switch(minimum) { diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 1772936..e037c12 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -404,8 +404,13 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) hexfingerprint (pk, pkhex, sizeof pkhex); hexfingerprint (mainpk, mainpkhex, sizeof mainpkhex); + /* Note that we do not want to create a trustdb just for + * getting the ownertrust: If there is no trustdb there can't + * be ulitmately trusted key anyway and thus the ownertrust + * value is irrelevant. */ write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c", - pkhex, mainpkhex, get_ownertrust_info (mainpk)); + pkhex, mainpkhex, + get_ownertrust_info (mainpk, 1)); } diff --git a/g10/tdbdump.c b/g10/tdbdump.c index be9d1f2..ab2f072 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -70,7 +70,7 @@ list_trustdb (estream_t fp, const char *username) (void)username; - init_trustdb(); + init_trustdb (0); /* For now we ignore the user ID. */ if (1) { @@ -101,7 +101,7 @@ export_ownertrust() int i; byte *p; - init_trustdb(); + init_trustdb (0); es_printf (_("# List of assigned trustvalues, created %s\n" "# (Use \"gpg --import-ownertrust\" to restore them)\n"), asctimestamp( make_timestamp() ) ); @@ -133,7 +133,7 @@ import_ownertrust( const char *fname ) int any = 0; int rc; - init_trustdb(); + init_trustdb (0); if( iobuf_is_pipe_filename (fname) ) { fp = es_stdin; fname = "[stdin]"; diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 8752f88..a74df20 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -138,9 +138,10 @@ uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid) } int -get_ownertrust_info (PKT_public_key *pk) +get_ownertrust_info (PKT_public_key *pk, int no_create) { (void)pk; + (void)no_create; return '?'; } diff --git a/g10/trust.c b/g10/trust.c index b1fa3d6..d0ea77e 100644 --- a/g10/trust.c +++ b/g10/trust.c @@ -179,17 +179,18 @@ get_ownertrust (PKT_public_key *pk) (void)pk; return TRUST_UNKNOWN; #else - return tdb_get_ownertrust (pk); + return tdb_get_ownertrust (pk, 0); #endif } /* * Same as get_ownertrust but this takes the minimum ownertrust value - * into account, and will bump up the value as needed. + * into account, and will bump up the value as needed. NO_CREATE + * inhibits creation of a trustdb it that does not yet exists. */ static int -get_ownertrust_with_min (PKT_public_key *pk) +get_ownertrust_with_min (PKT_public_key *pk, int no_create) { #ifdef NO_TRUST_MODELS (void)pk; @@ -197,8 +198,15 @@ get_ownertrust_with_min (PKT_public_key *pk) #else unsigned int otrust, otrust_min; - otrust = (tdb_get_ownertrust (pk) & TRUST_MASK); - otrust_min = tdb_get_min_ownertrust (pk); + /* Shortcut instead of doing the same twice in the two tdb_get + * functions: If the caller asked not to create a trustdb we call + * init_trustdb directly and allow it to fail with an error code for + * a non-existing trustdb. */ + if (no_create && init_trustdb (1)) + return TRUST_UNKNOWN; + + otrust = (tdb_get_ownertrust (pk, no_create) & TRUST_MASK); + otrust_min = tdb_get_min_ownertrust (pk, no_create); if (otrust < otrust_min) { /* If the trust that the user has set is less than the trust @@ -217,23 +225,25 @@ get_ownertrust_with_min (PKT_public_key *pk) /* * Same as get_ownertrust but return a trust letter instead of an - * value. This takes the minimum ownertrust value into account. + * value. This takes the minimum ownertrust value into account. If + * NO_CREATE is set, no efforts for creating a trustdb will be taken. */ int -get_ownertrust_info (PKT_public_key *pk) +get_ownertrust_info (PKT_public_key *pk, int no_create) { - return trust_letter (get_ownertrust_with_min (pk)); + return trust_letter (get_ownertrust_with_min (pk, no_create)); } /* * Same as get_ownertrust but return a trust string instead of an - * value. This takes the minimum ownertrust value into account. + * value. This takes the minimum ownertrust value into account. If + * NO_CREATE is set, no efforts for creating a trustdb will be taken. */ const char * -get_ownertrust_string (PKT_public_key *pk) +get_ownertrust_string (PKT_public_key *pk, int no_create) { - return trust_value_to_string (get_ownertrust_with_min (pk)); + return trust_value_to_string (get_ownertrust_with_min (pk, no_create)); } diff --git a/g10/trustdb.c b/g10/trustdb.c index 5f68012..f4df4c8 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -296,9 +296,9 @@ verify_own_keys(void) keystr(k->kid)); else { - tdb_update_ownertrust (&pk, - ((tdb_get_ownertrust (&pk) & ~TRUST_MASK) - | TRUST_ULTIMATE )); + tdb_update_ownertrust + (&pk, ((tdb_get_ownertrust (&pk, 0) & ~TRUST_MASK) + | TRUST_ULTIMATE )); release_public_key_parts (&pk); } @@ -439,21 +439,34 @@ how_to_fix_the_trustdb () } -void -init_trustdb () +/* Initialize the trustdb. With NO_CREATE set a missing trustdb is + * not an error and the function won't terminate the process on error; + * in that case 0 is returned if there is a trustdb or an error code + * if no trustdb is available. */ +gpg_error_t +init_trustdb (int no_create) { int level = trustdb_args.level; const char* dbname = trustdb_args.dbname; if( trustdb_args.init ) - return; + return 0; trustdb_args.init = 1; if(level==0 || level==1) { - int rc = tdbio_set_dbname( dbname, !!level, &trustdb_args.no_trustdb); - if( rc ) + int rc = tdbio_set_dbname (dbname, (!no_create && level), + &trustdb_args.no_trustdb); + if (no_create && trustdb_args.no_trustdb) + { + /* No trustdb found and the caller asked us not to create + * it. Return an error and set the initialization state + * back so that we always test for an existing trustdb. */ + trustdb_args.init = 0; + return gpg_error (GPG_ERR_ENOENT); + } + if (rc) log_fatal("can't init trustdb: %s\n", gpg_strerror (rc) ); } else @@ -493,6 +506,8 @@ init_trustdb () if(!tdbio_db_matches_options()) pending_check_trustdb=1; } + + return 0; } @@ -504,7 +519,7 @@ init_trustdb () void check_trustdb (ctrl_t ctrl) { - init_trustdb(); + init_trustdb (0); if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC || opt.trust_model == TM_TOFU_PGP || opt.trust_model == TM_TOFU) { @@ -541,7 +556,7 @@ check_trustdb (ctrl_t ctrl) void update_trustdb (ctrl_t ctrl) { - init_trustdb (); + init_trustdb (0); if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC || opt.trust_model == TM_TOFU_PGP || opt.trust_model == TM_TOFU) validate_keys (ctrl, 1); @@ -553,7 +568,7 @@ update_trustdb (ctrl_t ctrl) void tdb_revalidation_mark (void) { - init_trustdb(); + init_trustdb (0); if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) return; @@ -591,7 +606,7 @@ read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck, { TRUSTREC opts; - init_trustdb(); + init_trustdb (0); if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) memset (&opts, 0, sizeof opts); else @@ -622,7 +637,7 @@ read_trust_record (PKT_public_key *pk, TRUSTREC *rec) { int rc; - init_trustdb(); + init_trustdb (0); rc = tdbio_search_trust_bypk (pk, rec); if (rc) { @@ -642,12 +657,16 @@ read_trust_record (PKT_public_key *pk, TRUSTREC *rec) return 0; } -/**************** - * Return the assigned ownertrust value for the given public key. - * The key should be the primary key. + +/* + * Return the assigned ownertrust value for the given public key. The + * key should be the primary key. If NO_CREATE is set a missing + * trustdb will not be created. This comes for example handy when we + * want to print status lines (DECRYPTION_KEY) which carry ownertrust + * values but we usually use --always-trust. */ unsigned int -tdb_get_ownertrust ( PKT_public_key *pk) +tdb_get_ownertrust (PKT_public_key *pk, int no_create) { TRUSTREC rec; gpg_error_t err; @@ -655,6 +674,12 @@ tdb_get_ownertrust ( PKT_public_key *pk) if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) return TRUST_UNKNOWN; + /* If the caller asked not to create a trustdb we call init_trustdb + * directly and allow it to fail with an error code for a + * non-existing trustdb. */ + if (no_create && init_trustdb (1)) + return TRUST_UNKNOWN; + err = read_trust_record (pk, &rec); if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) return TRUST_UNKNOWN; /* no record yet */ @@ -669,7 +694,7 @@ tdb_get_ownertrust ( PKT_public_key *pk) unsigned int -tdb_get_min_ownertrust (PKT_public_key *pk) +tdb_get_min_ownertrust (PKT_public_key *pk, int no_create) { TRUSTREC rec; gpg_error_t err; @@ -677,6 +702,12 @@ tdb_get_min_ownertrust (PKT_public_key *pk) if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) return TRUST_UNKNOWN; + /* If the caller asked not to create a trustdb we call init_trustdb + * directly and allow it to fail with an error code for a + * non-existing trustdb. */ + if (no_create && init_trustdb (1)) + return TRUST_UNKNOWN; + err = read_trust_record (pk, &rec); if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) return TRUST_UNKNOWN; /* no record yet */ @@ -808,7 +839,7 @@ tdb_clear_ownertrusts (PKT_public_key *pk) TRUSTREC rec; gpg_error_t err; - init_trustdb (); + init_trustdb (0); if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) return 0; @@ -915,7 +946,7 @@ tdb_cache_disabled_value (PKT_public_key *pk) if (pk->flags.disabled_valid) return pk->flags.disabled; - init_trustdb(); + init_trustdb (0); if (trustdb_args.no_trustdb) return 0; /* No trustdb => not disabled. */ @@ -950,7 +981,7 @@ tdb_check_trustdb_stale (ctrl_t ctrl) { static int did_nextcheck=0; - init_trustdb (); + init_trustdb (0); if (trustdb_args.no_trustdb) return; /* No trustdb => can't be stale. */ @@ -1021,7 +1052,7 @@ tdb_get_validity_core (ctrl_t ctrl, (void)may_ask; #endif - init_trustdb (); + init_trustdb (0); /* If we have no trustdb (which also means it has not been created) and the trust-model is always, we don't know the validity - @@ -1036,7 +1067,7 @@ tdb_get_validity_core (ctrl_t ctrl, { /* Note that this happens BEFORE any user ID stuff is checked. The direct trust model applies to keys as a whole. */ - validity = tdb_get_ownertrust (main_pk); + validity = tdb_get_ownertrust (main_pk, 0); goto leave; } @@ -1248,7 +1279,7 @@ get_validity_counts (PKT_public_key *pk, PKT_user_id *uid) uid->help_marginal_count=uid->help_full_count=0; - init_trustdb (); + init_trustdb (0); if(read_trust_record (pk, &trec)) return; @@ -1353,7 +1384,7 @@ ask_ownertrust (ctrl_t ctrl, u32 *kid, int minimum) { ot=edit_ownertrust (ctrl, pk, 0); if(ot>0) - ot = tdb_get_ownertrust (pk); + ot = tdb_get_ownertrust (pk, 0); else if(ot==0) ot = minimum?minimum:TRUST_UNDEFINED; else @@ -2142,9 +2173,9 @@ validate_keys (ctrl_t ctrl, int interactive) k->kid[1]=kid[1]; k->ownertrust = (tdb_get_ownertrust - (kar->keyblock->pkt->pkt.public_key) & TRUST_MASK); + (kar->keyblock->pkt->pkt.public_key, 0) & TRUST_MASK); k->min_ownertrust = tdb_get_min_ownertrust - (kar->keyblock->pkt->pkt.public_key); + (kar->keyblock->pkt->pkt.public_key, 0); k->trust_depth= kar->keyblock->pkt->pkt.public_key->trust_depth; k->trust_value= diff --git a/g10/trustdb.h b/g10/trustdb.h index 6081d10..3088063 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -127,7 +127,7 @@ void update_trustdb (ctrl_t ctrl); int setup_trustdb( int level, const char *dbname ); void how_to_fix_the_trustdb (void); const char *trust_model_string (int model); -void init_trustdb( void ); +gpg_error_t init_trustdb (int no_create); void tdb_check_trustdb_stale (ctrl_t ctrl); void sync_trustdb( void ); @@ -152,10 +152,10 @@ void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck, byte *marginals,byte *completes,byte *cert_depth, byte *min_cert_level); -unsigned int tdb_get_ownertrust (PKT_public_key *pk); -unsigned int tdb_get_min_ownertrust (PKT_public_key *pk); -int get_ownertrust_info (PKT_public_key *pk); -const char *get_ownertrust_string (PKT_public_key *pk); +unsigned int tdb_get_ownertrust (PKT_public_key *pk, int no_create); +unsigned int tdb_get_min_ownertrust (PKT_public_key *pk, int no_create); +int get_ownertrust_info (PKT_public_key *pk, int no_create); +const char *get_ownertrust_string (PKT_public_key *pk, int no_create); void tdb_update_ownertrust (PKT_public_key *pk, unsigned int new_trust); int tdb_clear_ownertrusts (PKT_public_key *pk); ----------------------------------------------------------------------- Summary of changes: g10/gpgv.c | 3 +- g10/keyedit.c | 4 +-- g10/keylist.c | 2 +- g10/mainproc.c | 2 +- g10/pkclist.c | 2 +- g10/pubkey-enc.c | 7 ++++- g10/tdbdump.c | 6 ++-- g10/test-stubs.c | 3 +- g10/trust.c | 32 +++++++++++++-------- g10/trustdb.c | 85 ++++++++++++++++++++++++++++++++++++++------------------ g10/trustdb.h | 10 +++---- 11 files changed, 102 insertions(+), 54 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org