A literal IPv6 address without a trailing bracket will result in a write
past the end of the address buffer:
~~~ segfault.conf
protocols:
(
{ name: "tls"; host: "["; port: "8443"; }
);
~~~
~~~
$ sslh-select -p 127.0.0.1:443 --foreground -F./segfault.conf
[: no closing bracket in IPv6 address?
Segmentation fault (core dumped)
~~~
Do not allocate a 0 byte buffer if no addresses are available:
common.c:122:14: warning: Call to 'malloc' has an allocation size of 0 bytes
*sockfd = malloc(num_addr * sizeof(*sockfd[0]));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This allows people to chroot sslh into a path to further harden it.
We have to rework the user logic a bit because we need to look up
the user details *before* we chroot (as we need to read /etc/passwd
files), but do the actual priv dropping *after* we chroot (so we
have permission to make the actual chroot call).
Similarly, we need to open the syslog before we drop privs because
/dev/log won't be available inside the chroot.
When transparent mode is enabled and sslh listening on :: IPv6 address then
source origin address is propagated to target application independently if
connection is IPv4 or IPv6.
On Linux by default IPv6 socket can accept also IPv4 connections. More
applications, including OpenSSH server do not accept IPv4 connections on
IPv6 socket and therefore such transparent configuration does not work.
On BSD systems it is turned off by default due to security reasons.
This patch disables IPv4 connections on IPv6 listening sockets. If somebody
needs to have sslh listening on both IPv4 and IPv6 addresses, then still it
is possible by specifying multiple --listen arguments.
I think it is more misleading if option --listen :::443 cause listening on
both IPv4 and IPv6 addresses even IPv4 address was not specified. This can
also cause security related problems for people who do not know about this
fact as documentation does not mentioned this behavior.