1
/* Copyright (c) 2004-2011 Dovecot authors, see the included COPYING file */
5
#include "message-parser.h"
10
struct mbox_md5_context {
11
struct md5_context hdr_md5_ctx;
12
bool seen_received_hdr;
15
struct mbox_md5_header_func {
17
bool (*func)(struct mbox_md5_context *ctx,
18
struct message_header_line *hdr);
21
static bool parse_date(struct mbox_md5_context *ctx,
22
struct message_header_line *hdr)
24
if (!ctx->seen_received_hdr) {
25
/* Received-header contains date too, and more trusted one */
26
md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
31
static bool parse_delivered_to(struct mbox_md5_context *ctx,
32
struct message_header_line *hdr)
34
md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
38
static bool parse_message_id(struct mbox_md5_context *ctx,
39
struct message_header_line *hdr)
41
if (!ctx->seen_received_hdr) {
42
/* Received-header contains unique ID too,
43
and more trusted one */
44
md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
49
static bool parse_received(struct mbox_md5_context *ctx,
50
struct message_header_line *hdr)
52
if (!ctx->seen_received_hdr) {
53
/* get only the first received-header */
54
md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
56
ctx->seen_received_hdr = TRUE;
61
static bool parse_x_delivery_id(struct mbox_md5_context *ctx,
62
struct message_header_line *hdr)
64
/* Let the local delivery agent help generate unique ID's but don't
65
blindly trust this header alone as it could just as easily come from
67
md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len);
72
static struct mbox_md5_header_func md5_header_funcs[] = {
73
{ "Date", parse_date },
74
{ "Delivered-To", parse_delivered_to },
75
{ "Message-ID", parse_message_id },
76
{ "Received", parse_received },
77
{ "X-Delivery-ID", parse_x_delivery_id }
80
static int bsearch_header_func_cmp(const void *p1, const void *p2)
83
const struct mbox_md5_header_func *func = p2;
85
return strcasecmp(key, func->header);
88
struct mbox_md5_context *mbox_md5_init(void)
90
struct mbox_md5_context *ctx;
92
ctx = i_new(struct mbox_md5_context, 1);
93
md5_init(&ctx->hdr_md5_ctx);
97
void mbox_md5_continue(struct mbox_md5_context *ctx,
98
struct message_header_line *hdr)
100
struct mbox_md5_header_func *func;
102
func = bsearch(hdr->name, md5_header_funcs,
103
N_ELEMENTS(md5_header_funcs), sizeof(*md5_header_funcs),
104
bsearch_header_func_cmp);
106
(void)func->func(ctx, hdr);
109
void mbox_md5_finish(struct mbox_md5_context *ctx,
110
unsigned char result[16])
112
md5_final(&ctx->hdr_md5_ctx, result);