Mailing List Archive

Transparent SSL/TLS for notqmail/netqmail
I am doing a SSL/TLS implementation for ucspi-tcp for both server and client
side. It offers transparent SSL/TLS for qmail-smtpd, qmail-pop3d, tcpserver
without requiring to change qmail code. The implementation is available as a
patch for ucspi-tcp-0.88

https://sourceforge.net/projects/indimail/files/netqmail-addons/ucspi-tcp/ucspi-tcp-0.88-tls-1.0.patch.gz

The patch provides a new program dotls, which can run under tcpserver before
qmail-smtpd, qmail-pop3d and transparently provide STARTTLS, STLS extension as
well as forced TLS. dotls can do both tls server as well as tls
client. Examples are
below. The default certificate for -n "" option is
/var/qmail/control/servercert.pem.

# provide STARTTLS extension for qmail-smtpd
$ tcpserver 0 25 /usr/bin/dotls -n "" -s smtp qmail-smtpd

# provide SMTPS extension for qmail-smtpd
$ tcpserver 0 465 /usr/bin/dotls -n "" qmail-smtpd

# provide STLS extension for qmail-pop3d
# tcpserver 0 110 /usr/bin/dotls -n "" -s pop3 qmail-popup host \
checkpassword qmail-pop3d Maildir

# provide pop3s service for qmail-pop3d
# tcpserver 0 110 /usr/bin/dotls -n "" qmail-popup host \
checkpassword qmail-pop3d Maildir

This patch also modifies tcpclient to add TLS encryption using openssl
library. This was not necessary but I did it to have a useful program to test
any ssl enabled server like telnet.

The client side TLS for tcpclient also offers both opportunistic and forced
TLS. If you omit the prog argument to tcpclient, it works like openssl
s_client. If you provide -s argument to tcpclient, it works like openssl
sclient -starttls.
The default certificate for -n "" option is /var/qmail/control/clientcert.pem.
Examples are below

# like openssl s_client
$ tcpclient -n "" 0 465

# like openssl s_client -starttls smtp
$ tcpclient -n "" -s smtp 0 25

# like openssl s_client -starttls pop3
$ tcpclient -n "" -s pop3 0 110

# use a tcpclient script to connect to a ssl enabled server
# and use fd 6 to read from net and fd 7 to write to net
$ tcpclient 0 5555 /usr/bin/doit -T -n ""

# use a tcpclient script to connect to a ssl enabled server
# and use fd 0 to read from net and fd 1 to write to net
$ tcpclient 0 5555 /usr/bin/doit -CT -n ""

The program dotls works fine, both opportunistic TLS as well as forced TLS.
But have to apply a workaround for tcpclient -s option to make it work.
Without the workaround, the first time, just after TLS negotiation is complete,
select() tells that there is data to be read from the peer. But on calling
SSL_read(), the read blocks indefinitely, which I suspect is before the SSL
record is not yet complete for decryption. But If I do any SSL_write() first
to the peer, all subsequent SSL_read() return data when select returns.
So as of now I have made tcpclient work with a workaround, but would love
to hear from any of you what I might be missing and doing wrong. The
source code for all the above is at the PR below (same as above but
certificate locations, etc are for indimail-mta). The TLS code is in tls.c,
tls.h, dotls.c and tcpclient.c.

https://github.com/mbhangui/indimail-mta/pull/10

--
Regards Manvendra - http://www.indimail.org
GPG Pub Key
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC7CBC760014D250C
Re: Transparent SSL/TLS for notqmail/netqmail [ In reply to ]
On Mon, 8 Mar 2021 at 18:46, Manvendra Bhangui <mbhangui@gmail.com> wrote:
>
> Without the workaround, the first time, just after TLS negotiation is complete,
> select() tells that there is data to be read from the peer. But on calling
> SSL_read(), the read blocks indefinitely, which I suspect is before the SSL
> record is not yet complete for decryption. But If I do any SSL_write() first
> to the peer, all subsequent SSL_read() return data when select returns.

Fixed the issue. Apparently SSL_read() can block and one should use
non-blocking IO and check if SSL_get_error() returns SSL_ERROR_WANT_READ. If
it does then retry SSL_read(), else go back to the select() loop. Now
tcpclient -r smtp works without any workaround. I have also reduced the
tcpclient code by making the translate() function in tls.c generic and using
that instead of a custom select() loop. Uploaded the changes as

https://sourceforge.net/projects/indimail/files/netqmail-addons/ucspi-tcp/ucspi-tcp-0.88-tls-1.1.patch.gz

--
Regards Manvendra - http://www.indimail.org
GPG Pub Key
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC7CBC760014D250C
Re: Transparent SSL/TLS for notqmail/netqmail [ In reply to ]
On Tue, 9 Mar 2021 at 11:47, Shepherd Nhongo <shepherdzw@gmail.com> wrote:
>
> Good job Manvendra.
>
> Looks good at face value. I am yet to patch & confirm that it works. However your contributions are highly appreciated.
>
> Keep well
>

Thank you. I made one more change in tls.c. Instead of doing return -1 on
EAGAIN, continue SSL_read() in ssl_timeoutio() function and that too
works. The link for new patch is below

https://sourceforge.net/projects/indimail/files/netqmail-addons/ucspi-tcp/ucspi-tcp-0.88-tls-1.2.patch.gz
--
Regards Manvendra - http://www.indimail.org
GPG Pub Key
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC7CBC760014D250C