masqmail-0.2

changeset 171:349518b940db

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.
author meillo@marmaro.de
date Thu, 22 Jul 2010 23:30:05 +0200
parents 0f0e4e7cd762
children ed96d7054b9b
files man/masqmail.route.5 src/conf.c src/deliver.c src/masqmail.h src/smtp_out.c src/smtp_out.h
diffstat 6 files changed, 58 insertions(+), 16 deletions(-) [+]
line diff
     1.1 --- a/man/masqmail.route.5	Mon Jul 19 14:01:13 2010 +0200
     1.2 +++ b/man/masqmail.route.5	Thu Jul 22 23:30:05 2010 +0200
     1.3 @@ -74,6 +74,23 @@
     1.4  the \fBhelo_name\fR (see above) will be used.
     1.5  
     1.6  .TP
     1.7 +\fBinstant_helo\fR = \fIboolean\fR
     1.8 +
     1.9 +If this is set, masqmail does not wait for the greeting of the SMTP server
    1.10 +after opening the connection.
    1.11 +Instead it says EHLO right away (ESMTP is assumed).
    1.12 +Use this option with wrappers that eat the 220 greeting of the SMTP server.
    1.13 +Common examples are STARTTLS wrappers, like `openssl -starttls smtp ...'.
    1.14 +
    1.15 +If this option is set and a 220 greeting is received though,
    1.16 +everything should still work.
    1.17 +Please don't rely on that and keep in mind that RFC 2821 says that the client
    1.18 +SHOULD wait for the 220 greeting of the server.
    1.19 +
    1.20 +Default: false
    1.21 +
    1.22 +
    1.23 +.TP
    1.24  \fBdo_pipelining\fR = \fIboolean\fR
    1.25  
    1.26  If this is set to false, masqmail will not use ESMTP PIPELINING,
     2.1 --- a/src/conf.c	Mon Jul 19 14:01:13 2010 +0200
     2.2 +++ b/src/conf.c	Thu Jul 22 23:30:05 2010 +0200
     2.3 @@ -650,6 +650,8 @@
     2.4  			route->connect_error_fail = parse_boolean(rval);
     2.5  		else if (strcmp(lval, "do_correct_helo") == 0)
     2.6  			route->do_correct_helo = parse_boolean(rval);
     2.7 +		else if (strcmp(lval, "instant_helo") == 0)
     2.8 +			route->instant_helo = parse_boolean(rval);
     2.9  		else if (strcmp(lval, "do_pipelining") == 0)
    2.10  			route->do_pipelining = parse_boolean(rval);
    2.11  		else if (strcmp(lval, "allowed_return_paths") == 0)
     3.1 --- a/src/deliver.c	Mon Jul 19 14:01:13 2010 +0200
     3.2 +++ b/src/deliver.c	Thu Jul 22 23:30:05 2010 +0200
     3.3 @@ -353,7 +353,7 @@
     3.4  		if ((route->auth_name) && (route->auth_login) && (route->auth_secret))
     3.5  			set_auth(psb, route->auth_name, route->auth_login, route->auth_secret);
     3.6  #endif
     3.7 -		if (smtp_out_init(psb)) {
     3.8 +		if (smtp_out_init(psb, route->instant_helo)) {
     3.9  
    3.10  			if (!route->do_pipelining)
    3.11  				psb->use_pipelining = FALSE;
     4.1 --- a/src/masqmail.h	Mon Jul 19 14:01:13 2010 +0200
     4.2 +++ b/src/masqmail.h	Thu Jul 22 23:30:05 2010 +0200
     4.3 @@ -99,6 +99,7 @@
     4.4  
     4.5  	gchar *helo_name;
     4.6  	gboolean do_correct_helo;
     4.7 +	gboolean instant_helo;
     4.8  	gboolean do_pipelining;
     4.9  
    4.10  	gchar *set_h_from_domain;
     5.1 --- a/src/smtp_out.c	Mon Jul 19 14:01:13 2010 +0200
     5.2 +++ b/src/smtp_out.c	Thu Jul 22 23:30:05 2010 +0200
     5.3 @@ -231,11 +231,22 @@
     5.4  static gboolean
     5.5  check_helo_response(smtp_base * psb)
     5.6  {
     5.7 -	gchar *ptr = psb->buffer;
     5.8 +	gchar *ptr;
     5.9  
    5.10  	if (!check_response(psb, FALSE))
    5.11  		return FALSE;
    5.12  
    5.13 +	if (psb->last_code == 220) {
    5.14 +		logwrite(LOG_NOTICE, "received a 220 greeting after sending EHLO,\n");
    5.15 +		logwrite(LOG_NOTICE, "please remove `instant_helo' from your route config\n");
    5.16 +		/* read the next response, cause that's the actual helo response */
    5.17 +		if (!read_response(psb, SMTP_CMD_TIMEOUT) || !check_response(psb, FALSE)) {
    5.18 +			return FALSE;
    5.19 +		}
    5.20 +	}
    5.21 +
    5.22 +	ptr = psb->buffer;
    5.23 +
    5.24  	while (*ptr) {
    5.25  		if (strncasecmp(&(ptr[4]), "SIZE", 4) == 0) {
    5.26  			gchar *arg;
    5.27 @@ -668,24 +679,35 @@
    5.28  #endif
    5.29  
    5.30  gboolean
    5.31 -smtp_out_init(smtp_base * psb)
    5.32 +smtp_out_init(smtp_base * psb, gboolean instant_helo)
    5.33  {
    5.34  	gboolean ok;
    5.35  
    5.36 -	if ((ok = read_response(psb, SMTP_INITIAL_TIMEOUT))) {
    5.37 -		if ((ok = check_init_response(psb))) {
    5.38 +	logwrite(LOG_INFO, "smtp_out_init(): instant_helo:%d\n", instant_helo);
    5.39  
    5.40 -			if ((ok = smtp_helo(psb, psb->helo_name))) {
    5.41 +	if (instant_helo) {
    5.42 +		/* we say hello right away, hence we don't know if
    5.43 +		   ESMTP is supported; we just assume it */
    5.44 +		psb->use_esmtp = 1;
    5.45 +	} else {
    5.46 +		if ((ok = read_response(psb, SMTP_INITIAL_TIMEOUT))) {
    5.47 +			ok = check_init_response(psb);
    5.48 +		}
    5.49 +		if (!ok) {
    5.50 +			smtp_out_log_failure(psb, NULL);
    5.51 +			return ok;
    5.52 +		}
    5.53 +	}
    5.54 +
    5.55 +	if ((ok = smtp_helo(psb, psb->helo_name))) {
    5.56  #ifdef ENABLE_AUTH
    5.57 -				if (psb->auth_name && psb->use_auth) {
    5.58 -					/* we completely disregard the response of server here. If
    5.59 -					   authentication fails, the server will complain later
    5.60 -					   anyway. I know, this is not polite... */
    5.61 -					smtp_out_auth(psb);
    5.62 -				}
    5.63 +		if (psb->auth_name && psb->use_auth) {
    5.64 +			/* we completely disregard the response of server here. If
    5.65 +			   authentication fails, the server will complain later
    5.66 +			   anyway. I know, this is not polite... */
    5.67 +			smtp_out_auth(psb);
    5.68 +		}
    5.69  #endif
    5.70 -			}
    5.71 -		}
    5.72  	}
    5.73  	if (!ok)
    5.74  		smtp_out_log_failure(psb, NULL);
    5.75 @@ -899,7 +921,7 @@
    5.76  	if ((psb = smtp_out_open(host, port, resolve_list))) {
    5.77  		set_heloname(psb, return_path->domain, TRUE);
    5.78  		/* initiate connection, send message and quit: */
    5.79 -		if (smtp_out_init(psb)) {
    5.80 +		if (smtp_out_init(psb, FALSE)) {
    5.81  			smtp_out_msg(psb, msg, return_path, rcpt_list, NULL);
    5.82  			if (psb->error == smtp_ok || (psb->error == smtp_fail) || (psb->error == smtp_trylater)
    5.83  			    || (psb->error == smtp_syntax) || (psb->error == smtp_cancel))
     6.1 --- a/src/smtp_out.h	Mon Jul 19 14:01:13 2010 +0200
     6.2 +++ b/src/smtp_out.h	Thu Jul 22 23:30:05 2010 +0200
     6.3 @@ -77,7 +77,7 @@
     6.4  smtp_base *smtp_out_open(gchar * host, gint port, GList * resolve_list);
     6.5  smtp_base *smtp_out_open_child(gchar * cmd);
     6.6  gboolean smtp_out_rset(smtp_base * psb);
     6.7 -gboolean smtp_out_init(smtp_base * psb);
     6.8 +gboolean smtp_out_init(smtp_base * psb, gboolean instant_helo);
     6.9  gint smtp_out_msg(smtp_base * psb, message * msg, address * return_path, GList * rcpt_list, GList * hdr_list);
    6.10  gboolean smtp_out_quit(smtp_base * psb);
    6.11