summaryrefslogtreecommitdiffstats
path: root/tools/wks-receive.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2016-09-29 17:55:32 +0200
committerWerner Koch <wk@gnupg.org>2016-09-29 17:59:41 +0200
commit33800280da55a859e08dfa57f29144c89dd1bead (patch)
tree5c36328d866ad1bd0a49fef51a4ac7935d4009c7 /tools/wks-receive.c
parenttools: Convey signeddata also to the part_data callback in mime-parser. (diff)
downloadgnupg2-33800280da55a859e08dfa57f29144c89dd1bead.tar.xz
gnupg2-33800280da55a859e08dfa57f29144c89dd1bead.zip
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@gnupg.org>
Diffstat (limited to 'tools/wks-receive.c')
-rw-r--r--tools/wks-receive.c75
1 files changed, 63 insertions, 12 deletions
diff --git a/tools/wks-receive.c b/tools/wks-receive.c
index 59141fcdc..0deca9b20 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);