Some SMTP servers require a HELO/EHLO command before a STARTTLS,
e.g.:
$ telnet mail.sourceforge.net 25
220 mail.sourceforge.net ESMTP Exim 4.44 ...
STARTTLS
503 STARTTLS command used when not advertised
for instance, when I try to retrieve the server certificate for
mail.sourceforge.net:25 using `-starttls smtp -showcerts':
$ openssl s_client -connect mail.sourceforge.net:25 \
-starttls smtp -CApath /etc/ssl/certs -showcerts
it fails with an error message like:
CONNECTED(0003)
9829:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown
protocol:s23_clnt.c:567:
The attached patch (against openssl-0.9.8a) adds the `-ehlo'
option to s_client:
-ehlo hostname - use the EHLO smtp command before issuing STARTTLS
(to be used in conjunction with -starttls smtp)
with this patch, s_client successfully connects and shows the
certificate:
$ openssl s_client -connect mail.sourceforge.net:25 -showcerts
-starttls smtp -ehlo host.domain -CApath /etc/ssl/certs
...
Verify return code: 0 (ok)
---
220 mail.sourceforge.net ESMTP Exim 4.44 Tue, 27 Dec 2005 10:58:18 -0800
sc8-sf-mx1.sourceforge.net
250-mail.sourceforge.net Hello ppp85-140-15-108.pppoe.mtu-net.ru [85.140.15.108]
250-SIZE 1048576
250-EXPN
250-PIPELINING
250-STARTTLS
250 HELP
--
Pavel Gorshkov
--- openssl-0.9.8a.orig/apps/s_client.c Sat Oct 1 03:38:19 2005
+++ openssl-0.9.8a/apps/s_client.c Tue Dec 27 18:43:52 2005
@@ -227,6 +227,8 @@
BIO_printf(bio_err," for those protocols that support
it, where\n");
BIO_printf(bio_err," 'prot' defines which one to
assume. Currently,\n");
BIO_printf(bio_err," only \"smtp\" and \"pop3\" are
supported.\n");
+ BIO_printf(bio_err," -ehlo hostname - use the EHLO smtp command before
issuing STARTTLS\n");
+ BIO_printf(bio_err," (to be used in conjunction with
-starttls smtp)\n");
#ifndef OPENSSL_NO_ENGINE
BIO_printf(bio_err," -engine id- Initialise and use the specified
engine\n");
#endif
@@ -245,6 +247,7 @@
char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
int cbuf_len,cbuf_off;
int sbuf_len,sbuf_off;
+ int mbuf_off;
fd_set readfds,writefds;
short port=PORT;
int full_log=1;
@@ -261,6 +264,7 @@
SSL_CTX *ctx=NULL;
int ret=1,in_init=1,i,nbio_test=0;
int starttls_proto = 0;
+ char *ehlo_hostname=NULL;
int prexit = 0, vflags = 0;
SSL_METHOD *meth=NULL;
#ifdef sock_type
@@ -472,6 +476,11 @@
else
goto bad;
}
+ else if (strcmp(*argv,"-ehlo") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ehlo_hostname = *++argv;
+ }
#ifndef OPENSSL_NO_ENGINE
else if (strcmp(*argv,"-engine") == 0)
{
@@ -717,11 +726,17 @@
cbuf_off=0;
sbuf_len=0;
sbuf_off=0;
+ mbuf_off=0;
/* This is an ugly hack that does a lot of assumptions */
if (starttls_proto == 1)
{
- BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf_off = BIO_read(sbio,mbuf,BUFSIZZ);
+ if (ehlo_hostname)
+ {
+ BIO_printf(sbio,"EHLO %s\r\n",ehlo_hostname);
+ BIO_read(sbio,mbuf+mbuf_off,BUFSIZZ-mbuf_off);
+ }
BIO_printf(sbio,"STARTTLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}