The current implementation tries too hard to avoid duplication
of very few lines of code.
Instead, use two separate code paths, one for Windows, one for
Unix-like sytems.
This makes it more readable, and allows us to handle system-specific
quirks much easier. For example, SOCKET is unsigned on Windows, and
comparing it to -1 technically works (at least for two's complement
machines), but causes a compiler warning for a signed vs. unsigned
comparison.
Due to a regression in Qt 5, we can't use disconnectSocket(true)
to abort a handshake.
Use non-forceful disconnect to work around the Qt 5 bug.
See inline comment for more details.
Fixesmumble-voip/mumble#2334
And touch up some of its code.
LuaMilkshake reports that it is possible to get
Murmur to emit HTML even when allowhtml is false.
For example via "<br /><b>hello world</>",
which would be translated to "\n<b>hello world</b>"
by the previous HTML filtering code.
Mumble uses QXmlStreamReader to get each token of
an XML document to sanitize it.
Unfortunately, QXmlStreamReader isn't just a tokenizer.
It has a lot of behind-the-scenes XML logic to handle
things such as entities.
Entities definitions are read and handled by the
QXmlStreamReader itself, and are not emitted to a
consumer of QXmlStreamReader. This means that when
QXmlStreamReader gives you a piece of 'text' data,
it will have already translated any entities in the
text and translated them accordingly.
This is why LuaMilkshake's example works.
It is seemingly not possible to get QXmlStreamReader
to avoid handling entities. But I believe we can at
least stop it from allow new entities to be defined.
The original code already did that -- by wrapping
the input XML in a new root tag "<document>". This
ensures that an internal DTD cannot be defined, and
thus that no new entities can be added.
This limits the number of entities we need to
handle, to the small list of default entities
defined by XML: " & &aps; < >.
To ensure that the HTML filter is at least a little
bit effective against these injection attacks, we
ammend the logic of the HTML filter to attmpt to
strip < and > *after* running it through
the original QXmlStreamReader-based filter.
This ensures that no additional HTML elements
can be added via entities.
This commit ensures that a 'suggestversion' is always normalized to a
bitmasked version.
Previously, only a bitmasked 'suggestverson' was allowed.
With this commit, 'suggestversion' may now be either a version string,
or a bitmasked integer value representing the version.
The previous behavior was confusing to users, since the murmur.ini
has always used 'suggestversion' with a version string.
Fixesmumble-voip/mumble#989
The main problem here is that Windows uses types incompatible
to Linux in the setsockopt/getsockopt functions.
This patch works around this by defining TU-local macros to wrap
the types and casts.
This change allows server admins to specify Diffie-Hellman
parameters for Murmur to use. This is done using the sslDHParams
option in the config file. Diffie-Hellman parameters can also be
set on a per-server basis using the sslDHParams option.
Note: the functionality implemented in this change requires the
QSslDiffieHellmanParameters class in Qt, which has not yet landed
upstream in the Qt 5 'dev' branch. This means that the functionality
discussed in this change will, for now, only work in binaries provided
by the Mumble project, or binaries that are built using our build
environments, and not binaries that link against any released versions
of Qt at present.
This change modifies the default TLS cipher suite string to add
EDH+aRSA+AESGCM, DHE-RSA-AES256-SHA and DHE-RSA-AES128-SHA.
This yields the following ciphers, in TLS/RFC notation:
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
This change also allows Murmur servers to provide forward secrecy
to older clients, such as our own pre-built binaries before 1.2.9.
It also provides forward secrecy for users that use Mumble 1.2.x
versions on Linux distros, and other Unix-like systems. This is
because Mumble 1.2.x on Unix-like systems builds against Qt 4, which
limits the connection to TLS 1.0.
Before this change, Murmur was not able to negotiate an ephemeral
Diffie-Hellman key exchange for those clients. This is now possible.
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.