[Pkg-gnupg-commit] [gnupg2] 66/292: wks: Partly implement draft-koch-openpgp-webkey-service-02.
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Mon Nov 21 06:31:26 UTC 2016
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch master
in repository gnupg2.
commit 33800280da55a859e08dfa57f29144c89dd1bead
Author: Werner Koch <wk at gnupg.org>
Date: Thu Sep 29 17:55:32 2016 +0200
wks: Partly implement draft-koch-openpgp-webkey-service-02.
* tools/gpg-wks.h (WKS_RECEIVE_DRAFT2): New.
* tools/wks-receive.c: Include rfc822parse.h.
(struct receive_ctx_s): Add fields PARSER, DRAFT_VERSION_2, and
MULTIPART_MIXED_SEEN.
(decrypt_data): Add --no-options.
(verify_signature): Ditto.
(new_part): Check for Wks-Draft-Version header. Take care of text
parts.
(wks_receive): Set Parser and pass a flag value to RESULT_CB.
* tools/gpg-wks-client.c (read_confirmation_request): New.
(main) <aRead>: Call read_confirmation_request instead of
process_confirmation_request.
(command_receive_cb): Ditto. Add arg FLAGS..
(decrypt_stream_status_cb, decrypt_stream): New.
(command_send): Set header Wks-Draft-Version.
* tools/gpg-wks-server.c (struct server_ctx_s): Add field
DRAFT_VERSION_2.
(sign_stream_status_cb, sign_stream): New.
(command_receive_cb): Set draft flag.
(send_confirmation_request): Rework to implement protocol draft
version 2.
* tools/gpg-wks.h (DBG_MIME_VALUE, DBG_PARSER_VALUE): New.
(DBG_MIME, DBG_PARSER, DBG_CRYPTO): New. Use instead of a plain
opt.debug where useful.
* tools/gpg-wks-client.c (debug_flags): Add "mime" and "parser".
* tools/gpg-wks-server.c (debug_flags): Ditto.
--
If a client supporting the version 2 of the protocol is used, it will
tell this the server using a mail header. An old server will ignore
that but a recent server will use the new protocol. Next task is to
actually write draft-02.
There are still a lot of FIXMEs - take care.
Signed-off-by: Werner Koch <wk at gnupg.org>
---
tools/gpg-wks-client.c | 147 ++++++++++++++++++++++++++++--
tools/gpg-wks-server.c | 239 +++++++++++++++++++++++++++++++++++++++++--------
tools/gpg-wks.h | 13 ++-
tools/wks-receive.c | 75 +++++++++++++---
4 files changed, 417 insertions(+), 57 deletions(-)
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 143dbc8..f4257ec 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -91,6 +91,8 @@ static ARGPARSE_OPTS opts[] = {
/* The list of supported debug flags. */
static struct debug_flags_s debug_flags [] =
{
+ { DBG_MIME_VALUE , "mime" },
+ { DBG_PARSER_VALUE , "parser" },
{ DBG_CRYPTO_VALUE , "crypto" },
{ DBG_MEMORY_VALUE , "memory" },
{ DBG_MEMSTAT_VALUE, "memstat" },
@@ -103,9 +105,10 @@ static struct debug_flags_s debug_flags [] =
static void wrong_args (const char *text) GPGRT_ATTR_NORETURN;
static gpg_error_t command_supported (char *userid);
static gpg_error_t command_send (const char *fingerprint, char *userid);
-static gpg_error_t process_confirmation_request (estream_t msg);
+static gpg_error_t read_confirmation_request (estream_t msg);
static gpg_error_t command_receive_cb (void *opaque,
- const char *mediatype, estream_t fp);
+ const char *mediatype, estream_t fp,
+ unsigned int flags);
@@ -269,7 +272,7 @@ main (int argc, char **argv)
case aRead:
if (argc)
wrong_args ("--read < WKS-DATA");
- err = process_confirmation_request (es_stdin);
+ err = read_confirmation_request (es_stdin);
if (err)
log_error ("processing mail failed: %s\n", gpg_strerror (err));
break;
@@ -394,6 +397,83 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
+static void
+decrypt_stream_status_cb (void *opaque, const char *keyword, char *args)
+{
+ (void)opaque;
+
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
+}
+
+
+/* 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)
+{
+ gpg_error_t err;
+ ccparray_t ccp;
+ const char **argv;
+ estream_t output;
+
+ *r_output = NULL;
+
+ output = es_fopenmem (0, "w+b");
+ if (!output)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
+ return err;
+ }
+
+ ccparray_init (&ccp, 0);
+
+ ccparray_put (&ccp, "--no-options");
+ /* We limit the output to 64 KiB to avoid DoS using compression
+ * tricks. A regular client will anyway only send a minimal key;
+ * that is one w/o key signatures and attribute packets. */
+ ccparray_put (&ccp, "--max-output=0x10000");
+ if (!opt.verbose)
+ ccparray_put (&ccp, "--quiet");
+ else if (opt.verbose > 1)
+ ccparray_put (&ccp, "--verbose");
+ ccparray_put (&ccp, "--batch");
+ ccparray_put (&ccp, "--status-fd=2");
+ ccparray_put (&ccp, "--decrypt");
+ ccparray_put (&ccp, "--");
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ err = gnupg_exec_tool_stream (opt.gpg_program, argv, input,
+ NULL, output,
+ decrypt_stream_status_cb, NULL);
+ if (err)
+ {
+ log_error ("decryption failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ else if (opt.verbose)
+ log_info ("decryption succeeded\n");
+
+ es_rewind (output);
+ *r_output = output;
+ output = NULL;
+
+ leave:
+ es_fclose (output);
+ xfree (argv);
+ return err;
+}
+
+
+
+
/* Check whether the provider supports the WKS protocol. */
static gpg_error_t
command_supported (char *userid)
@@ -517,6 +597,11 @@ 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");
+ if (err)
+ goto leave;
+
err = mime_maker_add_stream (mime, &key);
if (err)
goto leave;
@@ -539,8 +624,8 @@ encrypt_response_status_cb (void *opaque, const char *keyword, char *args)
gpg_error_t *failure = opaque;
char *fields[2];
- if (opt.debug)
- log_debug ("%s: %s\n", keyword, args);
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
if (!strcmp (keyword, "FAILURE"))
{
@@ -747,7 +832,7 @@ process_confirmation_request (estream_t msg)
goto leave;
}
- if (opt.debug)
+ if (DBG_MIME)
{
log_debug ("request follows:\n");
nvc_write (nvc, log_get_stream ());
@@ -822,16 +907,62 @@ process_confirmation_request (estream_t msg)
}
+/* Read a confirmation request and decrypt it if needed. This
+ * function may not be used with a mail or MIME message but only with
+ * the actual encrypted or plaintext WKS data. */
+static gpg_error_t
+read_confirmation_request (estream_t msg)
+{
+ gpg_error_t err;
+ int c;
+ estream_t plaintext = NULL;
+
+ /* We take a really simple approach to check whether MSG is
+ * encrypted: We know that an encrypted message is always armored
+ * and thus starts with a few dashes. It is even sufficient to
+ * check for a single dash, because that can never be a proper first
+ * WKS data octet. We need to skip leading spaces, though. */
+ while ((c = es_fgetc (msg)) == ' ' || c == '\t' || c == '\r' || c == '\n')
+ ;
+ if (c == EOF)
+ {
+ log_error ("can't process an empty message\n");
+ return gpg_error (GPG_ERR_INV_DATA);
+ }
+ if (es_ungetc (c, msg) != c)
+ {
+ log_error ("error ungetting octet from message\n");
+ return gpg_error (GPG_ERR_INTERNAL);
+ }
+
+ if (c != '-')
+ err = process_confirmation_request (msg);
+ else
+ {
+ err = decrypt_stream (&plaintext, msg);
+ if (err)
+ log_error ("decryption failed: %s\n", gpg_strerror (err));
+ else
+ err = process_confirmation_request (plaintext);
+ }
+
+ es_fclose (plaintext);
+ return err;
+}
+
+
/* 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, estream_t msg)
+command_receive_cb (void *opaque, const char *mediatype,
+ estream_t msg, unsigned int flags)
{
gpg_error_t err;
(void)opaque;
+ (void)flags;
if (!strcmp (mediatype, "application/vnd.gnupg.wks"))
- err = process_confirmation_request (msg);
+ err = read_confirmation_request (msg);
else
{
log_info ("ignoring unexpected message of type '%s'\n", mediatype);
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index 96e5e05..408e3f5 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -102,6 +102,8 @@ static ARGPARSE_OPTS opts[] = {
/* The list of supported debug flags. */
static struct debug_flags_s debug_flags [] =
{
+ { DBG_MIME_VALUE , "mime" },
+ { DBG_PARSER_VALUE , "parser" },
{ DBG_CRYPTO_VALUE , "crypto" },
{ DBG_MEMORY_VALUE , "memory" },
{ DBG_MEMSTAT_VALUE, "memstat" },
@@ -116,6 +118,7 @@ struct server_ctx_s
{
char *fpr;
strlist_t mboxes; /* List of addr-specs taken from the UIDs. */
+ unsigned int draft_version_2:1; /* Client supports the draft 2. */
};
typedef struct server_ctx_s *server_ctx_t;
@@ -123,7 +126,8 @@ typedef struct server_ctx_s *server_ctx_t;
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, estream_t fp,
+ unsigned int flags);
static gpg_error_t command_list_domains (void);
static gpg_error_t command_cron (void);
@@ -350,8 +354,8 @@ list_key_status_cb (void *opaque, const char *keyword, char *args)
{
server_ctx_t ctx = opaque;
(void)ctx;
- if (opt.debug)
- log_debug ("%s: %s\n", keyword, args);
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
}
@@ -629,8 +633,8 @@ encrypt_stream_status_cb (void *opaque, const char *keyword, char *args)
{
(void)opaque;
- if (opt.debug)
- log_debug ("%s: %s\n", keyword, args);
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
}
@@ -698,6 +702,78 @@ encrypt_stream (estream_t *r_output, estream_t input, const char *keyfile)
}
+static void
+sign_stream_status_cb (void *opaque, const char *keyword, char *args)
+{
+ (void)opaque;
+
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
+}
+
+/* Sign the INPUT stream to a new stream which is stored at success at
+ * R_OUTPUT. A detached signature is created using the key specified
+ * by USERID. */
+static gpg_error_t
+sign_stream (estream_t *r_output, estream_t input, const char *userid)
+{
+ gpg_error_t err;
+ ccparray_t ccp;
+ const char **argv;
+ estream_t output;
+
+ *r_output = NULL;
+
+ output = es_fopenmem (0, "w+b");
+ if (!output)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
+ return err;
+ }
+
+ ccparray_init (&ccp, 0);
+
+ ccparray_put (&ccp, "--no-options");
+ if (!opt.verbose)
+ ccparray_put (&ccp, "--quiet");
+ else if (opt.verbose > 1)
+ ccparray_put (&ccp, "--verbose");
+ ccparray_put (&ccp, "--batch");
+ ccparray_put (&ccp, "--status-fd=2");
+ ccparray_put (&ccp, "--armor");
+ ccparray_put (&ccp, "--local-user");
+ ccparray_put (&ccp, userid);
+ ccparray_put (&ccp, "--detach-sign");
+ ccparray_put (&ccp, "--");
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ err = gnupg_exec_tool_stream (opt.gpg_program, argv, input,
+ NULL, output,
+ sign_stream_status_cb, NULL);
+ if (err)
+ {
+ log_error ("signing failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ es_rewind (output);
+ *r_output = output;
+ output = NULL;
+
+ leave:
+ es_fclose (output);
+ xfree (argv);
+ return err;
+}
+
+
/* Get the submission address for address MBOX. Caller must free the
* value. If no address can be found NULL is returned. */
static char *
@@ -933,6 +1009,8 @@ send_confirmation_request (server_ctx_t ctx,
gpg_error_t err;
estream_t body = NULL;
estream_t bodyenc = NULL;
+ estream_t signeddata = NULL;
+ estream_t signature = NULL;
mime_maker_t mime = NULL;
char *from_buffer = NULL;
const char *from;
@@ -958,12 +1036,16 @@ send_confirmation_request (server_ctx_t ctx,
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: application/vnd.gnupg.wks\n"
- "Content-Transfer-Encoding: 8bit\n"
- "\n",
- body);
+
+ if (!ctx->draft_version_2)
+ {
+ /* It is fine to use 8 bit encoding because that is encrypted and
+ * only our client will see it. */
+ es_fputs ("Content-Type: application/vnd.gnupg.wks\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "\n",
+ body);
+ }
es_fprintf (body, ("type: confirmation-request\n"
"sender: %s\n"
@@ -1002,35 +1084,117 @@ send_confirmation_request (server_ctx_t ctx,
goto leave;
}
- err = mime_maker_add_header (mime, "Content-Type",
- "multipart/encrypted; "
- "protocol=\"application/pgp-encrypted\"");
- if (err)
- goto leave;
- err = mime_maker_add_container (mime);
- if (err)
- goto leave;
+ if (!ctx->draft_version_2)
+ {
+ err = mime_maker_add_header (mime, "Content-Type",
+ "multipart/encrypted; "
+ "protocol=\"application/pgp-encrypted\"");
+ if (err)
+ goto leave;
+ err = mime_maker_add_container (mime);
+ if (err)
+ goto leave;
- err = mime_maker_add_header (mime, "Content-Type",
- "application/pgp-encrypted");
- if (err)
- goto leave;
- err = mime_maker_add_body (mime, "Version: 1\n");
- if (err)
- goto leave;
- err = mime_maker_add_header (mime, "Content-Type",
- "application/octet-stream");
- if (err)
- goto leave;
+ err = mime_maker_add_header (mime, "Content-Type",
+ "application/pgp-encrypted");
+ if (err)
+ goto leave;
+ err = mime_maker_add_body (mime, "Version: 1\n");
+ if (err)
+ goto leave;
+ err = mime_maker_add_header (mime, "Content-Type",
+ "application/octet-stream");
+ if (err)
+ goto leave;
- err = mime_maker_add_stream (mime, &bodyenc);
- if (err)
- goto leave;
+ err = mime_maker_add_stream (mime, &bodyenc);
+ if (err)
+ goto leave;
+
+ }
+ else
+ {
+ unsigned int partid;
+
+ /* FIXME: Add micalg. */
+ err = mime_maker_add_header (mime, "Content-Type",
+ "multipart/signed; "
+ "protocol=\"application/pgp-signature\"");
+ if (err)
+ goto leave;
+ err = mime_maker_add_container (mime);
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_header (mime, "Content-Type", "multipart/mixed");
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_container (mime);
+ if (err)
+ goto leave;
+ partid = mime_maker_get_partid (mime);
+
+ err = mime_maker_add_header (mime, "Content-Type", "text/plain");
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_body
+ (mime,
+ "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");
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_header (mime, "Content-Type",
+ "application/vnd.gnupg.wks");
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_stream (mime, &bodyenc);
+ if (err)
+ goto leave;
+
+ err = mime_maker_end_container (mime);
+ if (err)
+ goto leave;
+
+ mime_maker_dump_tree (mime);
+ err = mime_maker_get_part (mime, partid, &signeddata);
+ if (err)
+ goto leave;
+
+ err = sign_stream (&signature, signeddata, from);
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_header (mime, "Content-Type",
+ "application/pgp-signature");
+ if (err)
+ goto leave;
+
+ err = mime_maker_add_stream (mime, &signature);
+ if (err)
+ goto leave;
+ }
err = wks_send_mime (mime);
leave:
mime_maker_release (mime);
+ es_fclose (signature);
+ es_fclose (signeddata);
es_fclose (bodyenc);
es_fclose (body);
xfree (from_buffer);
@@ -1478,15 +1642,18 @@ 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, estream_t msg)
+command_receive_cb (void *opaque, const char *mediatype,
+ estream_t msg, unsigned int flags)
{
gpg_error_t err;
struct server_ctx_s ctx;
- memset (&ctx, 0, sizeof ctx);
-
(void)opaque;
+ memset (&ctx, 0, sizeof ctx);
+ if ((flags & WKS_RECEIVE_DRAFT2))
+ ctx.draft_version_2 = 1;
+
if (!strcmp (mediatype, "application/pgp-keys"))
err = process_new_key (&ctx, msg);
else if (!strcmp (mediatype, "application/vnd.gnupg.wks"))
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index 85000cc..f8b6cfd 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -39,12 +39,18 @@ struct
} opt;
/* Debug values and macros. */
+#define DBG_MIME_VALUE 1 /* Debug the MIME structure. */
+#define DBG_PARSER_VALUE 2 /* Debug the Mail parser. */
#define DBG_CRYPTO_VALUE 4 /* Debug low level crypto. */
#define DBG_MEMORY_VALUE 32 /* Debug memory allocation stuff. */
#define DBG_MEMSTAT_VALUE 128 /* Show memory statistics. */
#define DBG_IPC_VALUE 1024 /* Debug assuan communication. */
#define DBG_EXTPROG_VALUE 16384 /* debug external program calls */
+#define DBG_MIME (opt.debug & DBG_MIME_VALUE)
+#define DBG_PARSER (opt.debug & DBG_PARSER_VALUE)
+#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE)
+
/* The parsed policy flags. */
struct policy_flags_s
@@ -64,10 +70,15 @@ gpg_error_t wks_parse_policy (policy_flags_t flags, estream_t stream,
int ignore_unknown);
/*-- wks-receive.c --*/
+
+/* Flag values for the receive callback. */
+#define WKS_RECEIVE_DRAFT2 1
+
gpg_error_t wks_receive (estream_t fp,
gpg_error_t (*result_cb)(void *opaque,
const char *mediatype,
- estream_t data),
+ estream_t data,
+ unsigned int flags),
void *cb_data);
diff --git a/tools/wks-receive.c b/tools/wks-receive.c
index 59141fc..0deca9b 100644
--- a/tools/wks-receive.c
+++ b/tools/wks-receive.c
@@ -26,6 +26,7 @@
#include "ccparray.h"
#include "exectool.h"
#include "gpg-wks.h"
+#include "rfc822parse.h"
#include "mime-parser.h"
@@ -41,6 +42,7 @@
/* Data for a received object. */
struct receive_ctx_s
{
+ mime_parser_t parser;
estream_t encrypted;
estream_t plaintext;
estream_t signeddata;
@@ -49,6 +51,8 @@ struct receive_ctx_s
estream_t wkd_data;
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. */
+ unsigned int multipart_mixed_seen:1;
};
typedef struct receive_ctx_s *receive_ctx_t;
@@ -59,7 +63,8 @@ decrypt_data_status_cb (void *opaque, const char *keyword, char *args)
{
receive_ctx_t ctx = opaque;
(void)ctx;
- log_debug ("%s: %s\n", keyword, args);
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
}
@@ -86,6 +91,7 @@ decrypt_data (receive_ctx_t ctx)
ccparray_init (&ccp, 0);
+ ccparray_put (&ccp, "--no-options");
/* We limit the output to 64 KiB to avoid DoS using compression
* tricks. A regular client will anyway only send a minimal key;
* that is one w/o key signatures and attribute packets. */
@@ -113,7 +119,7 @@ decrypt_data (receive_ctx_t ctx)
goto leave;
}
- if (opt.debug)
+ if (DBG_CRYPTO)
{
es_rewind (ctx->plaintext);
log_debug ("plaintext: '");
@@ -133,7 +139,8 @@ verify_signature_status_cb (void *opaque, const char *keyword, char *args)
{
receive_ctx_t ctx = opaque;
(void)ctx;
- log_debug ("%s: %s\n", keyword, args);
+ if (DBG_CRYPTO)
+ log_debug ("gpg status: %s %s\n", keyword, args);
}
/* Verify the signed data. */
@@ -151,6 +158,7 @@ verify_signature (receive_ctx_t ctx)
ccparray_init (&ccp, 0);
+ ccparray_put (&ccp, "--no-options");
ccparray_put (&ccp, "--batch");
if (opt.verbose)
ccparray_put (&ccp, "--verbose");
@@ -177,6 +185,8 @@ verify_signature (receive_ctx_t ctx)
goto leave;
}
+ log_debug ("Fixme: Verification result is not used\n");
+
leave:
xfree (argv);
}
@@ -264,6 +274,22 @@ 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)
{
@@ -303,6 +329,19 @@ new_part (void *cookie, const char *mediatype, const char *mediasubtype)
}
}
}
+ else if (!strcmp (mediatype, "multipart")
+ && !strcmp (mediasubtype, "mixed"))
+ {
+ ctx->multipart_mixed_seen = 1;
+ }
+ else if (!strcmp (mediatype, "text"))
+ {
+ /* Check that we receive a text part only after a
+ * application/mixed. This is actually a too simple test and we
+ * should eventually employ a strict MIME structure check. */
+ if (!ctx->multipart_mixed_seen)
+ err = gpg_error (GPG_ERR_UNEXPECTED_MSG);
+ }
else
{
log_error ("unexpected '%s/%s' message part\n", mediatype, mediasubtype);
@@ -320,7 +359,7 @@ part_data (void *cookie, const void *data, size_t datalen)
if (data)
{
- if (opt.debug)
+ if (DBG_MIME)
log_debug ("part_data: '%.*s'\n", (int)datalen, (const char*)data);
if (ctx->collect_key_data)
{
@@ -337,7 +376,7 @@ part_data (void *cookie, const void *data, size_t datalen)
}
else
{
- if (opt.debug)
+ if (DBG_MIME)
log_debug ("part_data: finished\n");
ctx->collect_key_data = 0;
ctx->collect_wkd_data = 0;
@@ -353,7 +392,8 @@ gpg_error_t
wks_receive (estream_t fp,
gpg_error_t (*result_cb)(void *opaque,
const char *mediatype,
- estream_t data),
+ estream_t data,
+ unsigned int flags),
void *cb_data)
{
gpg_error_t err;
@@ -361,6 +401,7 @@ wks_receive (estream_t fp,
mime_parser_t parser;
estream_t plaintext = NULL;
int c;
+ unsigned int flags = 0;
ctx = xtrycalloc (1, sizeof *ctx);
if (!ctx)
@@ -369,14 +410,16 @@ wks_receive (estream_t fp,
err = mime_parser_new (&parser, ctx);
if (err)
goto leave;
- if (opt.verbose > 1 || opt.debug)
- mime_parser_set_verbose (parser, opt.debug? 10: 1);
+ if (DBG_PARSER)
+ mime_parser_set_verbose (parser, 1);
mime_parser_set_new_part (parser, new_part);
mime_parser_set_part_data (parser, part_data);
mime_parser_set_collect_encrypted (parser, collect_encrypted);
mime_parser_set_collect_signeddata (parser, collect_signeddata);
mime_parser_set_collect_signature (parser, collect_signature);
+ ctx->parser = parser;
+
err = mime_parser_parse (parser, fp);
if (err)
goto leave;
@@ -385,6 +428,11 @@ wks_receive (estream_t fp,
log_info ("key data found\n");
if (ctx->wkd_data)
log_info ("wkd data found\n");
+ if (ctx->draft_version_2)
+ {
+ log_info ("draft version 2 requested\n");
+ flags |= WKS_RECEIVE_DRAFT2;
+ }
if (ctx->plaintext)
{
@@ -412,7 +460,7 @@ wks_receive (estream_t fp,
if (ctx->key_data)
{
- if (opt.debug)
+ if (DBG_MIME)
{
es_rewind (ctx->key_data);
log_debug ("Key: '");
@@ -424,14 +472,15 @@ wks_receive (estream_t fp,
if (result_cb)
{
es_rewind (ctx->key_data);
- err = result_cb (cb_data, "application/pgp-keys", ctx->key_data);
+ err = result_cb (cb_data, "application/pgp-keys",
+ ctx->key_data, flags);
if (err)
goto leave;
}
}
if (ctx->wkd_data)
{
- if (opt.debug)
+ if (DBG_MIME)
{
es_rewind (ctx->wkd_data);
log_debug ("WKD: '");
@@ -443,7 +492,8 @@ wks_receive (estream_t fp,
if (result_cb)
{
es_rewind (ctx->wkd_data);
- err = result_cb (cb_data, "application/vnd.gnupg.wks", ctx->wkd_data);
+ err = result_cb (cb_data, "application/vnd.gnupg.wks",
+ ctx->wkd_data, flags);
if (err)
goto leave;
}
@@ -453,6 +503,7 @@ wks_receive (estream_t fp,
leave:
es_fclose (plaintext);
mime_parser_release (parser);
+ ctx->parser = NULL;
es_fclose (ctx->encrypted);
es_fclose (ctx->plaintext);
es_fclose (ctx->signeddata);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list