Hi John Jack:

Am 17.04.17 15:21 schrieb(en) [email protected]:
I have an GMX.net email account. Retrieving email is working. Sending email 
aborts with failure 501. Here is the debugging log:
[snip]
** (balsa:10386): DEBUG: W 'MAIL FROM:<[email protected]> RET=HDRS 
[email protected]'
** (balsa:10386): DEBUG: R '501 Syntax error in parameters or arguments'

Ooops.  You found a bug in the SMTP code.  The GMX server does not support 
Delivery Status Notifications (DSN), but I mistakenly try to configure DSN 
parameters...

The attached patch fixes the following:
- do not set SMTP DSN parameters for a server not supporting it
- fix long delay when sending a message fails in the callback
- improve SMTP unit tests
- improve the test environment script as to place the results readable in the 
cwd

Thanks for pointing me to this issue,
cheers,
Albrecht.
diff --git a/libnetclient/net-client-smtp.c b/libnetclient/net-client-smtp.c
index b55710c..1d4dec1 100644
--- a/libnetclient/net-client-smtp.c
+++ b/libnetclient/net-client-smtp.c
@@ -22,6 +22,7 @@ struct _NetClientSmtpPrivate {
 	NetClientCryptMode crypt_mode;
 	guint auth_allowed[2];			/** 0: encrypted, 1: unencrypted */
 	gboolean can_dsn;
+	gboolean data_state;
 };
 
 
@@ -182,7 +183,7 @@ net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *mess
 		(message->recipients != NULL) && (message->data_callback != NULL), FALSE);
 
 	/* set the RFC 5321 sender and recipient(s) */
-	if (message->have_dsn_rcpt) {
+	if (client->priv->can_dsn && message->have_dsn_rcpt) {
 		if (message->dsn_envid != NULL) {
 			result = net_client_smtp_execute(client, "MAIL FROM:<%s> RET=%s ENVID=%s", NULL, error, message->sender,
 											 (message->dsn_ret_full) ? "FULL" : "HDRS", message->dsn_envid);
@@ -216,6 +217,7 @@ net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *mess
 		gssize count;
 		gchar last_char = '\0';
 
+		client->priv->data_state = TRUE;
 		do {
 			count = message->data_callback(buffer, SMTP_DATA_BUF_SIZE, message->user_data, error);
 			if (count < 0) {
@@ -236,6 +238,7 @@ net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *mess
 
 	if (result) {
 		result = net_client_smtp_read_reply(client, -1, NULL, error);
+		client->priv->data_state = FALSE;
 	}
 
 	return result;
@@ -339,8 +342,11 @@ net_client_smtp_finalise(GObject *object)
 	const NetClientSmtp *client = NET_CLIENT_SMTP(object);
 	const GObjectClass *parent_class = G_OBJECT_CLASS(net_client_smtp_parent_class);
 
-	/* send the 'QUIT' command - no need to evaluate the reply or check for errors */
-	(void) net_client_execute(NET_CLIENT(client), NULL, "QUIT", NULL);
+	/* send the 'QUIT' command unless we are in 'DATA' state where the server will probably fail to reply - no need to evaluate the
+	 * reply or check for errors */
+	if (!client->priv->data_state) {
+		(void) net_client_execute(NET_CLIENT(client), NULL, "QUIT", NULL);
+	}
 
 	g_free(client->priv);
 	(*parent_class->finalize)(object);
diff --git a/libnetclient/test/inetsim.conf b/libnetclient/test/inetsim.conf
index 75e5fa0..4865337 100644
--- a/libnetclient/test/inetsim.conf
+++ b/libnetclient/test/inetsim.conf
@@ -797,7 +797,7 @@ smtps_service_extension		8BITMIME
 smtps_service_extension		SIZE 102400000
 smtps_service_extension		ENHANCEDSTATUSCODES
 smtps_service_extension		AUTH PLAIN LOGIN CRAM-MD5 CRAM-SHA1
-smtps_service_extension		DSN
+#smtps_service_extension		DSN
 smtps_service_extension		ETRN
 #
 
diff --git a/libnetclient/test/start-test-env.sh.in b/libnetclient/test/start-test-env.sh.in
index 5479612..acb8e4b 100644
--- a/libnetclient/test/start-test-env.sh.in
+++ b/libnetclient/test/start-test-env.sh.in
@@ -13,7 +13,11 @@ echo "GnuTLS server w/ client checking @ port 65002 as s_server2..."
 @SCREEN@ -ls
 
 echo "inetsim (as root)..."
-@SUDO@ @INETSIM@ --config inetsim.conf
+@SUDO@ -s -- <<EOF
+rm -f debug.log main.log service.log report.*.txt
+@INETSIM@ --config inetsim.conf --report-dir . --log-dir .
+chmod 666 debug.log main.log service.log report.*.txt
+EOF
 
 echo "shut down GnuTLS servers..."
 @SCREEN@ -S s_server1 -X quit
diff --git a/libnetclient/test/tests.c b/libnetclient/test/tests.c
index 053d48c..9213174 100644
--- a/libnetclient/test/tests.c
+++ b/libnetclient/test/tests.c
@@ -237,6 +237,7 @@ test_basic_crypt(void)
 typedef struct {
 	gchar *msg_text;
 	gchar *read_ptr;
+	gboolean sim_error;
 } msg_data_t;
 
 
@@ -248,17 +249,21 @@ msg_data_cb(gchar *buffer, gsize count, gpointer user_data, GError **error)
 	gssize result;
 
 	g_message("%s(%p, %lu, %p, %p)", __func__, buffer, count, user_data, error);
-	msg_len = strlen(msg_data->read_ptr);
-	if (msg_len > 0) {
-		if (msg_len > count) {
-			result = count;
+	if (msg_data->sim_error) {
+		result = -1;
+	} else {
+		msg_len = strlen(msg_data->read_ptr);
+		if (msg_len > 0) {
+			if (msg_len > count) {
+				result = count;
+			} else {
+				result = msg_len;
+			}
+			memcpy(buffer, msg_data->read_ptr, result);
+			msg_data->read_ptr = &msg_data->read_ptr[result];
 		} else {
-			result = msg_len;
+			result = 0;
 		}
-		memcpy(buffer, msg_data->read_ptr, result);
-		msg_data->read_ptr = &msg_data->read_ptr[result];
-	} else {
-		result = 0;
 	}
 	g_message("%s: return %ld", __func__, result);
 	return result;
@@ -303,6 +308,7 @@ test_smtp(void)
 
 	// message creation
 	msg_buf.msg_text = msg_buf.read_ptr = MSG_TEXT;
+	msg_buf.sim_error = FALSE;
 	sput_fail_unless(net_client_smtp_msg_new(NULL, NULL) == NULL, "create msg: no callback");
 	sput_fail_unless((msg = net_client_smtp_msg_new(msg_data_cb, &msg_buf)) != NULL, "create msg: ok");
 
@@ -379,6 +385,17 @@ test_smtp(void)
 	sput_fail_unless(net_client_smtp_allow_auth(smtp, FALSE, NET_CLIENT_SMTP_AUTH_PLAIN) == TRUE, "force auth meth PLAIN");
 	g_signal_connect(G_OBJECT(smtp), "auth", G_CALLBACK(get_auth), smtp);
 	sput_fail_unless(net_client_smtp_connect(smtp, NULL, NULL) == TRUE, "connect: success");
+	msg_buf.sim_error = TRUE;
+	sput_fail_unless(net_client_smtp_send_msg(smtp, msg, NULL) == FALSE, "send msg: error in callback");
+	msg_buf.sim_error = FALSE;
+	g_object_unref(smtp);
+
+	// unencrypted, PLAIN auth
+	sput_fail_unless((smtp = net_client_smtp_new("localhost", 65025, NET_CLIENT_CRYPT_NONE)) != NULL, "localhost:65025");
+	sput_fail_unless(net_client_smtp_allow_auth(NULL, FALSE, NET_CLIENT_SMTP_AUTH_PLAIN) == FALSE, "set auth meths, no client");
+	sput_fail_unless(net_client_smtp_allow_auth(smtp, FALSE, NET_CLIENT_SMTP_AUTH_PLAIN) == TRUE, "force auth meth PLAIN");
+	g_signal_connect(G_OBJECT(smtp), "auth", G_CALLBACK(get_auth), smtp);
+	sput_fail_unless(net_client_smtp_connect(smtp, NULL, NULL) == TRUE, "connect: success");
 	sput_fail_unless(net_client_smtp_send_msg(smtp, msg, NULL) == TRUE, "send msg: success");
 	g_object_unref(smtp);
 
@@ -407,10 +424,10 @@ test_smtp(void)
 	sput_fail_unless(net_client_smtp_send_msg(smtp, msg, NULL) == TRUE, "send msg: success");
 	g_object_unref(smtp);
 
-	// SSL, CRAM-SHA1 auth
+	// STARTTLS, CRAM-SHA1 auth
 	sput_fail_unless(net_client_smtp_msg_add_recipient(msg, "[email protected]", NET_CLIENT_SMTP_DSN_DELAY) == TRUE,
 		"add recipient ok (dsn)");
-	sput_fail_unless((smtp = net_client_smtp_new("localhost", 65465, NET_CLIENT_CRYPT_ENCRYPTED)) != NULL, "localhost:65025, ssl");
+	sput_fail_unless((smtp = net_client_smtp_new("localhost", 65025, NET_CLIENT_CRYPT_STARTTLS)) != NULL, "localhost:65025");
 	sput_fail_unless(net_client_smtp_allow_auth(smtp, TRUE, NET_CLIENT_SMTP_AUTH_CRAM_SHA1) == TRUE, "force auth meth CRAM-SHA1");
 	g_signal_connect(G_OBJECT(smtp), "cert-check", G_CALLBACK(check_cert), NULL);
 	g_signal_connect(G_OBJECT(smtp), "auth", G_CALLBACK(get_auth), smtp);
@@ -419,10 +436,22 @@ test_smtp(void)
 	sput_fail_unless(net_client_smtp_send_msg(smtp, msg, NULL) == TRUE, "send msg: success");
 	g_object_unref(smtp);
 
+	// STARTTLS, auto select auth
+	sput_fail_unless(net_client_smtp_msg_add_recipient(msg, "[email protected]",
+		NET_CLIENT_SMTP_DSN_SUCCESS + NET_CLIENT_SMTP_DSN_FAILURE + NET_CLIENT_SMTP_DSN_DELAY) == TRUE, "add recipient ok (dsn)");
+	sput_fail_unless((smtp = net_client_smtp_new("localhost", 65025, NET_CLIENT_CRYPT_STARTTLS)) != NULL, "localhost:65025");
+	g_signal_connect(G_OBJECT(smtp), "cert-check", G_CALLBACK(check_cert), NULL);
+	g_signal_connect(G_OBJECT(smtp), "auth", G_CALLBACK(get_auth), smtp);
+	sput_fail_unless(net_client_smtp_connect(smtp, NULL, NULL) == TRUE, "connect: success");
+	sput_fail_unless(net_client_smtp_msg_set_dsn_opts(msg, "[email protected]", TRUE) == TRUE,
+		"dsn: envid, message");
+	sput_fail_unless(net_client_smtp_send_msg(smtp, msg, NULL) == TRUE, "send msg: success");
+	g_object_unref(smtp);
+
 	// SSL, auto select auth
 	sput_fail_unless(net_client_smtp_msg_add_recipient(msg, "[email protected]",
 		NET_CLIENT_SMTP_DSN_SUCCESS + NET_CLIENT_SMTP_DSN_FAILURE + NET_CLIENT_SMTP_DSN_DELAY) == TRUE, "add recipient ok (dsn)");
-	sput_fail_unless((smtp = net_client_smtp_new("localhost", 65465, NET_CLIENT_CRYPT_ENCRYPTED)) != NULL, "localhost:65025, ssl");
+	sput_fail_unless((smtp = net_client_smtp_new("localhost", 65465, NET_CLIENT_CRYPT_ENCRYPTED)) != NULL, "localhost:65465, ssl");
 	g_signal_connect(G_OBJECT(smtp), "cert-check", G_CALLBACK(check_cert), NULL);
 	g_signal_connect(G_OBJECT(smtp), "auth", G_CALLBACK(get_auth), smtp);
 	sput_fail_unless(net_client_smtp_connect(smtp, NULL, NULL) == TRUE, "connect: success");

Attachment: pgp1gM8vlF6uv.pgp
Description: PGP signature

_______________________________________________
balsa-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/balsa-list

Reply via email to