This patch fixes dual-stack UDP on Windows as well as for unsual
Linux configurations by ensuring the UDP sockets we create
inherit their IPV6_V6ONLY sockopt from their corresponding
TCP socket. Previously on systems where IPV6_V6ONLY was enabled
by default (e.g. Windows) we would incorrectly create an
IPv6 only socket even though our TCP socket and the system
are dual-stacked.
The dual-stack detection moved from Meta.h to Server.h into the
SslServer class where it is a better fit. Also modified the function
to instead of querying the value of IPV6_V6ONLY on a test socket
it now tries to actively disable it. While previously dual stack
support was only detected if it was the default configuration for
that system, it should now be detected in all cases. The function
also now performs the same check on Windows socket where the default
actually is to have IPV6_V6ONLY enabled.
Some configurations of Qt 5.X explicitly disable deprecated
parts of the API, such as 'QSsl::TlsV1'. To allow Mumble to build
on those configurations, we have to use 'QSsl::TlsV1_0' instead,
like we did in the prior to 71e522f4c4.
This commit also fixes an issue where QSsl::SecureProtocols was only
selected on the base 5.4.0 release, and not subsequent patch releases.
We upstreamed a patch for adding the self-explanatory
QSsl::TlsV1_0OrLater, QSsl::TlsV1_1OrLater and QSsl::TlsV1_2OrLater
enums to QSsl.
Before this, we had a patch in our Qt 5.4 build (on Windows), that
changed the meaning of QSsl::TlsV1_0 to mean "TLSv1.0 or later".
However, that approach wouldn't work in the real world (some setups
require very specific TLS versions), so it was dropped in favour of
the TlsV1_0OrLater and friends.
Since our patch is in Qt 5.5, it means that we now can use
QSsl::TlsV1_0OrLater in the Mumble tree (ifdef'd to QT_VERSION
>= 0x050500), and not break anything for distros.
For Qt 5.4, we can rely on QSsl::SecureProtocols, because Qt 5.4
deprecated SSLv3. Thus, in Qt 5.4, QSsl::SecureProtocols means the
same thing as TlsV1_0OrLater means in Qt 5.5.
Why do we need TlsV1_0OrLater and friends if we have
QSsl::SecureProtocols? Because we don't have a guarantee that
QSsl::SecureProtocols will keep having TLSv1.0 as its minimum
version. The current Mumble protocol requires TLS 1.0.
If something comes up in the future that makes us abandon TLSv1.0,
we'll still handshake it. Rejection can happen at the Mumble protocol
level instead, providing a better user experience.
Qt4's moc is not able to expand QT_VERSION_CHECK which may lead
to invalid codegen when used for backwards compatibility work.
Replaced all occurances with explicit check against numeric
version which are treated correctly. Even though bad interactions
might be rare we should no longer use this macro as long as we
want to compile with Qt 4. Also see:
http://lists.qt-project.org/pipermail/interest/2013-August/008351.html
Without this option (or when it's set to false), Murmur's default
authentication will kick in when your external authenticator plugin
crashes and basically allow *anyone* to login and register.
When it's enabled, Murmur will instead return a temporary login
failure to the client.
Murmur uses the saiTcpLocalAddress field of ServerUser to determine
the correct source address of outgoing UDP packets. On some systems,
such as multi-homed setups, this is important for correct datagram
delivery.
The saiTcpLocalAddress field is initialized when the client first
connects. Its value is extracted from QHostAddress, and then
converted to a sockaddr struct via our own HostAddress class's
toSockAddr method.
HostAddress::toSockAddr is implemented such that any IPv4 address
(including IPv4-mapped IPv6 addresses) will always cause a sockaddr
struct belonging to the AF_INET (IPv4) family to be output. Pure IPv6
addresses will be output as an AF_INET6 sockaddr.
The code that this change touches assumed that it could use the
value of saiTcpLocalAddress directly as the source address in UDP
packets.
This is not always the case. On most systems, Murmur will listen on
[::]:64738 by default, and as such, the address of the server's UDP
socket will be in the AF_INET6 family. Attempting to send packets
with a source address in the AF_INET family using that socket will
cause sendmsg() to return EINVAL on some systems, if not all.
The new code for the sendmsg() code path converts the ServerUser's
saiTcpLocalAddress back into a HostAddress, which, internally, is
fully IPv6. If the input address is IPv4, HostAddress will convert
it to an IPv4-mapped IPv6 address.
When the client's UDP socket is of the AF_INET6 family, we can now
trust that the HostAddress, 'tcpha', is either a real IPv6 address,
or an IPv4-mapped IPv6 address. This allows us to use the 'tcpha'
address regardless of the address family of the saiTcpLocalAddress.
We can simply memcpy it in place.
When the UDP socket is of the AF_INET family, we can only set the
source address if the saiTcpLocalAddress is also AF_INET, or if
it is of the AF_INET6 family and its address is an IPv4-mapped IPv6
address. When a pure IPv6 address is encountered in that path, it is
simply dropped.
Add NestingLimitException to Ice Interface and introduce a new NestingLimit PermissionDenied type.
Addresses #3566322 "ServerDB::deleteServer crashes master"
- Call recheckCodecVersion on AuthenticatedClient disconnect.
- Make every recheckCodecVersions() call switching to Opus send a message to users only supporting CELT.
clearACLCache doesn't just clear the cache, it also adds
some entries, which might be wrong if we're calling it before
changing the channel for a user. Fix this by not using the cache
for the ACL test.
People were able to send a few voice packets to the new channel
prior to being switched to their new channel. Applying the Whisper ACL
before changing the current channel should fix that.
If the server is using a self-signed certificate the strong
certificate check for the client cert will fail with a
"The certificate is self-signed" error even if it's a valid
cert. It looks like Qt is propagating the "error" for the server
certificate to the client cert check. Adding the server certificate
as a CA certificate fixes the problem.
IPv6-mapped IPv4 addresses contain to many zeros to
use XOR without revealing the "key". Switching the
output to a sha1 hash of the random value + the address
solves the problem. We don't include the port in the hash
because it's useful to see which connection attempts were
from the same IP address even if you can't read the actual
value.
Lowering the user limit and raising it again would add duplicate
session IDs to the session ID queue.
Recreate the queue if the limit changes to fix the problem and
ignore IDs which are too high for the new user limit when
someone disconnects.