mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 05:38:06 +00:00
postfix-1.1.11-20020529
This commit is contained in:
parent
2f5c5bf795
commit
15df7b4fbf
@ -6572,6 +6572,12 @@ Apologies for any names omitted.
|
||||
pcre_table(5) manual page. Files: util/dict_pcre.c,
|
||||
proto/pcre_table.
|
||||
|
||||
20020529
|
||||
|
||||
Bugfix: mail rejected due to MIME errors was rejected
|
||||
without proper logging. Files: global/mime_state.c,
|
||||
cleanup/cleanup_message.c.
|
||||
|
||||
Open problems:
|
||||
|
||||
Medium: old maildrop files are no longer readable by the
|
||||
|
@ -56,6 +56,7 @@ tidy: clean
|
||||
.nfs* */.nfs* */*/.nfs* \
|
||||
.pure */.pure */*/.pure \
|
||||
*.out */*.out */*/*.out \
|
||||
*.tmp */*.tmp */*/*.tmp \
|
||||
*.a */*.a */*/*.a \
|
||||
*~ */*~ */*/*~ \
|
||||
*- */*- */*/*- \
|
||||
|
@ -258,16 +258,6 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Can't do header checks if the MIME structure is nested too deeply.
|
||||
*/
|
||||
if ((state->mime_errs & MIME_ERR_NESTING)
|
||||
&& (*var_header_checks || *var_mimehdr_checks || *var_nesthdr_checks)
|
||||
&& state->reason == 0) {
|
||||
state->errs |= CLEANUP_STAT_CONT;
|
||||
state->reason = mystrdup("too much MIME nesting");
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep reading in case of problems, until the sender is ready to receive
|
||||
* our status report.
|
||||
|
@ -603,10 +603,6 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
|
||||
state->mime_errs = mime_state_update(state->mime_state, type, buf, len);
|
||||
/* Ignore header truncation after primary message headers. */
|
||||
state->mime_errs &= ~MIME_ERR_TRUNC_HEADER;
|
||||
/* Ignore MIME nesting error if bouncing or forwarding mail. */
|
||||
/* XXX Also: ignore if not header checking. */
|
||||
if ((state->flags & CLEANUP_FLAG_FILTER) == 0)
|
||||
state->mime_errs &= ~MIME_ERR_NESTING;
|
||||
if (state->mime_errs && state->reason == 0) {
|
||||
state->errs |= CLEANUP_STAT_CONT;
|
||||
state->reason = mystrdup(mime_state_error(state->mime_errs));
|
||||
@ -626,6 +622,27 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup_mime_error_callback - error report call-back routine */
|
||||
|
||||
static void cleanup_mime_error_callback(void *context, int err_code,
|
||||
const char *text)
|
||||
{
|
||||
CLEANUP_STATE *state = (CLEANUP_STATE *) context;
|
||||
const char *origin;
|
||||
|
||||
/*
|
||||
* Message header too large errors are handled after the end of the
|
||||
* primary message headers.
|
||||
*/
|
||||
if ((err_code & ~MIME_ERR_TRUNC_HEADER) != 0) {
|
||||
if ((origin = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
|
||||
origin = MAIL_ATTR_ORG_NONE;
|
||||
msg_info("%s: reject: mime-error %s: %.100s from %s; from=<%s> to=<%s>",
|
||||
state->queue_id, mime_state_error(err_code), text, origin,
|
||||
state->sender, state->recip ? state->recip : "unknown");
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup_message - initialize message content segment */
|
||||
|
||||
void cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len)
|
||||
@ -653,7 +670,7 @@ void cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len)
|
||||
if (var_disable_mime_input) {
|
||||
mime_options |= MIME_OPT_DISABLE_MIME;
|
||||
} else {
|
||||
/* Turn off strict MIME checks if bouncing or forwarding mail. */
|
||||
/* Turn off content checks if bouncing or forwarding mail. */
|
||||
if (state->flags & CLEANUP_FLAG_FILTER) {
|
||||
if (var_strict_8bitmime || var_strict_7bit_hdrs)
|
||||
mime_options |= MIME_OPT_REPORT_8BIT_IN_HEADER;
|
||||
@ -661,6 +678,11 @@ void cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len)
|
||||
mime_options |= MIME_OPT_REPORT_8BIT_IN_7BIT_BODY;
|
||||
if (var_strict_encoding)
|
||||
mime_options |= MIME_OPT_REPORT_ENCODING_DOMAIN;
|
||||
if (var_strict_8bitmime || var_strict_7bit_hdrs
|
||||
|| var_strict_8bit_body || var_strict_encoding
|
||||
|| *var_header_checks || *var_mimehdr_checks
|
||||
|| *var_nesthdr_checks)
|
||||
mime_options |= MIME_OPT_REPORT_NESTING;
|
||||
}
|
||||
}
|
||||
state->mime_state = mime_state_alloc(mime_options,
|
||||
@ -668,6 +690,7 @@ void cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len)
|
||||
cleanup_header_done_callback,
|
||||
cleanup_body_callback,
|
||||
(MIME_STATE_ANY_END) 0,
|
||||
cleanup_mime_error_callback,
|
||||
(void *) state);
|
||||
|
||||
/*
|
||||
|
@ -219,7 +219,7 @@ mime_state: $(LIB) $(LIBS)
|
||||
$(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
|
||||
mv junk $@.o
|
||||
|
||||
tests: tok822_test mime_test
|
||||
tests: tok822_test mime_test mime_nest mime_8bit mime_dom mime_trunc
|
||||
|
||||
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
|
||||
./tok822_parse <tok822_parse.in >tok822_parse.tmp
|
||||
@ -231,6 +231,26 @@ mime_test: mime_state mime_test.in mime_test.ref
|
||||
diff mime_test.ref mime_test.tmp
|
||||
rm -f mime_test.tmp
|
||||
|
||||
mime_nest: mime_state mime_nest.in mime_nest.ref
|
||||
./mime_state <mime_nest.in >mime_nest.tmp
|
||||
diff mime_nest.ref mime_nest.tmp
|
||||
rm -f mime_nest.tmp
|
||||
|
||||
mime_8bit: mime_state mime_8bit.in mime_8bit.ref
|
||||
./mime_state <mime_8bit.in >mime_8bit.tmp
|
||||
diff mime_8bit.ref mime_8bit.tmp
|
||||
rm -f mime_8bit.tmp
|
||||
|
||||
mime_dom: mime_state mime_dom.in mime_dom.ref
|
||||
./mime_state <mime_dom.in >mime_dom.tmp
|
||||
diff mime_dom.ref mime_dom.tmp
|
||||
rm -f mime_dom.tmp
|
||||
|
||||
mime_trunc: mime_state mime_trunc.in mime_trunc.ref
|
||||
./mime_state <mime_trunc.in >mime_trunc.tmp
|
||||
diff mime_trunc.ref mime_trunc.tmp
|
||||
rm -f mime_trunc.tmp
|
||||
|
||||
printfck: $(OBJS) $(PROG)
|
||||
rm -rf printfck
|
||||
mkdir printfck
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Patches change the patchlevel and the release date. Snapshots change the
|
||||
* release date only, unless they include the same bugfix as a patch release.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20020528"
|
||||
#define MAIL_RELEASE_DATE "20020529"
|
||||
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE
|
||||
|
3
postfix/src/global/mime_8bit.in
Normal file
3
postfix/src/global/mime_8bit.in
Normal file
@ -0,0 +1,3 @@
|
||||
Header: f€€bar
|
||||
|
||||
b€dy
|
9
postfix/src/global/mime_8bit.ref
Normal file
9
postfix/src/global/mime_8bit.ref
Normal file
@ -0,0 +1,9 @@
|
||||
mime_state: warning: improper use of 8-bit data in message header: Header: f??bar
|
||||
MAIN Header: f€€bar
|
||||
HEADER END
|
||||
BODY
|
||||
mime_state: warning: improper use of 8-bit data in message body: b?dy
|
||||
BODY b€dy
|
||||
BODY END
|
||||
mime_state: warning: improper use of 8-bit data in message header
|
||||
mime_state: warning: improper use of 8-bit data in message body
|
2
postfix/src/global/mime_dom.in
Normal file
2
postfix/src/global/mime_dom.in
Normal file
@ -0,0 +1,2 @@
|
||||
content-type: message/rfc822
|
||||
content-transfer-encoding: base64
|
8
postfix/src/global/mime_dom.ref
Normal file
8
postfix/src/global/mime_dom.ref
Normal file
@ -0,0 +1,8 @@
|
||||
mime_state: header_token: message / rfc822
|
||||
MAIN content-type: message/rfc822
|
||||
mime_state: header_token: base64
|
||||
MAIN content-transfer-encoding: base64
|
||||
HEADER END
|
||||
mime_state: warning: invalid message/* or multipart/* encoding domain: base64
|
||||
BODY END
|
||||
mime_state: warning: improper message/* or multipart/* encoding domain
|
69
postfix/src/global/mime_nest.in
Normal file
69
postfix/src/global/mime_nest.in
Normal file
@ -0,0 +1,69 @@
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
||||
content-type: multipart/mixed; boundary=foobar
|
||||
|
||||
--foobar
|
163
postfix/src/global/mime_nest.ref
Normal file
163
postfix/src/global/mime_nest.ref
Normal file
@ -0,0 +1,163 @@
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MAIN content-type: multipart/mixed; boundary=foobar
|
||||
HEADER END
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: PUSH boundary foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
mime_state: header_token: multipart / mixed
|
||||
mime_state: header_token: boundary = foobar
|
||||
mime_state: warning: MIME nesting exceeds safety limit: content-type: multipart/mixed; boundary=foobar
|
||||
MULT content-type: multipart/mixed; boundary=foobar
|
||||
BODY
|
||||
BODY --foobar
|
||||
BODY END
|
||||
mime_state: warning: MIME nesting exceeds safety limit
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
||||
mime_state: POP boundary foobar
|
@ -7,7 +7,8 @@
|
||||
/* #include <mime_state.h>
|
||||
/*
|
||||
/* MIME_STATE *mime_state_alloc(flags, head_out, head_end,
|
||||
/* body_out, body_end, context)
|
||||
/* body_out, body_end,
|
||||
/* err_print, context)
|
||||
/* int flags;
|
||||
/* void (*head_out)(void *ptr, int header_class,
|
||||
/* HEADER_OPTS *header_info, VSTRING *buf);
|
||||
@ -15,6 +16,7 @@
|
||||
/* void (*body_out)(void *ptr, int rec_type,
|
||||
/* const char *buf, int len);
|
||||
/* void (*body_end)(void *ptr);
|
||||
/* void (*err_print(void *ptr, int err_flag, const char *text)
|
||||
/* void *context;
|
||||
/*
|
||||
/* int mime_state_update(state, rec_type, buf, len)
|
||||
@ -80,6 +82,10 @@
|
||||
/* routines.
|
||||
/* .IP enc_type
|
||||
/* The content encoding: MIME_ENC_7BIT or MIME_ENC_8BIT.
|
||||
/* .IP err_print
|
||||
/* Null pointer, or pointer to a function that is called with
|
||||
/* arguments: the application context, the error type, and the
|
||||
/* offending input. Only one instance per error type is reported.
|
||||
/* .IP flags
|
||||
/* Special processing options. Specify the bit-wise OR of zero or
|
||||
/* more of the following:
|
||||
@ -102,6 +108,9 @@
|
||||
/* .IP MIME_OPT_REPORT_ENCODING_DOMAIN
|
||||
/* Report errors that set the MIME_ERR_ENCODING_DOMAIN error
|
||||
/* flag (see above).
|
||||
/* .IP MIME_OPT_REPORT_NESTING
|
||||
/* Report errors that set the MIME_ERR_NESTING error flag
|
||||
/* (see above).
|
||||
/* .IP MIME_OPT_RECURSE_ALL_MESSAGE
|
||||
/* Recurse into message/anything types other than message/rfc822.
|
||||
/* This feature can detect "bad" information in headers of
|
||||
@ -274,6 +283,7 @@ struct MIME_STATE {
|
||||
MIME_STATE_ANY_END head_end; /* end of primary header routine */
|
||||
MIME_STATE_BODY_OUT body_out; /* body output routine */
|
||||
MIME_STATE_ANY_END body_end; /* end of body output routine */
|
||||
MIME_STATE_ERR_PRINT err_print; /* error report */
|
||||
void *app_context; /* application context */
|
||||
};
|
||||
|
||||
@ -329,6 +339,15 @@ typedef struct MIME_ENCODING {
|
||||
#define MIME_ENC_BINARY 9 /* domain only */
|
||||
#endif
|
||||
|
||||
static MIME_ENCODING mime_encoding_map[] = { /* RFC 2045 */
|
||||
"7bit", MIME_ENC_7BIT, MIME_ENC_7BIT, /* domain */
|
||||
"8bit", MIME_ENC_8BIT, MIME_ENC_8BIT, /* domain */
|
||||
"binary", MIME_ENC_BINARY, MIME_ENC_BINARY, /* domain */
|
||||
"base64", MIME_ENC_BASE64, MIME_ENC_7BIT, /* encoding */
|
||||
"quoted-printable", MIME_ENC_QP, MIME_ENC_7BIT, /* encoding */
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Silly Little Macros.
|
||||
*/
|
||||
@ -337,6 +356,14 @@ typedef struct MIME_ENCODING {
|
||||
#define END(x) vstring_end(x)
|
||||
#define CU_CHAR_PTR(x) ((const unsigned char *) (x))
|
||||
|
||||
#define REPORT_ERROR(state, err_type, text) do { \
|
||||
if ((state->err_flags & err_type) == 0) { \
|
||||
if (state->err_print != 0) \
|
||||
state->err_print(state->app_context, err_type, text); \
|
||||
state->err_flags |= err_type; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* mime_state_push - push boundary onto stack */
|
||||
|
||||
static void mime_state_push(MIME_STATE *state, int def_ctype, int def_stype,
|
||||
@ -355,21 +382,17 @@ static void mime_state_push(MIME_STATE *state, int def_ctype, int def_stype,
|
||||
* will still correctly detect all intermediate boundaries and all the
|
||||
* message headers that follow those boundaries.
|
||||
*/
|
||||
if (state->nesting_level > var_mime_maxdepth) {
|
||||
state->err_flags |= MIME_ERR_NESTING;
|
||||
} else {
|
||||
state->nesting_level += 1;
|
||||
stack = (MIME_STACK *) mymalloc(sizeof(*stack));
|
||||
stack->def_ctype = def_ctype;
|
||||
stack->def_stype = def_stype;
|
||||
if ((stack->bound_len = strlen(boundary)) > var_mime_bound_len)
|
||||
stack->bound_len = var_mime_bound_len;
|
||||
stack->boundary = mystrndup(boundary, stack->bound_len);
|
||||
stack->next = state->stack;
|
||||
state->stack = stack;
|
||||
if (msg_verbose)
|
||||
msg_info("PUSH boundary %s", stack->boundary);
|
||||
}
|
||||
state->nesting_level += 1;
|
||||
stack = (MIME_STACK *) mymalloc(sizeof(*stack));
|
||||
stack->def_ctype = def_ctype;
|
||||
stack->def_stype = def_stype;
|
||||
if ((stack->bound_len = strlen(boundary)) > var_mime_bound_len)
|
||||
stack->bound_len = var_mime_bound_len;
|
||||
stack->boundary = mystrndup(boundary, stack->bound_len);
|
||||
stack->next = state->stack;
|
||||
state->stack = stack;
|
||||
if (msg_verbose)
|
||||
msg_info("PUSH boundary %s", stack->boundary);
|
||||
}
|
||||
|
||||
/* mime_state_pop - pop boundary from stack */
|
||||
@ -395,6 +418,7 @@ MIME_STATE *mime_state_alloc(int flags,
|
||||
MIME_STATE_ANY_END head_end,
|
||||
MIME_STATE_BODY_OUT body_out,
|
||||
MIME_STATE_ANY_END body_end,
|
||||
MIME_STATE_ERR_PRINT err_print,
|
||||
void *context)
|
||||
{
|
||||
MIME_STATE *state;
|
||||
@ -417,6 +441,7 @@ MIME_STATE *mime_state_alloc(int flags,
|
||||
state->head_end = head_end;
|
||||
state->body_out = body_out;
|
||||
state->body_end = body_end;
|
||||
state->err_print = err_print;
|
||||
state->app_context = context;
|
||||
return (state);
|
||||
}
|
||||
@ -521,9 +546,16 @@ static void mime_state_content_type(MIME_STATE *state,
|
||||
while ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) >= 0) {
|
||||
if (tok_count >= 3
|
||||
&& TOKEN_MATCH(state->token[0], "boundary")
|
||||
&& state->token[1].type == '=')
|
||||
mime_state_push(state, def_ctype, def_stype,
|
||||
state->token[2].u.value);
|
||||
&& state->token[1].type == '=') {
|
||||
if (state->nesting_level > var_mime_maxdepth) {
|
||||
if (state->static_flags & MIME_OPT_REPORT_NESTING)
|
||||
REPORT_ERROR(state, MIME_ERR_NESTING,
|
||||
STR(state->output_buffer));
|
||||
} else {
|
||||
mime_state_push(state, def_ctype, def_stype,
|
||||
state->token[2].u.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -544,14 +576,6 @@ static void mime_state_content_encoding(MIME_STATE *state,
|
||||
HEADER_OPTS *header_info)
|
||||
{
|
||||
const char *cp;
|
||||
static MIME_ENCODING code_map[] = { /* RFC 2045 */
|
||||
"7bit", MIME_ENC_7BIT, MIME_ENC_7BIT, /* domain */
|
||||
"8bit", MIME_ENC_8BIT, MIME_ENC_8BIT, /* domain */
|
||||
"binary", MIME_ENC_BINARY, MIME_ENC_BINARY, /* domain */
|
||||
"base64", MIME_ENC_BASE64, MIME_ENC_7BIT, /* encoding */
|
||||
"quoted-printable", MIME_ENC_QP, MIME_ENC_7BIT, /* encoding */
|
||||
0,
|
||||
};
|
||||
MIME_ENCODING *cmp;
|
||||
|
||||
#define PARSE_CONTENT_ENCODING_HEADER(state, ptr) \
|
||||
@ -565,7 +589,7 @@ static void mime_state_content_encoding(MIME_STATE *state,
|
||||
cp = STR(state->output_buffer) + strlen(header_info->name) + 1;
|
||||
if (PARSE_CONTENT_ENCODING_HEADER(state, &cp) > 0
|
||||
&& state->token[0].type == HEADER_TOK_TOKEN) {
|
||||
for (cmp = code_map; cmp->name != 0; cmp++) {
|
||||
for (cmp = mime_encoding_map; cmp->name != 0; cmp++) {
|
||||
if (strcasecmp(state->token[0].u.value, cmp->name) == 0) {
|
||||
state->curr_encoding = cmp->encoding;
|
||||
state->curr_domain = cmp->domain;
|
||||
@ -575,6 +599,18 @@ static void mime_state_content_encoding(MIME_STATE *state,
|
||||
}
|
||||
}
|
||||
|
||||
/* mime_state_enc_name - encoding to printable form */
|
||||
|
||||
static const char *mime_state_enc_name(int encoding)
|
||||
{
|
||||
MIME_ENCODING *cmp;
|
||||
|
||||
for (cmp = mime_encoding_map; cmp->name != 0; cmp++)
|
||||
if (encoding == cmp->encoding)
|
||||
return (cmp->name);
|
||||
return ("unknown");
|
||||
}
|
||||
|
||||
/* mime_state_downgrade - convert 8-bit data to quoted-printable */
|
||||
|
||||
static void mime_state_downgrade(MIME_STATE *state, int rec_type,
|
||||
@ -643,10 +679,10 @@ int mime_state_update(MIME_STATE *state, int rec_type,
|
||||
HEADER_OPTS *header_info;
|
||||
const unsigned char *cp;
|
||||
|
||||
#define SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type) { \
|
||||
#define SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type) do { \
|
||||
state->prev_rec_type = rec_type; \
|
||||
return (state->err_flags); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Be sure to flush any partial output line that might still be buffered
|
||||
@ -681,7 +717,8 @@ int mime_state_update(MIME_STATE *state, int rec_type,
|
||||
vstring_strcat(state->output_buffer, text);
|
||||
} else {
|
||||
if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER)
|
||||
state->err_flags |= MIME_ERR_TRUNC_HEADER;
|
||||
REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER,
|
||||
STR(state->output_buffer));
|
||||
}
|
||||
SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type);
|
||||
}
|
||||
@ -691,7 +728,8 @@ int mime_state_update(MIME_STATE *state, int rec_type,
|
||||
vstring_strcat(state->output_buffer, text);
|
||||
} else {
|
||||
if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER)
|
||||
state->err_flags |= MIME_ERR_TRUNC_HEADER;
|
||||
REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER,
|
||||
STR(state->output_buffer));
|
||||
}
|
||||
SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type);
|
||||
}
|
||||
@ -721,7 +759,8 @@ int mime_state_update(MIME_STATE *state, int rec_type,
|
||||
for (cp = CU_CHAR_PTR(STR(state->output_buffer));
|
||||
cp < CU_CHAR_PTR(END(state->output_buffer)); cp++)
|
||||
if (*cp & 0200) {
|
||||
state->err_flags |= MIME_ERR_8BIT_IN_HEADER;
|
||||
REPORT_ERROR(state, MIME_ERR_8BIT_IN_HEADER,
|
||||
STR(state->output_buffer));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -803,14 +842,17 @@ int mime_state_update(MIME_STATE *state, int rec_type,
|
||||
if (state->curr_stype == MIME_STYPE_PARTIAL
|
||||
|| state->curr_stype == MIME_STYPE_EXTERN_BODY) {
|
||||
if (state->curr_domain != MIME_ENC_7BIT)
|
||||
state->err_flags |= MIME_ERR_ENCODING_DOMAIN;
|
||||
REPORT_ERROR(state, MIME_ERR_ENCODING_DOMAIN,
|
||||
mime_state_enc_name(state->curr_encoding));
|
||||
} else {
|
||||
if (state->curr_encoding != state->curr_domain)
|
||||
state->err_flags |= MIME_ERR_ENCODING_DOMAIN;
|
||||
REPORT_ERROR(state, MIME_ERR_ENCODING_DOMAIN,
|
||||
mime_state_enc_name(state->curr_encoding));
|
||||
}
|
||||
} else if (state->curr_ctype == MIME_CTYPE_MULTIPART) {
|
||||
if (state->curr_encoding != state->curr_domain)
|
||||
state->err_flags |= MIME_ERR_ENCODING_DOMAIN;
|
||||
REPORT_ERROR(state, MIME_ERR_ENCODING_DOMAIN,
|
||||
mime_state_enc_name(state->curr_encoding));
|
||||
}
|
||||
}
|
||||
|
||||
@ -885,7 +927,7 @@ int mime_state_update(MIME_STATE *state, int rec_type,
|
||||
&& (state->err_flags & MIME_ERR_8BIT_IN_7BIT_BODY) == 0) {
|
||||
for (cp = CU_CHAR_PTR(text); cp < CU_CHAR_PTR(text + len); cp++)
|
||||
if (*cp & 0200) {
|
||||
state->err_flags |= MIME_ERR_8BIT_IN_7BIT_BODY;
|
||||
REPORT_ERROR(state, MIME_ERR_8BIT_IN_7BIT_BODY, text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -944,7 +986,7 @@ const char *mime_state_error(int error_code)
|
||||
if (error_code & MIME_ERR_NESTING)
|
||||
return ("MIME nesting exceeds safety limit");
|
||||
if (error_code & MIME_ERR_TRUNC_HEADER)
|
||||
return ("message header was truncated");
|
||||
return ("message header length exceeds safety limit");
|
||||
if (error_code & MIME_ERR_8BIT_IN_HEADER)
|
||||
return ("improper use of 8-bit data in message header");
|
||||
if (error_code & MIME_ERR_8BIT_IN_7BIT_BODY)
|
||||
@ -1005,9 +1047,14 @@ static void body_end(void *context)
|
||||
vstream_fprintf(stream, "BODY END\n");
|
||||
}
|
||||
|
||||
int var_header_limit = DEF_HEADER_LIMIT;
|
||||
int var_mime_maxdepth = DEF_MIME_MAXDEPTH;
|
||||
int var_mime_bound_len = DEF_MIME_BOUND_LEN;
|
||||
static void err_print(void *context, int err_flag, const char *text)
|
||||
{
|
||||
msg_warn("%s: %.100s", mime_state_error(err_flag), text);
|
||||
}
|
||||
|
||||
int var_header_limit = 200;
|
||||
int var_mime_maxdepth = 20;
|
||||
int var_mime_bound_len = 200;
|
||||
|
||||
int main(int unused_argc, char **argv)
|
||||
{
|
||||
@ -1024,6 +1071,8 @@ int main(int unused_argc, char **argv)
|
||||
(MIME_OPT_REPORT_8BIT_IN_7BIT_BODY \
|
||||
| MIME_OPT_REPORT_8BIT_IN_HEADER \
|
||||
| MIME_OPT_REPORT_ENCODING_DOMAIN \
|
||||
| MIME_OPT_REPORT_TRUNC_HEADER \
|
||||
| MIME_OPT_REPORT_NESTING \
|
||||
| MIME_OPT_DOWNGRADE)
|
||||
|
||||
msg_vstream_init(basename(argv[0]), VSTREAM_OUT);
|
||||
@ -1032,6 +1081,7 @@ int main(int unused_argc, char **argv)
|
||||
state = mime_state_alloc(MIME_OPTIONS,
|
||||
head_out, head_end,
|
||||
body_out, body_end,
|
||||
err_print,
|
||||
(void *) VSTREAM_OUT);
|
||||
|
||||
/*
|
||||
@ -1048,7 +1098,7 @@ int main(int unused_argc, char **argv)
|
||||
* Error reporting.
|
||||
*/
|
||||
if (err & MIME_ERR_TRUNC_HEADER)
|
||||
msg_warn("message header was truncated");
|
||||
msg_warn("message header length exceeds safety limit");
|
||||
if (err & MIME_ERR_NESTING)
|
||||
msg_warn("MIME nesting exceeds safety limit");
|
||||
if (err & MIME_ERR_8BIT_IN_HEADER)
|
||||
|
@ -28,8 +28,9 @@ typedef struct MIME_STATE MIME_STATE;
|
||||
typedef void (*MIME_STATE_HEAD_OUT) (void *, int, HEADER_OPTS *, VSTRING *);
|
||||
typedef void (*MIME_STATE_BODY_OUT) (void *, int, const char *, int);
|
||||
typedef void (*MIME_STATE_ANY_END) (void *);
|
||||
typedef void (*MIME_STATE_ERR_PRINT) (void *, int, const char *);
|
||||
|
||||
extern MIME_STATE *mime_state_alloc(int, MIME_STATE_HEAD_OUT, MIME_STATE_ANY_END, MIME_STATE_BODY_OUT, MIME_STATE_ANY_END, void *);
|
||||
extern MIME_STATE *mime_state_alloc(int, MIME_STATE_HEAD_OUT, MIME_STATE_ANY_END, MIME_STATE_BODY_OUT, MIME_STATE_ANY_END, MIME_STATE_ERR_PRINT, void *);
|
||||
extern int mime_state_update(MIME_STATE *, int, const char *, int);
|
||||
extern MIME_STATE *mime_state_free(MIME_STATE *);
|
||||
extern const char *mime_state_error(int);
|
||||
@ -45,6 +46,7 @@ extern const char *mime_state_error(int);
|
||||
#define MIME_OPT_RECURSE_ALL_MESSAGE (1<<4)
|
||||
#define MIME_OPT_REPORT_TRUNC_HEADER (1<<5)
|
||||
#define MIME_OPT_DISABLE_MIME (1<<6)
|
||||
#define MIME_OPT_REPORT_NESTING (1<<7)
|
||||
|
||||
/*
|
||||
* Body encoding domains.
|
||||
|
@ -19,6 +19,7 @@ mime_state: PUSH boundary pqrs
|
||||
NEST content-type: multipart/mumble; boundary(comment)="pqrs"
|
||||
mime_state: header_token: base64
|
||||
NEST content-transfer-encoding: base64
|
||||
mime_state: warning: invalid message/* or multipart/* encoding domain: base64
|
||||
BODY
|
||||
BODY pqrs prolog
|
||||
BODY
|
||||
|
1441
postfix/src/global/mime_trunc.in
Normal file
1441
postfix/src/global/mime_trunc.in
Normal file
File diff suppressed because it is too large
Load Diff
8
postfix/src/global/mime_trunc.ref
Normal file
8
postfix/src/global/mime_trunc.ref
Normal file
@ -0,0 +1,8 @@
|
||||
mime_state: warning: message header length exceeds safety limit: Header: ??garbage garbage garbage garbage garbage garbage garbage garbage garbage ??garbage garbage
|
||||
MAIN Header:
|
||||
garbage garbage garbage garbage garbage garbage garbage garbage garbage
|
||||
garbage garbage garbage garbage garbage garbage garbage garbage garbage
|
||||
garbage garbage garbage garbage garbage garbage garbage garbage garbage
|
||||
HEADER END
|
||||
BODY END
|
||||
mime_state: warning: message header length exceeds safety limit
|
@ -771,11 +771,13 @@ int smtp_xfer(SMTP_STATE *state)
|
||||
&& (state->features & SMTP_FEATURE_8BITMIME) == 0
|
||||
&& strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) != 0);
|
||||
if (downgrading)
|
||||
state->mime_state = mime_state_alloc(MIME_OPT_DOWNGRADE,
|
||||
state->mime_state = mime_state_alloc(MIME_OPT_DOWNGRADE
|
||||
| MIME_OPT_REPORT_NESTING,
|
||||
smtp_header_out,
|
||||
(MIME_STATE_ANY_END) 0,
|
||||
smtp_text_out,
|
||||
(MIME_STATE_ANY_END) 0,
|
||||
(MIME_STATE_ERR_PRINT) 0,
|
||||
(void *) state);
|
||||
state->space_left = var_smtp_line_limit;
|
||||
smtp_timeout_setup(state->session->stream,
|
||||
|
Loading…
x
Reference in New Issue
Block a user