summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alpine/send.c55
-rw-r--r--imap/src/c-client/mail.h1
-rw-r--r--pith/conf.c2
-rw-r--r--pith/conftype.h1
-rw-r--r--pith/pine.hlp18
-rw-r--r--pith/send.c58
6 files changed, 116 insertions, 19 deletions
diff --git a/alpine/send.c b/alpine/send.c
index bc70dadf..823080c9 100644
--- a/alpine/send.c
+++ b/alpine/send.c
@@ -4115,6 +4115,23 @@ pine_send(ENVELOPE *outgoing, struct mail_bodystruct **body,
pbf = save_previous_pbuf;
g_rolenick = NULL;
+ /* Topal: Unmangle the body types. */
+ if ((*body)->type == TYPEMULTIPART
+ && (*body)->topal_hack == 1) {
+ /* This was a single part message which Topal mangled. */
+ dprint((9, "Topal: unmangling single part message\n"));
+ (*body)->type = TYPETEXT;
+ }
+ if ((*body)->type == TYPEMULTIPART
+ && (*body)->topal_hack != 1
+ && (*body)->nested.part->body.type == TYPEMULTIPART
+ && (*body)->nested.part->body.topal_hack == 1) {
+ /* Topal mangled a multipart message. So the first nested part
+ is really TYPETEXT. */
+ dprint((9, "Topal: unmangling first part of multipart message\n"));
+ (*body)->nested.part->body.type = TYPETEXT;
+ }
+
dprint((4, "=== send returning ===\n"));
}
@@ -5451,22 +5468,50 @@ filter_message_text(char *fcmd, ENVELOPE *outgoing, struct mail_bodystruct *body
rfc822_parse_content_header(nb,
(char *) ucase((unsigned char *) buf+8),s);
+ /* Topal: We're working on the first
+ text segment of the message. If
+ the filter returns something that
+ isn't TYPETEXT, then we need to
+ pretend (later on) that this is in
+ fact a TYPETEXT, because Topal has
+ already encoded it....
+
+ Original code path first, then an
+ alternate path.
+ */
if(nb->type == TYPETEXT
&& nb->subtype
&& (!b->subtype
|| strucmp(b->subtype, nb->subtype))){
- if(b->subtype)
- fs_give((void **) &b->subtype);
-
+ if(b->subtype)
+ fs_give((void **) &b->subtype);
+
+ b->subtype = nb->subtype;
+ nb->subtype = NULL;
+
+ mail_free_body_parameter(&b->parameter);
+ b->parameter = nb->parameter;
+ nb->parameter = NULL;
+ mail_free_body_parameter(&nb->parameter);
+ }
+ else if(F_ON(F_ENABLE_TOPAL_HACK, ps_global)){
+ /* Perhaps the type isn't TYPETEXT,
+ and the hack is requested. So,
+ let's mess with the types. */
+ if(nb->type != TYPETEXT){
+ b->type = nb->type;
b->subtype = nb->subtype;
nb->subtype = NULL;
-
+
+ dprint((9, "Topal: mangling body!\n"));
mail_free_body_parameter(&b->parameter);
b->parameter = nb->parameter;
nb->parameter = NULL;
mail_free_body_parameter(&nb->parameter);
+ b->topal_hack = 1;
+ }
}
-
+ /* Topal: end */
mail_free_body(&nb);
}
diff --git a/imap/src/c-client/mail.h b/imap/src/c-client/mail.h
index 79f0b3f3..c89d1638 100644
--- a/imap/src/c-client/mail.h
+++ b/imap/src/c-client/mail.h
@@ -844,6 +844,7 @@ BODY {
unsigned long bytes; /* size of text in octets */
} size;
char *md5; /* MD5 checksum */
+ unsigned short topal_hack; /* set to 1 if topal has wrecked the sending */
void *sparep; /* spare pointer reserved for main program */
};
diff --git a/pith/conf.c b/pith/conf.c
index e4f64c71..21afdf4e 100644
--- a/pith/conf.c
+++ b/pith/conf.c
@@ -2992,6 +2992,8 @@ feature_list(int index)
F_SEND_WO_CONFIRM, h_config_send_wo_confirm, PREF_SEND, 0},
{"strip-whitespace-before-send", "Strip Whitespace Before Sending",
F_STRIP_WS_BEFORE_SEND, h_config_strip_ws_before_send, PREF_SEND, 0},
+ {"enable-topal-hack", "Enable Topal hack for OpenPGP/MIME messages",
+ F_ENABLE_TOPAL_HACK, h_config_enable_topal_hack, PREF_HIDDEN, 0},
{"warn-if-blank-fcc", "Warn if Blank Fcc",
F_WARN_ABOUT_NO_FCC, h_config_warn_if_fcc_blank, PREF_SEND, 0},
{"warn-if-blank-subject", "Warn if Blank Subject",
diff --git a/pith/conftype.h b/pith/conftype.h
index 3ed5040f..5f695f51 100644
--- a/pith/conftype.h
+++ b/pith/conftype.h
@@ -532,6 +532,7 @@ typedef enum {
F_MARK_FCC_SEEN,
F_MULNEWSRC_HOSTNAMES_AS_TYPED,
F_STRIP_WS_BEFORE_SEND,
+ F_ENABLE_TOPAL_HACK,
F_QUELL_FLOWED_TEXT,
F_COMPOSE_ALWAYS_DOWNGRADE,
F_SORT_DEFAULT_FCC_ALPHA,
diff --git a/pith/pine.hlp b/pith/pine.hlp
index 26e5e269..b42db18a 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -4786,7 +4786,8 @@ There are also additional details on
<li><a href="h_config_always_spell_check">FEATURE: <!--#echo var="FEAT_spell-check-before-sending"--></a>
<li><a href="h_config_winpos_in_config">FEATURE: <!--#echo var="FEAT_store-window-position-in-config"--></a>
<li><a href="h_config_strip_sigdashes">FEATURE: <!--#echo var="FEAT_strip-from-sigdashes-on-reply"--></a>
-<li><a href="h_config_strip_ws_before_send">FEATURE: <!--#echo var="FEAT_strip-whitespace-before-send"--></a>
+<li><a href="h_config_strip_ws_before_send">FEATURE: <!--#echo var="FEAT_strip-whitespace-before-send"--></a>
+<li><a href="h_config_enable_topal_hack">FEATURE: <!--#echo var="FEAT_enable-topal-hack"--></a>
<li><a href="h_config_quells_asterisks">FEATURE: <!--#echo var="FEAT_suppress-asterisks-in-password-prompt"--></a>
<li><a href="h_config_quell_attach_ext_warn">FEATURE: <!--#echo var="FEAT_quell-attachment-extension-warn"--></a>
<li><a href="h_config_quell_attach_extra_prompt">FEATURE: <!--#echo var="FEAT_quell-attachment-extra-prompt"--></a>
@@ -30813,6 +30814,21 @@ want headers included in the reply message.
&lt;End of help on this topic&gt;
</BODY>
</HTML>
+====== h_config_enable_topal_hack =====
+<HTML>
+<HEAD>
+<TITLE>FEATURE: <!--#echo var="FEAT_enable-topal-hack"--></TITLE>
+</HEAD>
+<BODY>
+<H1>FEATURE: <!--#echo var="FEAT_enable-topal-hack"--></H1>
+<P>
+This feature allows Topal (and other sending-filters) to change the
+MIME type of the email. This is potentially dangerous because it
+pretends that multipart emails are plain emails.
+<P>
+&lt;End of help on this topic&gt;
+</BODY>
+</HTML>
====== h_config_del_from_dot =====
<HTML>
<HEAD>
diff --git a/pith/send.c b/pith/send.c
index 8d4d419a..95980b88 100644
--- a/pith/send.c
+++ b/pith/send.c
@@ -108,7 +108,7 @@ long post_rfc822_output(char *, ENVELOPE *, BODY *, soutr_t, TCPSTREAM *,
int l_flush_net(int);
int l_putc(int);
int pine_write_header_line(char *, char *, STORE_S *);
-int pine_write_params(PARAMETER *, STORE_S *);
+int pine_write_params(PARAMETER *, STORE_S *, BODY *);
char *tidy_smtp_mess(char *, char *, char *, size_t);
int lmc_body_header_line(char *, int);
int lmc_body_header_finish(void);
@@ -1733,7 +1733,9 @@ call_mailer(METAENV *header, struct mail_bodystruct *body, char **alt_smtp_serve
/* set up counts and such to keep track sent percentage */
send_bytes_sent = 0;
gf_filter_init(); /* zero piped byte count, 'n */
+ dprint((1, "Topal: HERE 1!\n"));
send_bytes_to_send = send_body_size(body); /* count body bytes */
+ dprint((1, "Topal: HERE 2!\n"));
ps_global->c_client_error[0] = error_buf[0] = '\0';
we_cancel = busy_cue(_("Sending mail"),
send_bytes_to_send ? sent_percent : NULL, 0);
@@ -1750,6 +1752,9 @@ call_mailer(METAENV *header, struct mail_bodystruct *body, char **alt_smtp_serve
#endif
+ dprint((1, "Topal: HERE 3!\n"));
+
+
/*
* If the user's asked for it, and we find that the first text
* part (attachments all get b64'd) is non-7bit, ask for 8BITMIME.
@@ -1757,6 +1762,7 @@ call_mailer(METAENV *header, struct mail_bodystruct *body, char **alt_smtp_serve
if(F_ON(F_ENABLE_8BIT, ps_global) && (bp = first_text_8bit(body)))
smtp_opts |= SOP_8BITMIME;
+ dprint((1, "Topal: HERE 3.1!\n"));
#ifdef DEBUG
#ifndef DEBUGJOURNAL
if(debug > 5 || (flags & CM_VERBOSE))
@@ -1820,17 +1826,21 @@ call_mailer(METAENV *header, struct mail_bodystruct *body, char **alt_smtp_serve
}
}
+ dprint((1, "Topal: HERE 4!\n"));
+
/*
* Install our rfc822 output routine
*/
sending_hooks.rfc822_out = mail_parameters(NULL, GET_RFC822OUTPUT, NULL);
(void)mail_parameters(NULL, SET_RFC822OUTPUT, (void *)post_rfc822_output);
+ dprint((1, "Topal: HERE 5!\n"));
/*
* Allow for verbose posting
*/
(void) mail_parameters(NULL, SET_SMTPVERBOSE,
(void *) pine_smtp_verbose_out);
+ dprint((1, "Topal: HERE 6!\n"));
/*
* We do this because we want mm_log to put the error message into
@@ -1874,6 +1884,7 @@ call_mailer(METAENV *header, struct mail_bodystruct *body, char **alt_smtp_serve
ps_global->noshow_error = 0;
+ dprint((1, "Topal: HERE 7!\n"));
TIME_STAMP("smtp open", 1);
if(sending_stream){
unsigned short save_encoding, added_encoding;
@@ -2468,9 +2479,12 @@ write_fcc(char *fcc, CONTEXT_S *fcc_cntxt, STORE_S *tmp_storage,
BODY *
first_text_8bit(struct mail_bodystruct *body)
{
- if(body->type == TYPEMULTIPART) /* advance to first contained part */
+ /* Be careful of Topal changes... */
+ if(body->type == TYPEMULTIPART
+ && body->topal_hack != 1) /* advance to first contained part */
body = &body->nested.part->body;
+ /* Topal: this bit might not be correct, now. */
return((body->type == TYPETEXT && body->encoding != ENC7BIT)
? body : NULL);
}
@@ -2843,6 +2857,7 @@ pine_encode_body (struct mail_bodystruct *body)
char *freethis;
case TYPEMULTIPART: /* multi-part */
+ if (body->topal_hack != 1) { /* But only if Topal hasn't touched it! */
if(!(freethis=parameter_val(body->parameter, "BOUNDARY"))){
char tmp[MAILTMPLEN]; /* make cookie not in BASE64 or QUOTEPRINT*/
@@ -2858,6 +2873,7 @@ pine_encode_body (struct mail_bodystruct *body)
part = body->nested.part; /* encode body parts */
do pine_encode_body (&part->body);
while ((part = part->next) != NULL); /* until done */
+ }
break;
case TYPETEXT :
@@ -4253,7 +4269,9 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
bodyso = (STORE_S *) body->contents.text.data;
- if(body->type == TYPEMULTIPART) { /* multipart gets special handling */
+ if(body->type == TYPEMULTIPART
+ && body->topal_hack != 1) { /* multipart gets special handling,
+ unless Topal messed with it */
part = body->nested.part; /* first body part */
/* find cookie */
for (param = body->parameter; param && !cookie; param = param->next)
@@ -4360,10 +4378,14 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
* BEFORE applying any encoding (rfc1341: appendix G)...
* NOTE: almost all filters expect CRLF newlines
*/
- if(body->type == TYPETEXT
- && body->encoding != ENCBASE64
+ if(((body->type == TYPETEXT
+ && body->encoding != ENCBASE64)
+ /* Or if Topal mucked with it... */
+ | (body->type == TYPEMULTIPART && body->topal_hack == 1))
&& !so_attr(bodyso, "rawbody", NULL)){
- gf_link_filter(gf_local_nvtnl, NULL);
+ if(body->topal_hack == 1)
+ dprint((9, "Topal: Canonical conversion, although Topal has mangled...\n"));
+ gf_link_filter(gf_local_nvtnl, NULL);
}
switch (body->encoding) { /* all else needs filtering */
@@ -4476,7 +4498,7 @@ pine_write_body_header(struct mail_bodystruct *body, soutr_t f, void *s)
return(pwbh_finish(0, so));
if(body->parameter){
- if(!pine_write_params(body->parameter, so))
+ if(!pine_write_params(body->parameter, so, body))
return(pwbh_finish(0, so));
}
else if ((body->type != TYPEMESSAGE
@@ -4558,7 +4580,7 @@ pine_write_body_header(struct mail_bodystruct *body, soutr_t f, void *s)
&& so_puts(so, body->disposition.type)))
return(pwbh_finish(0, so));
- if(!pine_write_params(body->disposition.parameter, so))
+ if(!pine_write_params(body->disposition.parameter, so, body))
return(pwbh_finish(0, so));
if(!so_puts(so, "\015\012"))
@@ -4620,7 +4642,7 @@ pine_write_header_line(char *hdr, char *val, STORE_S *so)
* pine_write_param - convert, encode and write MIME header-field parameters
*/
int
-pine_write_params(PARAMETER *param, STORE_S *so)
+pine_write_params(PARAMETER *param, STORE_S *so, BODY *body)
{
for(; param; param = param->next){
int rv;
@@ -4629,9 +4651,17 @@ pine_write_params(PARAMETER *param, STORE_S *so)
cs = posting_characterset(param->value, NULL, HdrText);
cv = utf8_to_charset(param->value, cs, 0);
- rv = (so_puts(so, "; ")
- && rfc2231_output(so, param->attribute, cv, (char *) tspecials, cs));
-
+ if (body->topal_hack == 1
+ && !struncmp(param->attribute, "protocol", 9)) {
+ /* Did Topal introduce more parameters? */
+ dprint((9, "Topal: parameter encoding of protocol, with Topal hack\n"));
+ rv = (so_puts(so, "; \015\012\011")
+ && rfc2231_output(so, param->attribute, cv, (char *) tspecials, cs));
+ }
+ else
+ rv = (so_puts(so, "; ")
+ && rfc2231_output(so, param->attribute, cv, (char *) tspecials, cs));
+
if(cv && cv != param->value)
fs_give((void **) &cv);
@@ -4738,7 +4768,9 @@ send_body_size(struct mail_bodystruct *body)
long l = 0L;
PART *part;
- if(body->type == TYPEMULTIPART) { /* multipart gets special handling */
+ if(body->type == TYPEMULTIPART
+ && body->topal_hack != 1) { /* multipart gets special handling
+ but again, be careful of Topal */
part = body->nested.part; /* first body part */
do /* for each part */
l += send_body_size(&part->body);