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(00000003)
    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);
                }

Reply via email to