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 -- <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, "other3 there com", 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, "other4 there com", + 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, "20170113212711 19833 here com", 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, "other4 there com", 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");