diff options
author | Werner Koch <[email protected]> | 2025-06-02 10:42:59 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2025-06-02 10:42:59 +0000 |
commit | e6463d7fe097b39c9e8952ef9f5758fa0ee0e4bd (patch) | |
tree | 38222b8338276d8de0b92130dd43b003ec46754c | |
parent | gpg-mail-tube: Support templates. (diff) | |
download | gnupg-e6463d7fe097b39c9e8952ef9f5758fa0ee0e4bd.tar.gz gnupg-e6463d7fe097b39c9e8952ef9f5758fa0ee0e4bd.zip |
wks: Use templates for the server responses.
* common/helpfile.c (gnupg_get_template): Add arg locale_override and
adjust all callers.
* tools/wks-receive.c (struct receive_ctx_s): Add field ct_language.
(get_language): New.
(new_part): Call it.
(wks_receive): Pass language to the result callback.
* tools/gpg-wks-client.c (short_locale): New.
(main): Get and store the current locale.
(command_create): Fix a glitch for the Posteo hack. Insert the locale
into the confirmation request.
(send_confirmation_response): Ditto.
* tools/gpg-wks-server.c (struct server_ctx_s): Add field language.
(only_ascii): New.
(struct my_subst_vars_s, my_subst_vars_cb, my_subst_vars): New.
(send_confirmation_request): Use a template.
(send_congratulation_message): Ditto.
(check_and_publish): Pss ctx to send_congratulation_message.
(command_receive_cb): Add arg language.
* doc/wks-utils.txt, doc/wks-utils.de.txt: New.
* doc/Makefile.am (helpfiles): Add them.
--
GnuPG-bug-id: 7381
Note that the subject is not yet translated or templated due to a
missing header encoding function.
-rw-r--r-- | common/helpfile.c | 22 | ||||
-rw-r--r-- | common/t-helpfile.c | 2 | ||||
-rw-r--r-- | common/util.h | 2 | ||||
-rw-r--r-- | doc/Makefile.am | 3 | ||||
-rw-r--r-- | doc/wks-utils.de.txt | 73 | ||||
-rw-r--r-- | doc/wks-utils.txt | 71 | ||||
-rw-r--r-- | doc/wks.texi | 9 | ||||
-rw-r--r-- | tools/gpg-mail-tube.c | 5 | ||||
-rw-r--r-- | tools/gpg-wks-client.c | 70 | ||||
-rw-r--r-- | tools/gpg-wks-server.c | 184 | ||||
-rw-r--r-- | tools/gpg-wks.h | 1 | ||||
-rw-r--r-- | tools/wks-receive.c | 39 |
12 files changed, 406 insertions, 75 deletions
diff --git a/common/helpfile.c b/common/helpfile.c index 956ec2516..240562794 100644 --- a/common/helpfile.c +++ b/common/helpfile.c @@ -234,21 +234,25 @@ findkey_locale (const char *domain, const char *key, const char *locname, intervening lines (except for comment lines) lead to the same help text. Lines following the key lines make up the actual template texts. */ - char * -gnupg_get_template (const char *domain, const char *key, unsigned int flags) +gnupg_get_template (const char *domain, const char *key, unsigned int flags, + const char *override_locale) { - static const char *locname; + static const char *locname_buffer; + const char *locname; char *result; - if (!locname) + if (override_locale && *override_locale) + locname = override_locale; + else if (!locname_buffer) { char *buffer, *p; int count = 0; const char *s = gnupg_messages_locale_name (); + buffer = xtrystrdup (s); if (!buffer) - locname = ""; + locname_buffer = ""; else { for (p = buffer; *p; p++) @@ -259,9 +263,12 @@ gnupg_get_template (const char *domain, const char *key, unsigned int flags) if (count++) *p = 0; /* Also cut at an underscore in the territory. */ } - locname = buffer; + locname_buffer = buffer; } + locname = locname_buffer; } + else + locname = locname_buffer; if (!key || !*key) return NULL; @@ -293,5 +300,6 @@ char * gnupg_get_help_string (const char *key, int only_current) { return gnupg_get_template ("help", key, - only_current? GET_TEMPLATE_CURRENT_LOCALE : 0); + only_current? GET_TEMPLATE_CURRENT_LOCALE : 0, + NULL); } diff --git a/common/t-helpfile.c b/common/t-helpfile.c index adb69ba2d..d1e7f547d 100644 --- a/common/t-helpfile.c +++ b/common/t-helpfile.c @@ -66,7 +66,7 @@ main (int argc, char **argv) } - result = gnupg_get_template (argv[0], argv[1], flags); + result = gnupg_get_template (argv[0], argv[1], flags, NULL); if (!result) { fprintf (stderr, diff --git a/common/util.h b/common/util.h index ce1dc37d8..b81664c3e 100644 --- a/common/util.h +++ b/common/util.h @@ -303,7 +303,7 @@ void gnupg_rl_initialize (void); #define GET_TEMPLATE_CRLF 4 /* Use CR+LF. */ char *gnupg_get_template (const char *domain, const char *key, - unsigned int flags); + unsigned int flags, const char *override_locale); char *gnupg_get_help_string (const char *key, int only_current_locale); /*-- localename.c --*/ diff --git a/doc/Makefile.am b/doc/Makefile.am index 6d52de830..1e4c6fb64 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -34,7 +34,8 @@ helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt \ help.ja.txt help.nb.txt help.pl.txt help.pt.txt \ help.pt_BR.txt help.ro.txt help.ru.txt help.sk.txt \ help.sv.txt help.tr.txt help.zh_CN.txt help.zh_TW.txt \ - mail-tube.txt mail-tube.de.txt + mail-tube.txt mail-tube.de.txt \ + wks-utils.txt wks-utils.de.txt EXTRA_DIST = samplekeys.asc mksamplekeys com-certs.pem \ gnupg-logo.pdf gnupg-logo.png gnupg-logo-tr.png \ diff --git a/doc/wks-utils.de.txt b/doc/wks-utils.de.txt new file mode 100644 index 000000000..02f768476 --- /dev/null +++ b/doc/wks-utils.de.txt @@ -0,0 +1,73 @@ +# wks-utils.txt - gpg-wks-server/-client strings (de) -*- default-generic -*- +# Written in 2025 by g10 Code GmbH +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this text to the +# public domain worldwide. This text is distributed without any +# warranty. You should have received a copy of the CC0 Public Domain +# Dedication along with this software. If not, see +# <https://creativecommons.org/publicdomain/zero/1.0/>. +# SPDX-License-Identifier: CC0-1.0 +# +# Note that this template file needs to be UTF-8 encoded. When looking +# for a template item, GnuPG scans the help files in the following order +# (assuming a standard Unix layout): +# +# /etc/gnupg/TEMPLATE.LL_TT.txt +# /etc/gnupg/TEMPLATE.LL.txt +# /etc/gnupg/TEMPLATE.txt +# /usr/share/gnupg/TEMPLATE.LL_TT.txt +# /usr/share/gnupg/TEMPLATE.LL.txt +# /usr/share/gnupg/TEMPLATE.txt +# +# Here TEMPLATE denotes the name of the template (e.g. "mail-tube"), +# LL_TT denotes the full name of the current locale with the territory +# (.e.g. "de_DE"), LL denotes just the locale name (e.g. "de"). The +# first matching item is returned. To put a dot or a hash mark at the +# beginning of a text line, it needs to be prefixed with a dot and a +# space. A single dot may be used to terminated an entry. Depending +# on the template type certain variables (${NAME}) are expanded. +# Check the man page of the respective tool. + +.server.confirm.body + +Diese Nachricht wurde auf Ihre Anforderung gesendet, Ihren Schlüssel +zu veröffentlichen. Falls Sie solch eine Anforderung nicht gesendet +haben, so ignorieren Sie bitte diese Nachricht. + +[English: This message has been send to confirm your request + to publish your key. If you did not request a key + publication, simply ignore this message.] + +Viele Mail Software ist in der Lage diese Art von Nachrichten +automatisch zu verarbeiten. In diesem Fall sollten Sie diesen Text +auch nicht sehen. Falls doch so ist Ihre Mailsoftware veraltet und +kann mit dieser Nachricht nichts anfangen. Unter + + https://gnupg.org/faq/wkd.html + +finden Sie eine Erklärung, wie Sie solche Nachrichten anderweitig +verarbeiten können. + + +${sigdelim} +Weitere Informationen zu GnuPG finden Sie hier: https://gnupg.org + +. + +.server.publish.congrats +Hallo! + +Der Schlüssel für Ihre Mailadresse '${address}' wurde soeben vom +Web Key Directory akzeptiert. Je nach Konfiguration Ihres Providers kann +es bis zu 15 Minuten dauern, bis er öffentlich sichtbar wird. + +Viele Grüße von Ihrem + + Schlüsselveröffentlichungsdienst + + +${sigdelim} +Weitere Informationen zu GnuPG finden Sie hier: https://gnupg.org + +. diff --git a/doc/wks-utils.txt b/doc/wks-utils.txt new file mode 100644 index 000000000..012e46da6 --- /dev/null +++ b/doc/wks-utils.txt @@ -0,0 +1,71 @@ +# wks-utils.txt - gpg-wks-server/-client strings (en) -*- default-generic -*- +# Written in 2025 by g10 Code GmbH +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this text to the +# public domain worldwide. This text is distributed without any +# warranty. You should have received a copy of the CC0 Public Domain +# Dedication along with this software. If not, see +# <https://creativecommons.org/publicdomain/zero/1.0/>. +# SPDX-License-Identifier: CC0-1.0 +# +# Note that this template file needs to be UTF-8 encoded. When looking +# for a template item, GnuPG scans the help files in the following order +# (assuming a standard Unix layout): +# +# /etc/gnupg/TEMPLATE.LL_TT.txt +# /etc/gnupg/TEMPLATE.LL.txt +# /etc/gnupg/TEMPLATE.txt +# /usr/share/gnupg/TEMPLATE.LL_TT.txt +# /usr/share/gnupg/TEMPLATE.LL.txt +# /usr/share/gnupg/TEMPLATE.txt +# +# Here TEMPLATE denotes the name of the template (e.g. "mail-tube"), +# LL_TT denotes the full name of the current locale with the territory +# (.e.g. "de_DE"), LL denotes just the locale name (e.g. "de"). The +# first matching item is returned. To put a dot or a hash mark at the +# beginning of a text line, it needs to be prefixed with a dot and a +# space. A single dot may be used to terminated an entry. Depending +# on the template type certain variables (${NAME}) are expanded. +# Check the man page of the respective tool. + +.server.confirm.body +This message has been send to confirm your request +to publish your key. If you did not request a key +publication, simply ignore this message. + +Most mail software can handle this kind of message +automatically and thus you would not have seen this +message. It seems that your client does not fully +support this service. The web page + + https://gnupg.org/faq/wkd.html + +explains how you can process this message anyway in +a few manual steps. + + +${sigdelim} +For information on GnuPG see: https://gnupg.org + +. + +.server.publish.congrats +Hello! + +The key for your address '${address}' has been published +and can now be retrieved from the Web Key Directory. + +For more information on this system see: + + https://gnupg.org/faq/wkd.html + +Best regards + + GnuPG Key Publisher + + +${sigdelim} +For information on GnuPG see: https://gnupg.org + +. diff --git a/doc/wks.texi b/doc/wks.texi index bfdd069f2..a47bdfa92 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -358,6 +358,15 @@ use option @option{-q}. The command @option{--revoke-key} is not yet functional. +This tool needs to insert strings into the mails which can be +configured using a plain text file. The installed default files for +English (@file{wks-utils.txt}) and German (@file{wks-utils.de.txt}) +can be copied to the system configuration directory and changed to +local needs. Environment variables in these texts are expanded, the +variable ``sigdelim'' is replaced by two dashes and a blank, the +variable ``address'' is replaced by the mail address of the key to be +published. + @mansect options @noindent diff --git a/tools/gpg-mail-tube.c b/tools/gpg-mail-tube.c index 7c3c6d0e3..c672651de 100644 --- a/tools/gpg-mail-tube.c +++ b/tools/gpg-mail-tube.c @@ -371,7 +371,7 @@ main (int argc, char **argv) } -/* Return true if TSRING has only ascii chacrterst or is NULL. */ +/* Return true if STRING has only ascii characters or is NULL. */ static int only_ascii (const char *string) { @@ -571,7 +571,8 @@ mail_tube_encrypt (estream_t fpin, strlist_t recipients) ct_is_text? "encrypted-file-attached" : "encrypted-mail-attached", (GET_TEMPLATE_SUBST_ENVVARS - | GET_TEMPLATE_CRLF)); + | GET_TEMPLATE_CRLF), + NULL); if (templ && !only_ascii (templ)) { charset = "utf-8"; diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index ef11a4e3e..2d037faef 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -155,6 +155,8 @@ const char *fake_submission_addr; static char **blacklist_array; static size_t blacklist_array_len; +/* The current locale in the short form (e.g. "de" instead of "de_DE") */ +static char *short_locale; static void wrong_args (const char *t1, const char *t2) GPGRT_ATTR_NORETURN; static void add_blacklist (const char *fname); @@ -168,7 +170,9 @@ static gpg_error_t encrypt_response (estream_t *r_output, estream_t input, const char *fingerprint); static gpg_error_t read_confirmation_request (estream_t msg); static gpg_error_t command_receive_cb (void *opaque, - const char *mediatype, estream_t fp, + const char *mediatype, + const char *language, + estream_t fp, unsigned int flags); static gpg_error_t command_mirror (char *domain[]); @@ -374,6 +378,20 @@ main (int argc, char **argv) !opt.no_autostart); + /* Get the short form of the current locale. */ + { + const char *locname = gnupg_messages_locale_name (); + char *p; + + if (locname && *locname && strcmp (locname, "C")) + { + short_locale = xstrdup (locname); + if ((p = strpbrk (short_locale, "_.@/"))) + *p = 0; + gpgrt_annotate_leaked_object (short_locale); + } + } + /* Check that the top directory exists. */ if (cmd == aInstallKey || cmd == aRemoveKey || cmd == aMirror) { @@ -1338,16 +1356,32 @@ command_create (const char *fingerprint, const char *userid) } } + /* Hack to support posteo but let them disable this by setting the + * new policy-version flag. */ + if (policy->protocol_version < 3 + && !ascii_strcasecmp (domain, "posteo.de")) + { + log_info ("Warning: Using draft-1 method for domain '%s'\n", domain); + no_encrypt = 1; + posteo_hack = 1; + } + /* Now put the armor around the key. */ { estream_t newkey; + char *prefix; + + prefix = xstrconcat + ("Content-Type: application/pgp-keys\n", + short_locale && *short_locale? "Content-Language: " : "", + short_locale && *short_locale? short_locale : "", + short_locale && *short_locale? "\n" : "", + "\n", NULL); es_rewind (key); - err = wks_armor_key (&newkey, key, - no_encrypt? NULL - /* */ : ("Content-Type: application/pgp-keys\n" - "\n")); + err = wks_armor_key (&newkey, key, no_encrypt? NULL : prefix); + xfree (prefix); if (err) { log_error ("error armoring key: %s\n", gpg_strerror (err)); @@ -1357,16 +1391,6 @@ command_create (const char *fingerprint, const char *userid) key = newkey; } - /* Hack to support posteo but let them disable this by setting the - * new policy-version flag. */ - if (policy->protocol_version < 3 - && !ascii_strcasecmp (domain, "posteo.de")) - { - log_info ("Warning: Using draft-1 method for domain '%s'\n", domain); - no_encrypt = 1; - posteo_hack = 1; - } - /* Encrypt the key part. */ if (!no_encrypt) { @@ -1415,8 +1439,10 @@ command_create (const char *fingerprint, const char *userid) goto leave; } - err = mime_maker_add_header (mime, "Content-type", + err = mime_maker_add_header (mime, "Content-Type", "application/pgp-keys"); + if (!err && short_locale && *short_locale) + err = mime_maker_add_header (mime, "Content-Language", short_locale); if (err) goto leave; @@ -1596,10 +1622,11 @@ send_confirmation_response (const char *sender, const char *address, * only our client will see it. */ if (encrypt) { - es_fputs ("Content-Type: application/vnd.gnupg.wks\n" - "Content-Transfer-Encoding: 8bit\n" - "\n", - body); + es_fprintf (body, + "Content-Type: application/vnd.gnupg.wks\n" + "Content-Transfer-Encoding: 8bit\n" + "Content-Language: %s\n" + "\n", (short_locale && *short_locale)? short_locale : "en"); } es_fprintf (body, ("type: confirmation-response\n" @@ -1858,12 +1885,13 @@ read_confirmation_request (estream_t msg) /* Called from the MIME receiver to process the plain text data in MSG. */ static gpg_error_t -command_receive_cb (void *opaque, const char *mediatype, +command_receive_cb (void *opaque, const char *mediatype, const char *language, estream_t msg, unsigned int flags) { gpg_error_t err; (void)opaque; + (void)language; (void)flags; if (!strcmp (mediatype, "application/vnd.gnupg.wks")) diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index 31de67618..0e216cec6 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -142,6 +142,7 @@ struct server_ctx_s { char *fpr; uidinfo_list_t mboxes; /* List with addr-specs taken from the UIDs. */ + char *language; /* Requested language. */ unsigned int draft_version_2:1; /* Client supports the draft 2. */ }; typedef struct server_ctx_s *server_ctx_t; @@ -157,7 +158,9 @@ static int opt_with_file; static gpg_error_t get_domain_list (strlist_t *r_list); static gpg_error_t command_receive_cb (void *opaque, - const char *mediatype, estream_t fp, + const char *mediatype, + const char *language, + estream_t fp, unsigned int flags); static gpg_error_t command_list_domains (void); static gpg_error_t command_revoke_key (const char *mailaddr); @@ -432,6 +435,54 @@ main (int argc, char **argv) } +/* Return true if STRING has only ascii characters or is NULL. */ +static int +only_ascii (const char *string) +{ + if (string) + for ( ; *string; string++) + if ((*string & 0x80)) + return 0; + return 1; +} + + +struct my_subst_vars_s +{ + const char *address; +}; + + +/* Helper for my_subst_vars. */ +static const char * +my_subst_vars_cb (void *cookie, const char *name) +{ + struct my_subst_vars_s *parm = cookie; + const char *s; + + if (name && !strcmp (name, "sigdelim")) + s = "-- "; + else if (name && !strcmp (name, "address")) + s = parm->address; + else /* Assume envvar. */ + s = getenv (name); + return s? s : ""; +} + + +/* Substitute all envvars in TEMPL and the var $address my the value + * of MBOX. Return a a new malloced string or NULL. */ +static char * +my_subst_vars (server_ctx_t ctx, const char *templ, const char *mbox) +{ + struct my_subst_vars_s parm; + + (void)ctx; + parm.address = mbox; + return substitute_vars (templ, my_subst_vars_cb, &parm); +} + + /* Take the key in KEYFILE and write it to OUTFILE in binary encoding. * If ADDRSPEC is given only matching user IDs are included in the * output. */ @@ -991,6 +1042,9 @@ send_confirmation_request (server_ctx_t ctx, char *from_buffer = NULL; const char *from; strlist_t sl; + char *templ = NULL; + char *p; + const char *cttype, *ctencode; from = from_buffer = get_submission_address (mbox); if (!from) @@ -1123,25 +1177,48 @@ send_confirmation_request (server_ctx_t ctx, goto leave; partid = mime_maker_get_partid (mime); - err = mime_maker_add_header (mime, "Content-Type", "text/plain"); + templ = gnupg_get_template ("wks-utils", "server.confirm.body", + 0, ctx->language); + if (templ) + { + p = my_subst_vars (ctx, templ, mbox); + xfree (templ); + templ = p; + } + + if (templ && !only_ascii (templ)) + { + cttype = "text/plain; charset=utf-8"; + ctencode = "quoted-printable"; + p = mime_maker_qp_encode (templ); + if (!p) + { + err = gpg_error_from_syserror (); + log_error ("QP encoding failed: %s\n", gpg_strerror (err)); + goto leave; + } + xfree (templ); + templ = p; + } + else + { + cttype = "text/plain"; + ctencode = NULL; + } + + err = mime_maker_add_header (mime, "Content-Type", cttype); + if (err) + goto leave; + if (ctencode) + err = mime_maker_add_header (mime, + "Content-Transfer-Encoding", ctencode); if (err) goto leave; - err = mime_maker_add_body - (mime, + err = mime_maker_add_body (mime, templ? templ : "This message has been send to confirm your request\n" "to publish your key. If you did not request a key\n" - "publication, simply ignore this message.\n" - "\n" - "Most mail software can handle this kind of message\n" - "automatically and thus you would not have seen this\n" - "message. It seems that your client does not fully\n" - "support this service. The web page\n" - "\n" - " https://gnupg.org/faq/wkd.html\n" - "\n" - "explains how you can process this message anyway in\n" - "a few manual steps.\n"); + "publication, simply ignore this message.\n"); if (err) goto leave; @@ -1180,6 +1257,7 @@ send_confirmation_request (server_ctx_t ctx, err = wks_send_mime (mime); leave: + xfree (templ); mime_maker_release (mime); es_fclose (signature); es_fclose (signeddata); @@ -1285,7 +1363,8 @@ process_new_key (server_ctx_t ctx, estream_t key) /* Send a message to tell the user at MBOX that their key has been * published. FNAME the name of the file with the key. */ static gpg_error_t -send_congratulation_message (const char *mbox, const char *keyfile) +send_congratulation_message (server_ctx_t ctx, + const char *mbox, const char *keyfile) { gpg_error_t err; estream_t body = NULL; @@ -1294,6 +1373,9 @@ send_congratulation_message (const char *mbox, const char *keyfile) char *from_buffer = NULL; const char *from; strlist_t sl; + char *templ = NULL; + char *p; + const char *charset, *ctencode; from = from_buffer = get_submission_address (mbox); if (!from) @@ -1315,28 +1397,47 @@ send_congratulation_message (const char *mbox, const char *keyfile) log_error ("error allocating memory buffer: %s\n", gpg_strerror (err)); goto leave; } - /* It is fine to use 8 bit encoding because that is encrypted and - * only our client will see it. */ - es_fputs ("Content-Type: text/plain; charset=utf-8\n" - "Content-Transfer-Encoding: 8bit\n" - "\n", - body); - - es_fprintf (body, - "Hello!\n\n" - "The key for your address '%s' has been published\n" - "and can now be retrieved from the Web Key Directory.\n" - "\n" - "For more information on this system see:\n" - "\n" - " https://gnupg.org/faq/wkd.html\n" - "\n" - "Best regards\n" - "\n" - " GnuPG Key Publisher\n\n\n" - "-- \n" - "For information on GnuPG see: %s\n", - mbox, "https://gnupg.org"); + + templ = gnupg_get_template ("wks-utils", "server.publish.congrats", + 0, ctx->language); + if (templ) + { + p = my_subst_vars (ctx, templ, mbox); + xfree (templ); + templ = p; + } + + if (templ && !only_ascii (templ)) + { + charset = "utf-8"; + ctencode = "Content-Transfer-Encoding: quoted-printable\n"; + p = mime_maker_qp_encode (templ); + if (!p) + { + err = gpg_error_from_syserror (); + log_error ("QP encoding failed: %s\n", gpg_strerror (err)); + goto leave; + } + xfree (templ); + templ = p; + } + else + { + charset = "us-ascii"; + ctencode = ""; + } + + + es_fprintf (body, "Content-Type: text/plain; charset=%s\n%s\n", + charset, ctencode); + + if (templ) + es_fputs (templ, body); + else + es_fprintf (body, "Hello!\n\n" + "The key for your address '%s' has been published\n" + "and can now be retrieved from the Web Key Directory.\n", + mbox); es_rewind (body); err = encrypt_stream (&bodyenc, body, keyfile); @@ -1399,6 +1500,7 @@ send_congratulation_message (const char *mbox, const char *keyfile) err = wks_send_mime (mime); leave: + xfree (templ); mime_maker_release (mime); es_fclose (bodyenc); es_fclose (body); @@ -1516,7 +1618,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce) fnewname, gpg_strerror (gpg_err_code_from_syserror())); log_info ("key %s published for '%s'\n", ctx->fpr, address); - send_congratulation_message (address, fnewname); + send_congratulation_message (ctx, address, fnewname); /* Try to publish as DANE record if the DANE directory exists. */ xfree (fname); @@ -1645,7 +1747,7 @@ process_confirmation_response (server_ctx_t ctx, estream_t msg) /* Called from the MIME receiver to process the plain text data in MSG . */ static gpg_error_t -command_receive_cb (void *opaque, const char *mediatype, +command_receive_cb (void *opaque, const char *mediatype, const char *language, estream_t msg, unsigned int flags) { gpg_error_t err; @@ -1656,6 +1758,8 @@ command_receive_cb (void *opaque, const char *mediatype, memset (&ctx, 0, sizeof ctx); if ((flags & WKS_RECEIVE_DRAFT2)) ctx.draft_version_2 = 1; + if (language) + ctx.language = xtrystrdup (language); if (!strcmp (mediatype, "application/pgp-keys")) err = process_new_key (&ctx, msg); diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h index 0601d48fe..3049aaa9d 100644 --- a/tools/gpg-wks.h +++ b/tools/gpg-wks.h @@ -127,6 +127,7 @@ gpg_error_t wks_cmd_print_wkd_url (const char *userid); gpg_error_t wks_receive (estream_t fp, gpg_error_t (*result_cb)(void *opaque, const char *mediatype, + const char *language, estream_t data, unsigned int flags), void *cb_data); diff --git a/tools/wks-receive.c b/tools/wks-receive.c index ecd8cafe3..6bc1318cc 100644 --- a/tools/wks-receive.c +++ b/tools/wks-receive.c @@ -50,6 +50,7 @@ struct receive_ctx_s estream_t signature; estream_t key_data; estream_t wkd_data; + char *ct_language; /* The short locale of the conent or NULL. */ unsigned int collect_key_data:1; unsigned int collect_wkd_data:1; unsigned int draft_version_2:1; /* This is a draft version 2 request. */ @@ -288,6 +289,34 @@ t2body (void *cookie, int level) } +/* Get the Content-Language from the curent MIME header and store it + * in CTX. */ +static void +get_language (receive_ctx_t ctx) +{ + rfc822parse_t msg; + char *value, *p; + size_t valueoff; + + msg = mime_parser_rfc822parser (ctx->parser); + if (msg) + { + value = rfc822parse_get_field (msg, "Content-Language", + -1, &valueoff); + if (value) + { + xfree (ctx->ct_language); + ctx->ct_language = xtrystrdup (value+valueoff); + /* Take only the first short language. */ + if (ctx->ct_language + && (p = strpbrk (ctx->ct_language, " \t,_.@/"))) + *p = 0; + rfc822_free (value); + } + } +} + + static gpg_error_t new_part (void *cookie, const char *mediatype, const char *mediasubtype) { @@ -308,6 +337,7 @@ new_part (void *cookie, const char *mediatype, const char *mediasubtype) } else { + get_language (ctx); ctx->key_data = es_fopenmem (0, "w+b"); if (!ctx->key_data) { @@ -333,6 +363,7 @@ new_part (void *cookie, const char *mediatype, const char *mediasubtype) } else { + get_language (ctx); ctx->wkd_data = es_fopenmem (0, "w+b"); if (!ctx->wkd_data) { @@ -410,6 +441,7 @@ gpg_error_t wks_receive (estream_t fp, gpg_error_t (*result_cb)(void *opaque, const char *mediatype, + const char *language, estream_t data, unsigned int flags), void *cb_data) @@ -482,6 +514,8 @@ wks_receive (estream_t fp, if (DBG_MIME) { es_rewind (ctx->key_data); + if (ctx->ct_language) + log_debug ("Language: '%s'\n", ctx->ct_language); log_debug ("Key: '"); log_printf ("\n"); while ((c = es_getc (ctx->key_data)) != EOF) @@ -492,7 +526,7 @@ wks_receive (estream_t fp, { es_rewind (ctx->key_data); err = result_cb (cb_data, "application/pgp-keys", - ctx->key_data, flags); + ctx->ct_language, ctx->key_data, flags); if (err) goto leave; } @@ -512,7 +546,7 @@ wks_receive (estream_t fp, { es_rewind (ctx->wkd_data); err = result_cb (cb_data, "application/vnd.gnupg.wks", - ctx->wkd_data, flags); + ctx->ct_language, ctx->wkd_data, flags); if (err) goto leave; } @@ -529,6 +563,7 @@ wks_receive (estream_t fp, es_fclose (ctx->signature); es_fclose (ctx->key_data); es_fclose (ctx->wkd_data); + xfree (ctx->ct_language); xfree (ctx); return err; } |