aboutsummaryrefslogtreecommitdiffstats
path: root/tools/gpg-wks-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gpg-wks-server.c')
-rw-r--r--tools/gpg-wks-server.c184
1 files changed, 144 insertions, 40 deletions
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);