aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-07-04 03:57:14 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-07-04 04:37:32 +0300
commit2d56241f89eae839959e538cede756539adba89e (patch)
tree86ba5b50f68e2ee3c0e45c52e24e30fd9c0d1310 /src
parenta113a190cc7b5339e9d07904cd1cf8c2820a0e53 (diff)
downloadmailfromd-2d56241f89eae839959e538cede756539adba89e.tar.gz
mailfromd-2d56241f89eae839959e538cede756539adba89e.tar.bz2
dkim: take into account changes applied by MMQ
* mflib/status.mf (e_badmmq): New exception: MMQ incompatible with the signing function (currently for dkim_sign). * src/builtin/dkim.bi (dkim_sign): Apply MMQ to the temporary message prior to calling mfd_dkim_sign. * src/mailfromd.h (env_msgmod_apply): Change the return type. * src/prog.c (env_msgmod_apply): Return int code from mu_list_foreach. * src/dkim.c (mfd_dkim_sign): Fix the type of the c auto.
Diffstat (limited to 'src')
-rw-r--r--src/builtin/dkim.bi167
-rw-r--r--src/dkim.c3
-rw-r--r--src/mailfromd.h2
-rw-r--r--src/prog.c4
4 files changed, 171 insertions, 5 deletions
diff --git a/src/builtin/dkim.bi b/src/builtin/dkim.bi
index 870a5689..a0b07234 100644
--- a/src/builtin/dkim.bi
+++ b/src/builtin/dkim.bi
@@ -19,6 +19,132 @@ MF_BUILTIN_MODULE
#include "dkim.h"
#include "msg.h"
+struct msgmod_data {
+ mu_message_t msg;
+ struct msgmod_closure *e_msgmod;
+};
+
+static int
+message_replace_body(mu_message_t msg, mu_stream_t stream)
+{
+ mu_body_t body;
+ int rc;
+
+ rc = mu_body_create(&body, msg);
+ if (rc) {
+ mu_diag_funcall(MU_DIAG_ERROR, "mu_body_create", NULL, rc);
+ return rc;
+ }
+
+ rc = mu_body_set_stream(body, stream, msg);
+ if (rc) {
+ mu_body_destroy(&body, msg);
+ mu_diag_funcall(MU_DIAG_ERROR, "mu_body_set_stream", NULL, rc);
+ return rc;
+ }
+
+ rc = mu_message_set_body(msg, body, mu_message_get_owner(msg));
+ if (rc) {
+ mu_body_destroy(&body, msg);
+ mu_diag_funcall(MU_DIAG_ERROR, "mu_message_set_body", NULL, rc);
+ }
+ return rc;
+}
+
+static int
+do_msgmod(void *item, void *data)
+{
+ struct msgmod_closure *msgmod = item;
+ struct msgmod_data *md = data;
+ mu_header_t hdr;
+ mu_stream_t stream;
+ int rc;
+
+ MF_DEBUG(MU_DEBUG_TRACE6,
+ ("%s %s: %s %u",
+ msgmod_opcode_str(msgmod->opcode),
+ SP(msgmod->name), SP(msgmod->value), msgmod->idx));
+
+ mu_message_get_header(md->msg, &hdr);
+
+ switch (msgmod->opcode) {
+ case header_replace:
+ rc = mu_header_insert(hdr, msgmod->name, msgmod->value,
+ NULL,
+ msgmod->idx, MU_HEADER_REPLACE);
+ if (rc == MU_ERR_NOENT) {
+ rc = mu_header_append(hdr, msgmod->name, msgmod->value);
+ if (rc)
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_header_append",
+ msgmod->name,
+ rc);
+ } else if (rc) {
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_header_insert",
+ msgmod->name,
+ rc);
+ }
+
+ if (rc) {
+ md->e_msgmod = msgmod;
+ return rc;
+ }
+ break;
+
+ case header_delete:
+ rc = mu_header_remove(hdr, msgmod->name, msgmod->idx);
+ if (rc && rc != MU_ERR_NOENT) {
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_header_remove",
+ msgmod->name,
+ rc);
+ md->e_msgmod = msgmod;
+ return rc;
+ }
+ break;
+
+ case body_repl:
+ rc = mu_static_memory_stream_create(&stream, msgmod->value,
+ strlen(msgmod->value));
+ if (rc)
+ return rc;
+ rc = message_replace_body(md->msg, stream);
+ if (rc) {
+ mu_stream_destroy(&stream);
+ return rc;
+ }
+ break;
+
+ case body_repl_fd:
+ rc = mu_fd_stream_create (&stream, "<body_repl_fd>",
+ msgmod->idx,
+ MU_STREAM_READ);
+ if (rc)
+ return rc;
+ rc = message_replace_body(md->msg, stream);
+ if (rc) {
+ mu_stream_destroy(&stream);
+ return rc;
+ }
+ break;
+
+ case header_add:
+ case header_insert:
+ md->e_msgmod = msgmod;
+ return MU_ERR_USER0;
+
+ case rcpt_add:
+ case rcpt_delete:
+ case quarantine:
+ case set_from:
+ break;
+ }
+ return 0;
+}
+
+
+
MF_STATE(eom)
MF_CAPTURE
MF_DEFUN(dkim_sign, VOID, STRING d, STRING s, STRING keyfile,
@@ -71,8 +197,47 @@ STRING canon_h, STRING canon_b, STRING headers)
}
sig.h = MF_OPTVAL(headers, default_headers);
- bi_get_current_message(env, &msg);
+ bi_get_current_message(env, &msg);
+ if (env_msgmod_count(env)) {
+ struct msgmod_data mdat;
+
+ rc = mu_message_create_copy(&mdat.msg, msg);
+ if (rc) {
+ mu_diag_funcall(MU_DIAG_ERROR,
+ "mu_message_create_copy",
+ NULL, rc);
+ MF_THROW(mfe_failure,
+ "mu_message_create_copy: %s",
+ mu_strerror(rc));
+ }
+ mdat.e_msgmod = 0;
+ rc = env_msgmod_apply(env, do_msgmod, &mdat);
+ if (rc) {
+ mu_message_unref(mdat.msg);
+ if (rc == MU_ERR_USER0) {
+ MF_THROW(mfe_badmmq,
+ _("MMQ incompatible with dkim_sign: %s on %s, value %s"),
+ msgmod_opcode_str(mdat.e_msgmod->opcode),
+ mdat.e_msgmod->name,
+ SP(mdat.e_msgmod->value));
+ } else if (mdat.e_msgmod) {
+ MF_THROW(mfe_failure,
+ _("%s failed on %s, value %s: %s"),
+ msgmod_opcode_str(mdat.e_msgmod->opcode),
+ mdat.e_msgmod->name,
+ SP(mdat.e_msgmod->value),
+ mu_strerror(rc));
+ } else
+ MF_THROW(mfe_failure,
+ _("error: %s"),
+ mu_strerror(rc));
+ }
+ msg = mdat.msg;
+ } else
+ mu_message_ref(msg);
+
rc = mfd_dkim_sign(msg, &sig, keyfile, &sighdr);
+ mu_message_unref(msg);
MF_ASSERT(rc == 0,
mfe_failure,
_("DKIM failed"));
diff --git a/src/dkim.c b/src/dkim.c
index b4ab9105..f7fffed2 100644
--- a/src/dkim.c
+++ b/src/dkim.c
@@ -620,7 +620,8 @@ mfd_dkim_sign(mu_message_t msg, struct dkim_signature *sig,
struct header_map *hmap;
uint8_t bh[BASE64_ENCODE_RAW_LENGTH(SHA256_DIGEST_SIZE)+1];
mu_opool_t op = NULL;
- int rc, c;
+ int rc;
+ char c;
struct sha256_ctx ctx;
int result = -1;
size_t count, i;
diff --git a/src/mailfromd.h b/src/mailfromd.h
index 401e67e3..3739c956 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -820,7 +820,7 @@ void env_msgmod_append(eval_environ_t env, enum msgmod_opcode opcode,
const char *name, const char *value, unsigned idx);
void env_msgmod_clear(eval_environ_t env);
size_t env_msgmod_count(eval_environ_t env);
-void env_msgmod_apply(eval_environ_t env, mu_list_action_t fun, void *data);
+int env_msgmod_apply(eval_environ_t env, mu_list_action_t fun, void *data);
void capture_on(void);
const char *env_get_macro(eval_environ_t env, const char *symbol);
diff --git a/src/prog.c b/src/prog.c
index 5cdefe0e..a896a941 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -2683,10 +2683,10 @@ env_msgmod_count(eval_environ_t env)
return n;
}
-void
+int
env_msgmod_apply(eval_environ_t env, mu_list_action_t fun, void *data)
{
- mu_list_foreach(env->mmq, fun, data);
+ return mu_list_foreach(env->mmq, fun, data);
}

Return to:

Send suggestions and report system problems to the System administrator.