[evolution-data-server] I#123 - [SMTP] Ignore 8BITMIME extension for Yahoo! servers
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#123 - [SMTP] Ignore 8BITMIME extension for Yahoo! servers
- Date: Thu, 30 May 2019 16:12:24 +0000 (UTC)
commit 76834cf20a8c1139791b17ca8c3182dc2a6cb474
Author: Milan Crha <mcrha redhat com>
Date: Thu May 30 18:14:10 2019 +0200
I#123 - [SMTP] Ignore 8BITMIME extension for Yahoo! servers
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/123
src/camel/camel-mime-message.c | 31 +++++++++++-----
src/camel/camel-mime-message.h | 23 ++++++++++++
src/camel/providers/smtp/camel-smtp-transport.c | 49 +++++++++++++++++++++----
3 files changed, 85 insertions(+), 18 deletions(-)
---
diff --git a/src/camel/camel-mime-message.c b/src/camel/camel-mime-message.c
index 6b47793a5..319782cea 100644
--- a/src/camel/camel-mime-message.c
+++ b/src/camel/camel-mime-message.c
@@ -860,13 +860,11 @@ camel_mime_message_get_source (CamelMimeMessage *message)
return src;
}
-typedef gboolean (*CamelPartFunc)(CamelMimeMessage *message, CamelMimePart *part, CamelMimePart
*parent_part, gpointer data);
-
static gboolean
message_foreach_part_rec (CamelMimeMessage *msg,
CamelMimePart *part,
CamelMimePart *parent_part,
- CamelPartFunc callback,
+ CamelForeachPartFunc callback,
gpointer data)
{
CamelDataWrapper *containee;
@@ -896,14 +894,27 @@ message_foreach_part_rec (CamelMimeMessage *msg,
return go;
}
-/* dont make this public yet, it might need some more thinking ... */
-/* MPZ */
-static void
-camel_mime_message_foreach_part (CamelMimeMessage *msg,
- CamelPartFunc callback,
- gpointer data)
+/**
+ * camel_mime_message_foreach_part:
+ * @message: a #CamelMimeMessage
+ * @callback: (scope call): a #CamelForeachPartFunc callback to call for each part
+ * @user_data: (closure callback): user data passed to the @callback
+ *
+ * Calls @callback for each part of the @message, including the message itself.
+ * The traverse of the @message parts can be stopped when the @callback
+ * returns %FALSE.
+ *
+ * Since: 3.34
+ **/
+void
+camel_mime_message_foreach_part (CamelMimeMessage *message,
+ CamelForeachPartFunc callback,
+ gpointer user_data)
{
- message_foreach_part_rec (msg, (CamelMimePart *) msg, NULL, callback, data);
+ g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+ g_return_if_fail (callback != NULL);
+
+ message_foreach_part_rec (message, CAMEL_MIME_PART (message), NULL, callback, user_data);
}
static gboolean
diff --git a/src/camel/camel-mime-message.h b/src/camel/camel-mime-message.h
index d10f9c2ac..f6770252e 100644
--- a/src/camel/camel-mime-message.h
+++ b/src/camel/camel-mime-message.h
@@ -119,6 +119,29 @@ void camel_mime_message_set_source (CamelMimeMessage *message,
const gchar * camel_mime_message_get_source (CamelMimeMessage *message);
/* utility functions */
+
+/**
+ * CamelForeachPartFunc:
+ * @message: a #CamelMimeMessage
+ * @part: a #CamelMimePart, for which the function is called
+ * @parent_part: (nullable): a #CamelMimePart, parent of the @part; can be %NULL
+ * @user_data: user data, as passed to camel_mime_message_foreach_part()
+ *
+ * Callback used to traverse parts of the @message using camel_mime_message_foreach_part().
+ *
+ * Returns: %TRUE, when the traverse should continue, %FALSE to stop
+ * traversing parts of the @message
+ *
+ * Since: 3.34
+ **/
+typedef gboolean (* CamelForeachPartFunc) (CamelMimeMessage *message,
+ CamelMimePart *part,
+ CamelMimePart *parent_part,
+ gpointer user_data);
+
+void camel_mime_message_foreach_part (CamelMimeMessage *message,
+ CamelForeachPartFunc callback,
+ gpointer user_data);
gboolean camel_mime_message_has_8bit_parts
(CamelMimeMessage *message);
void camel_mime_message_set_best_encoding
diff --git a/src/camel/providers/smtp/camel-smtp-transport.c b/src/camel/providers/smtp/camel-smtp-transport.c
index ca3f6a768..b459b14fa 100644
--- a/src/camel/providers/smtp/camel-smtp-transport.c
+++ b/src/camel/providers/smtp/camel-smtp-transport.c
@@ -77,6 +77,7 @@ static GHashTable * esmtp_get_authtypes (const guchar *buffer);
static gboolean smtp_helo (CamelSmtpTransport *transport,
CamelStreamBuffer *istream,
CamelStream *ostream,
+ gboolean ignore_8bitmime,
GCancellable *cancellable,
GError **error);
static gboolean smtp_mail (CamelSmtpTransport *transport,
@@ -178,6 +179,7 @@ connect_to_server (CamelService *service,
GIOStream *tls_stream;
gchar *respbuf = NULL;
gboolean success = TRUE;
+ gboolean ignore_8bitmime;
gchar *host;
if (!CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class)->
@@ -247,9 +249,11 @@ connect_to_server (CamelService *service,
} while (*(respbuf+3) == '-'); /* if we got "220-" then loop again */
g_free (respbuf);
+ ignore_8bitmime = host && camel_strstrcase (host, "yahoo.com");
+
/* Try sending EHLO */
transport->flags |= CAMEL_SMTP_TRANSPORT_IS_ESMTP;
- if (!smtp_helo (transport, istream, ostream, cancellable, error)) {
+ if (!smtp_helo (transport, istream, ostream, ignore_8bitmime, cancellable, error)) {
if (!transport->connected) {
success = FALSE;
goto exit;
@@ -259,7 +263,7 @@ connect_to_server (CamelService *service,
g_clear_error (error);
transport->flags &= ~CAMEL_SMTP_TRANSPORT_IS_ESMTP;
- if (!smtp_helo (transport, istream, ostream, cancellable, error)) {
+ if (!smtp_helo (transport, istream, ostream, ignore_8bitmime, cancellable, error)) {
success = FALSE;
goto exit;
}
@@ -331,7 +335,7 @@ connect_to_server (CamelService *service,
/* We are supposed to re-EHLO after a successful STARTTLS to
* re-fetch any supported extensions. */
- if (!smtp_helo (transport, istream, ostream, cancellable, error)) {
+ if (!smtp_helo (transport, istream, ostream, ignore_8bitmime, cancellable, error)) {
success = FALSE;
}
@@ -854,6 +858,25 @@ smtp_transport_query_auth_types_sync (CamelService *service,
return sasl_types;
}
+static gboolean
+message_has_8bit_or_qp_part_cb (CamelMimeMessage *message,
+ CamelMimePart *part,
+ CamelMimePart *parent_part,
+ gpointer user_data)
+{
+ CamelTransferEncoding encoding;
+ gint *has8bit = user_data;
+
+ /* check this part, and stop as soon as we are done */
+ encoding = camel_mime_part_get_encoding (part);
+
+ *has8bit = encoding == CAMEL_TRANSFER_ENCODING_8BIT ||
+ encoding == CAMEL_TRANSFER_ENCODING_BINARY ||
+ encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE;
+
+ return !(*has8bit);
+}
+
static gboolean
smtp_transport_send_to_sync (CamelTransport *transport,
CamelMimeMessage *message,
@@ -867,7 +890,7 @@ smtp_transport_send_to_sync (CamelTransport *transport,
CamelInternetAddress *cia;
CamelStreamBuffer *istream;
CamelStream *ostream;
- gboolean has_8bit_parts;
+ gboolean has_8bit_parts = FALSE;
const gchar *addr;
gint i, len;
@@ -897,8 +920,8 @@ smtp_transport_send_to_sync (CamelTransport *transport,
camel_operation_push_message (cancellable, _("Sending message"));
- /* find out if the message has 8bit mime parts */
- has_8bit_parts = camel_mime_message_has_8bit_parts (message);
+ /* find out if the message has 8bit mime parts; quoted-printable are reencoded to 8bit too */
+ camel_mime_message_foreach_part (message, message_has_8bit_or_qp_part_cb, &has_8bit_parts);
/* If the connection needs a ReSET, then do so */
if (smtp_transport->need_rset &&
@@ -1358,10 +1381,12 @@ static gboolean
smtp_helo (CamelSmtpTransport *transport,
CamelStreamBuffer *istream,
CamelStream *ostream,
+ gboolean ignore_8bitmime,
GCancellable *cancellable,
GError **error)
{
gchar *name = NULL, *cmdbuf = NULL, *respbuf = NULL;
+ gboolean first_line = TRUE;
const gchar *token;
GResolver *resolver;
GInetAddress *address;
@@ -1446,9 +1471,17 @@ smtp_helo (CamelSmtpTransport *transport,
token = respbuf + 4;
+ if (first_line) {
+ ignore_8bitmime = ignore_8bitmime || camel_strstrcase (token, "yahoo.com") != NULL;
+ first_line = FALSE;
+ }
+
if (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP) {
if (!g_ascii_strncasecmp (token, "8BITMIME", 8)) {
- transport->flags |= CAMEL_SMTP_TRANSPORT_8BITMIME;
+ if (ignore_8bitmime)
+ d (fprintf (stderr, "[SMTP] Ignoring 8BITMIME extension\n"));
+ else
+ transport->flags |= CAMEL_SMTP_TRANSPORT_8BITMIME;
} else if (!g_ascii_strncasecmp (token, "ENHANCEDSTATUSCODES", 19)) {
transport->flags |= CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES;
} else if (!g_ascii_strncasecmp (token, "STARTTLS", 8)) {
@@ -1505,7 +1538,7 @@ smtp_mail (CamelSmtpTransport *transport,
/* we gotta tell the smtp server who we are. (our email addy) */
gchar *cmdbuf, *respbuf = NULL;
- if (transport->flags & CAMEL_SMTP_TRANSPORT_8BITMIME && has_8bit_parts)
+ if ((transport->flags & CAMEL_SMTP_TRANSPORT_8BITMIME) && has_8bit_parts)
cmdbuf = g_strdup_printf ("MAIL FROM:<%s> BODY=8BITMIME\r\n", sender);
else
cmdbuf = g_strdup_printf ("MAIL FROM:<%s>\r\n", sender);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]