A malicious or compromised IRC server could send data with no end-of-line
(or a flood of "005" messages), making WeeChat accumulate it in a buffer
that grew without limit, until all memory was exhausted.
The unterminated received message and the accumulated "005" (ISUPPORT)
data are now bounded by IRC_SERVER_RECV_MSG_MAX_LENGTH and
IRC_SERVER_ISUPPORT_MAX_LENGTH: extra data is ignored once the limit is
reached.
weecrypto_totp_validate compared the generated and client-supplied OTPs
with strcmp and broke out of the time-window loop on the first match.
Both choices leaked information via response timing: strcmp leaked the
expected OTP digit-by-digit (shrinking the brute-force search from
~10^digits to a handful of guesses within the 30-second window), and
the early break leaked which window offset matched.
Compare in constant time with string_memcmp_constant_time and always
iterate the full window, OR-ing the result into otp_ok without an
early exit.
This affects both relay protocols (which call totp_validate via the
public info hook) and any other caller of the info hook.
The IRC relay protocol's PASS handler compared the server password with
the client-supplied value using strcmp, leaking the password byte-by-byte
via response timing. This is the same class of bug fixed for the api and
weechat protocols, on a separate code path that did not go through
relay_auth_check_password_plain.
Extract the HMAC-then-constant-time-compare logic from
relay_auth_check_password_plain into relay_auth_password_equals, then
use it in both the plain-auth wrapper and the IRC PASS handler.
The relay authentication used non-constant-time comparisons (strcasecmp,
strcmp) to verify password hashes and plaintext passwords, allowing an
attacker to derive the expected hash byte-by-byte from response timing
and then authenticate without knowing the password.
- SHA/PBKDF2 hex hash comparisons: normalize the client-supplied hash to
uppercase and compare in constant time over the fixed expected length.
- Plaintext password comparison: HMAC-SHA256 both passwords with a fresh
per-call random key and compare the fixed-size MACs in constant time,
hiding both per-byte timing and the password length.
Add string_memcmp_constant_time helper in core, exposed via the plugin
API. Bump WEECHAT_PLUGIN_API_VERSION accordingly.
An authenticated relay client using the permessage-deflate websocket
extension could send a small compressed frame that decompresses to an
unbounded amount of data, exhausting all memory and crashing WeeChat.
The output buffer in relay_websocket_inflate is now capped to
WEBSOCKET_INFLATE_MAX_SIZE: frames decompressing beyond this limit are
rejected and the connection is closed.
In commit 9a9a262ea1 we moved from
pkg-config to find_package() to work around a deficiency in the pkgsrc
package manager, which does not ship pkg-config files as intended by
CPython.
Modern CMake discourages use of "FOO_LIBRARIES" in all cases, when
imported "interface" libraries can and should be used instead. The meson
equivalent is `dependency()` versus `cc.find_library()`, so this is
certainly a general trend among modern build systems.
An imported interface target, such as the previous PkgConfig::PYTHON,
carries with it the various internal properties such as DEFINITIONS,
INCLUDE_DIRS, or LIBRARIES, and batch applies them. It also avoids
leaking across cmake 2.x style whole-directory scopes.
Use the documented cmake imported interface target for embedding Python
and avoid `add_definitions(${Python_DEFINITIONS})` and similar. As a
bonus, it's also shorter and more concise.
Fixes: 9a9a262ea1
Fixes: https://github.com/weechat/weechat/pull/2251
Signed-off-by: Eli Schwartz <eschwartz@gentoo.org>
In commit 9a9a262ea1 we moved from
pkg-config to find_package() to work around a deficiency in the pkgsrc
package manager, which does not ship pkg-config files as intended by
CPython. In the process, Gentoo and other platforms that, unlike pkgsrc,
publicly support multiple versions of python installed in parallel, had
python version selection broken. Consequently, weechat linked to the
wrong python, which happened to be installed in build chroots but was
not the versioned python package that the weechat package listed as a
dependency. Attempting to install weechat then broke on some systems
(which installed one version of python as a dependency but actually
linked to a totally different one).
This happens due to a design bug in upstream CMake. It is never
conceptually reasonable to use
```
find_package(Python COMPONENTS ...)
```
and omit the "Interpreter" component; if you do, CMake will ignore its
own documentation on how to control the build to use a specific python,
and choose one randomly (== "latest version available"). If, and only
if, the Interpreter component is checked, the development headers /
libraries for python will be guaranteed consistent with the documented
lookup variables from FindPython.cmake's documentation.
Bug: https://bugs.gentoo.org/968814
Fixes: 9a9a262ea1
Fixes: https://github.com/weechat/weechat/pull/2251
Signed-off-by: Eli Schwartz <eschwartz@gentoo.org>
Move the requirement checks within the respective plugin cmakefile.
Use REQUIRED instead of the manual FOUND check and error handling.
Note: the tcl check was only moved, since using REQUIRED explodes in
CI.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
With CMP0083 introduced with cmake 3.14, as we set the variable
CMAKE_POSITION_INDEPENDENT_CODE we can rely on the build system to do
the correct thing, across all the targets.
Since we require 3.18 (or 3.16 in the patched Debian/Ubuntu version),
which sets the policy to NEW we're all set.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Move the respective include_directories() stansas to the top-level
cmakefile. While this technically adds them to targets where they are
not needed, there is no harm is having them.
This maskes the find_dependency/use_includes/use_libs more consistent
across the board and helps it stand out where it's forgotten. Fixes for
which will be coming at a later date.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Avoid creating/appending variables and effectively deviating from the
style used across the project.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The tcl ones has not been required for over a decade since commit
ffdba5b24 ("Remove check of Tcl_CreateNamespace in cmake build (not used
any more) (bug #27119)").
While the top-level one, with the EXTRA_LIBS reshuffle/consolidation a
few commits ago.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Since commit e98a32373 ("core: check if res_init requires linking with
libresolv") we detect if/when we should be linking against libresolv.
The detection seems a bit clunky (to me), although it's better to keep
things consolidated/consistent across tree. Swap the Darwin checks with
the new token LIBRESOLV_HAS_RES_INIT.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Move the handling to the top-level, adding it _once_ to EXTRA_LIBS.
Thus avoiding some duplication across the board.
Note that final handling varies a bit, namely:
- OpenBSD/intl should be handled via the existing cmake/FindGettext.cmake
- Darwin/resolv should not be needed since commit e98a32373 ("core: check
if res_init requires linking with libresolv")
- the backtrace/execinfo handling has been consolidated and moved
In the unlikely case of unwanted over-linking, the platforms can add
`-Wl,--as-needed` to their linker flags. Something which is strongly
encouraged and has been the default across multiple (linux) distros for
years.
Alternatively, if move quirks are needed they should be handled in a
single place.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Move the handling to the top-level, adding it _once_ to EXTRA_LIBS.
Thus avoiding some duplication across the board.
This change technically adds an extra link for the unit tests, which
seemingly was omitted by mistake. Alternatively, the extra over-linking
won't be an issue in practise.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Move the handling to the top-level, adding it _once_ to EXTRA_LIBS.
Thus avoiding some duplication across the board.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Move the handling to the top-level, adding it _once_ to EXTRA_LIBS.
Thus avoiding some duplication across the board.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
In a handful of places we explicitly use add_dependencies() where the
exact same libraries are also (implicitly) added as dependencies via
target_link_libraries().
Remove the folder, which helps us remove some duplication with follow-up
patches.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>