# HG changeset patch # User meillo@marmaro.de # Date 1279834205 -7200 # Node ID 349518b940dbbcfdf3be308b76de6a1bb66e9e1a # Parent 0f0e4e7cd762e789a5ad5213d5ac88c5dee9d135 added support for STARTTLS wrappers added the route config option `instant_helo' which causes masqmail, as SMTP client, not to wait for the server's 220 greeting. Instead if says EHLO right at once. You'll need this for STARTTLS wrappers that usually eat the greeting line. diff -r 0f0e4e7cd762 -r 349518b940db man/masqmail.route.5 --- a/man/masqmail.route.5 Mon Jul 19 14:01:13 2010 +0200 +++ b/man/masqmail.route.5 Thu Jul 22 23:30:05 2010 +0200 @@ -74,6 +74,23 @@ the \fBhelo_name\fR (see above) will be used. .TP +\fBinstant_helo\fR = \fIboolean\fR + +If this is set, masqmail does not wait for the greeting of the SMTP server +after opening the connection. +Instead it says EHLO right away (ESMTP is assumed). +Use this option with wrappers that eat the 220 greeting of the SMTP server. +Common examples are STARTTLS wrappers, like `openssl -starttls smtp ...'. + +If this option is set and a 220 greeting is received though, +everything should still work. +Please don't rely on that and keep in mind that RFC 2821 says that the client +SHOULD wait for the 220 greeting of the server. + +Default: false + + +.TP \fBdo_pipelining\fR = \fIboolean\fR If this is set to false, masqmail will not use ESMTP PIPELINING, diff -r 0f0e4e7cd762 -r 349518b940db src/conf.c --- a/src/conf.c Mon Jul 19 14:01:13 2010 +0200 +++ b/src/conf.c Thu Jul 22 23:30:05 2010 +0200 @@ -650,6 +650,8 @@ route->connect_error_fail = parse_boolean(rval); else if (strcmp(lval, "do_correct_helo") == 0) route->do_correct_helo = parse_boolean(rval); + else if (strcmp(lval, "instant_helo") == 0) + route->instant_helo = parse_boolean(rval); else if (strcmp(lval, "do_pipelining") == 0) route->do_pipelining = parse_boolean(rval); else if (strcmp(lval, "allowed_return_paths") == 0) diff -r 0f0e4e7cd762 -r 349518b940db src/deliver.c --- a/src/deliver.c Mon Jul 19 14:01:13 2010 +0200 +++ b/src/deliver.c Thu Jul 22 23:30:05 2010 +0200 @@ -353,7 +353,7 @@ if ((route->auth_name) && (route->auth_login) && (route->auth_secret)) set_auth(psb, route->auth_name, route->auth_login, route->auth_secret); #endif - if (smtp_out_init(psb)) { + if (smtp_out_init(psb, route->instant_helo)) { if (!route->do_pipelining) psb->use_pipelining = FALSE; diff -r 0f0e4e7cd762 -r 349518b940db src/masqmail.h --- a/src/masqmail.h Mon Jul 19 14:01:13 2010 +0200 +++ b/src/masqmail.h Thu Jul 22 23:30:05 2010 +0200 @@ -99,6 +99,7 @@ gchar *helo_name; gboolean do_correct_helo; + gboolean instant_helo; gboolean do_pipelining; gchar *set_h_from_domain; diff -r 0f0e4e7cd762 -r 349518b940db src/smtp_out.c --- a/src/smtp_out.c Mon Jul 19 14:01:13 2010 +0200 +++ b/src/smtp_out.c Thu Jul 22 23:30:05 2010 +0200 @@ -231,11 +231,22 @@ static gboolean check_helo_response(smtp_base * psb) { - gchar *ptr = psb->buffer; + gchar *ptr; if (!check_response(psb, FALSE)) return FALSE; + if (psb->last_code == 220) { + logwrite(LOG_NOTICE, "received a 220 greeting after sending EHLO,\n"); + logwrite(LOG_NOTICE, "please remove `instant_helo' from your route config\n"); + /* read the next response, cause that's the actual helo response */ + if (!read_response(psb, SMTP_CMD_TIMEOUT) || !check_response(psb, FALSE)) { + return FALSE; + } + } + + ptr = psb->buffer; + while (*ptr) { if (strncasecmp(&(ptr[4]), "SIZE", 4) == 0) { gchar *arg; @@ -668,24 +679,35 @@ #endif gboolean -smtp_out_init(smtp_base * psb) +smtp_out_init(smtp_base * psb, gboolean instant_helo) { gboolean ok; - if ((ok = read_response(psb, SMTP_INITIAL_TIMEOUT))) { - if ((ok = check_init_response(psb))) { + logwrite(LOG_INFO, "smtp_out_init(): instant_helo:%d\n", instant_helo); - if ((ok = smtp_helo(psb, psb->helo_name))) { + if (instant_helo) { + /* we say hello right away, hence we don't know if + ESMTP is supported; we just assume it */ + psb->use_esmtp = 1; + } else { + if ((ok = read_response(psb, SMTP_INITIAL_TIMEOUT))) { + ok = check_init_response(psb); + } + if (!ok) { + smtp_out_log_failure(psb, NULL); + return ok; + } + } + + if ((ok = smtp_helo(psb, psb->helo_name))) { #ifdef ENABLE_AUTH - if (psb->auth_name && psb->use_auth) { - /* we completely disregard the response of server here. If - authentication fails, the server will complain later - anyway. I know, this is not polite... */ - smtp_out_auth(psb); - } + if (psb->auth_name && psb->use_auth) { + /* we completely disregard the response of server here. If + authentication fails, the server will complain later + anyway. I know, this is not polite... */ + smtp_out_auth(psb); + } #endif - } - } } if (!ok) smtp_out_log_failure(psb, NULL); @@ -899,7 +921,7 @@ if ((psb = smtp_out_open(host, port, resolve_list))) { set_heloname(psb, return_path->domain, TRUE); /* initiate connection, send message and quit: */ - if (smtp_out_init(psb)) { + if (smtp_out_init(psb, FALSE)) { smtp_out_msg(psb, msg, return_path, rcpt_list, NULL); if (psb->error == smtp_ok || (psb->error == smtp_fail) || (psb->error == smtp_trylater) || (psb->error == smtp_syntax) || (psb->error == smtp_cancel)) diff -r 0f0e4e7cd762 -r 349518b940db src/smtp_out.h --- a/src/smtp_out.h Mon Jul 19 14:01:13 2010 +0200 +++ b/src/smtp_out.h Thu Jul 22 23:30:05 2010 +0200 @@ -77,7 +77,7 @@ smtp_base *smtp_out_open(gchar * host, gint port, GList * resolve_list); smtp_base *smtp_out_open_child(gchar * cmd); gboolean smtp_out_rset(smtp_base * psb); -gboolean smtp_out_init(smtp_base * psb); +gboolean smtp_out_init(smtp_base * psb, gboolean instant_helo); gint smtp_out_msg(smtp_base * psb, message * msg, address * return_path, GList * rcpt_list, GList * hdr_list); gboolean smtp_out_quit(smtp_base * psb);