diff -rup ssmtp-2.60/ssmtp.c ssmtp-2.60-starttls/ssmtp.c --- ssmtp-2.60/ssmtp.c 2002-12-08 19:26:20.000000000 +0200 +++ ssmtp-2.60-starttls/ssmtp.c 2003-06-09 00:32:24.000000000 +0300 @@ -48,8 +48,12 @@ bool_t minus_t = False; bool_t minus_v = False; bool_t override_from = False; bool_t rewrite_domain = False; +#ifdef HAVE_SSL bool_t use_tls = False; /* Use SSL to transfer mail to HUB */ +bool_t use_starttls = False; /* Use STARTTLS SMTP command to initiate TLS */ bool_t use_cert = False; /* Use a certificate to transfer SSL mail */ +bool_t tls_initialized = False; +#endif #define ARPADATE_LENGTH 32 /* Current date in RFC format */ char arpadate[ARPADATE_LENGTH]; @@ -878,11 +882,24 @@ bool_t read_config() use_tls = False; } - if(log_level > 0) { + if(log_level > 0) { log_event(LOG_INFO, "Set UseTLS=\"%s\"\n", use_tls ? "True" : "False"); } } + else if(strcasecmp(p, "UseSTARTTLS") == 0) { + if(strcasecmp(q, "YES") == 0) { + use_starttls = True; + } + else { + use_starttls = False; + } + + if(log_level > 0) { + log_event(LOG_INFO, + "Set UseSTARTTLS=\"%s\"\n", use_starttls ? "True" : "False"); + } + } else if(strcasecmp(p, "UseTLSCert") == 0) { if(strcasecmp(q, "YES") == 0) { use_cert = True; @@ -920,8 +937,11 @@ bool_t read_config() /* smtp_open() -- Open connection to a remote SMTP listener */ +void smtp_write(int fd, char *format, ...); +int smtp_okay(int fd, char *response); int smtp_open(char *host, int port) { + char buf[(BUF_SZ + 1)]; #ifdef INET6 struct addrinfo hints, *ai0, *ai; char servname[NI_MAXSERV]; @@ -949,7 +969,7 @@ int smtp_open(char *host, int port) return(-1); } - if(use_cert == True) { + if(use_cert == True) { if(SSL_CTX_use_certificate_chain_file(ctx, tls_cert) <= 0) { perror("Use certfile"); return(-1); @@ -1028,11 +1048,24 @@ int smtp_open(char *host, int port) return(-1); } #endif + if(smtp_okay(s, buf) == False) { + log_event(LOG_ERR, "Invalid response SMTP server"); + return(-1); + } #ifdef HAVE_SSL if(use_tls == True) { log_event(LOG_INFO, "Creating SSL connection to host"); + if(use_starttls == True) { + smtp_write(s, "STARTTLS", hostname); + (void)alarm((unsigned) MEDWAIT); + if(smtp_okay(s, buf) == False) { + log_event(LOG_ERR, "STARTTLS failed: %s", buf); + return(-1); + } + } + ssl = SSL_new(ctx); if(!ssl) { log_event(LOG_ERR, "SSL not working"); @@ -1041,12 +1074,13 @@ int smtp_open(char *host, int port) SSL_set_fd(ssl, s); err = SSL_connect(ssl); - if(err < 0) { + if(err < 0) { perror("SSL_connect"); return(-1); } + tls_initialized = True; - if(log_level > 0) { + if(log_level > 0) { log_event(LOG_INFO, "SSL connection using %s", SSL_get_cipher(ssl)); } @@ -1070,7 +1104,7 @@ fd_getc() -- Read a character from an fd ssize_t fd_getc(int fd, void *c) { #ifdef HAVE_SSL - if(use_tls == True) { + if(use_tls == True && tls_initialized == True) { return(SSL_read(ssl, c, 1)); } #endif @@ -1134,10 +1168,10 @@ int smtp_okay(int fd, char *response) /* fd_puts() -- Write characters to fd */ -ssize_t fd_puts(int fd, const void *buf, size_t count) +ssize_t fd_puts(int fd, const void *buf, size_t count) { #ifdef HAVE_SSL - if(use_tls == True) { + if(use_tls == True && tls_initialized == True) { return(SSL_write(ssl, buf, count)); } #endif @@ -1237,9 +1271,6 @@ int ssmtp(char *argv[]) if((sock = smtp_open(mailhost, port)) == -1) { die("Cannot open %s:%d", mailhost, port); } - else if(smtp_okay(sock, buf) == False) { - die("Invalid response SMTP server"); - } /* If user supplied username and password, then try ELHO */ if(auth_user) { diff -rup ssmtp-2.60/ssmtp.conf ssmtp-2.60-starttls/ssmtp.conf --- ssmtp-2.60/ssmtp.conf 2001-05-08 13:22:08.000000000 +0300 +++ ssmtp-2.60-starttls/ssmtp.conf 2003-06-09 00:35:01.000000000 +0300 @@ -30,6 +30,10 @@ hostname=_HOSTNAME_ # Use SSL/TLS to send secure messages to server. #UseTLS=YES +# Use STARTTLS SMTP command to initiate SSL, you should enable UseTLS too +# for this option to work +UseSTARTTLS=YES + # Use SSL/TLS certificate to authenticate against smtp host. #UseTLSCert=YES