5981 Commits

Author SHA1 Message Date
ZNC-Jenkins 2cc7197c38 Update translations from Crowdin for bg_BG da_DK de_DE el_GR es_ES fr_FR id_ID it_IT nl_NL pl_PL pt_BR pt_PT ro_RO ru_RU tr_TR 2026-06-10 00:26:19 +00:00
Alexey Sokolov e7919287fe Merge pull request #2021 from dxbjavid/copy-preserve-mode
fileutils: open Copy() destination at the source's mode
2026-06-09 23:24:33 +01:00
Alexey Sokolov 16062c87b1 Merge pull request #2020 from rootvector2/identfile-bound-spoof-read
identfile: read original spoof with ReadFile
2026-06-09 22:47:40 +01:00
rootvector2 02031f5173 fileutils: mark CFile::Read as [[nodiscard]]
Read()'s return value is the only bound on how many bytes are valid in
the caller's buffer; ignoring it is what caused the identfile OOB read.
All existing callers already use the result, so flag the rest at compile
time.
2026-06-09 17:14:32 +05:30
rootvector2 28b9971e83 identfile: read original spoof with ReadFile
Read() returned up to 1024 bytes into a stack buffer that was then
assigned to a CString via the const char* overload, so strlen() walked
past the end of buf when the file filled all 1024 bytes without a NUL.
ReadFile() bounds the append by the byte count Read() returns and reads
the whole file, so the original contents also round-trip faithfully.
2026-06-09 17:14:27 +05:30
TehPeGaSuS d4f5d5f9e8 Enable SSL by default in znc --makeconf when connecting to servers (#2022)
* Enable SSL by default in ZNC configuration when connecting to servers

* Change default port from 6667 to 6697 in znctest

* Update SSL variable initialization with preprocessor checks

Refactor SSL configuration to use preprocessor directives.

* Fix comment formatting in znc.cpp

Fix extraneous double tab that slipped into the commit
2026-06-09 08:21:01 +01:00
dxbjavid 01678166a8 fileutils: force owner write while copying read-only sources
Opening the destination at the source's exact mode breaks when the
source lacks owner write (e.g. r-xr-xr-x): the create still works but
the overwrite path can't reopen such a destination for writing. Force
owner read+write while copying and let the trailing Chmod() put the
source mode back, which only ever adds owner bits so the group/other
bits stay as restrictive as the source throughout. Add a regression
test covering the restricted-mode and read-only-source cases.
2026-06-09 09:53:57 +05:30
Alexey Sokolov 042d827e4a Merge pull request #2023 from DarthGandalf/nossl
Add CI job for ZNC without SSL support
2026-06-08 23:03:02 +01:00
Alexey Sokolov 53ffcc909b add include 2026-06-08 22:43:13 +01:00
Alexey Sokolov 2a9359d1fb Merge branch 'nossl' of github.com:DarthGandalf/znc into nossl 2026-06-08 22:07:34 +01:00
Alexey Sokolov ad12a6011d Skip tests which require SSL 2026-06-08 22:07:11 +01:00
Alexey Sokolov 14846166c6 Update test/integration/framework/znctest.cpp
Co-authored-by: dgw <dgw@technobabbl.es>
2026-06-08 22:00:37 +01:00
Alexey Sokolov 197a235764 test: Don't wait for SSL question if built without SSL
And don't hardcode 6667 in preparation for #2022
2026-06-08 21:54:34 +01:00
Alexey Sokolov 15c94bef77 Add CI job for ZNC without SSL support 2026-06-08 21:42:02 +01:00
dxbjavid 1701edca5b fileutils: open Copy() destination at the source's mode 2026-05-25 13:08:43 +05:30
Alexey Sokolov 56ed5c3f94 docker: update alpine 2026-05-07 20:15:53 +01:00
Alexey Sokolov f018a75cde Merge branch '1.10.x' 2026-05-07 20:07:54 +01:00
Alexey Sokolov eba009c49e Return version number to 1.10.x 2026-05-07 20:07:43 +01:00
Alexey Sokolov 59af2206c6 Increase the version number to 1.10.2 znc-1.10.2 2026-05-07 20:00:42 +01:00
Alexey Sokolov a80cf49f5e Merge pull request #2018 from MarkLee131/fix/http-hardening-headers
HTTPSock: emit standard hardening response headers
2026-05-05 00:26:58 +01:00
Alexey Sokolov 663699b617 Merge pull request #2015 from MarkLee131/fix/cstring-empty-input-guards
ZNCString: guard Replace/Split against empty-width arguments
2026-05-04 22:05:49 +01:00
MarkLee131 80699c4178 test: use EXPECT_THAT matchers for Split assertions
Pull in gmock so the empty-delimiter Split assertions can keep using
EXPECT_THAT(..., ElementsAre(...)) and IsEmpty(). On failure the matcher
prints the actual vector contents, which EXPECT_TRUE(vempty.empty())
hides behind a bare 'not true'.
2026-05-04 20:51:56 +08:00
MarkLee131 83e7eefc21 HTTPSock: tighten hardening header defaults
Switch the default Referrer-Policy from same-origin to no-referrer so the
webadmin URL (which can carry user/network names in the path) does not
leak to outbound clicks either.

Drop Pragma: no-cache; it is deprecated and modern intermediaries honor
Cache-Control. Simplify Cache-Control to a single no-store directive,
which on its own already prevents storing per RFC 9111; the previous
no-cache, must-revalidate, max-age=0 tail was HTTP/1.0-era padding.
2026-05-04 20:35:23 +08:00
MarkLee131 c3f1b0c00e test: replace gmock matchers in Split test with gtest equivalents
StringTest.cpp does not include gmock, so EXPECT_THAT/ElementsAre/IsEmpty
do not compile and the unittest target fails on every CI configuration.
Use EXPECT_EQ against a VCString and EXPECT_TRUE(empty()) instead, which
keeps the test scope identical without dragging gmock into this file.
2026-05-04 19:31:29 +08:00
Alexey Sokolov 3584162177 CI: remove firefox
It tries to be upgraded from snap, and fails
2026-05-02 00:29:31 +01:00
Alexey Sokolov f35e565637 Merge pull request #2013 from MarkLee131/fix/base64-decode-ub
ZNCString: avoid left shift of negative value in Base64Decode
2026-05-01 22:23:24 +01:00
ZNC-Jenkins e0c573c053 Update translations from Crowdin for bg_BG da_DK de_DE el_GR es_ES fr_FR id_ID it_IT nl_NL pl_PL pt_BR pt_PT ro_RO ru_RU tr_TR 2026-05-01 00:28:00 +00:00
Alexey Sokolov 6186f611b9 Merge pull request #2017 from MarkLee131/fix/checkpass-constant-time
User: use constant-time compare for MD5/SHA256/plain password paths
2026-04-30 08:23:07 +01:00
MarkLee131 f71e021e3b HTTPSock: emit standard hardening response headers
Close #2012.

Add X-Frame-Options: SAMEORIGIN, X-Content-Type-Options: nosniff and
Referrer-Policy: same-origin to every response so webadmin and module
pages are framed/sniff-protected by default. Add no-store Cache-Control
and Pragma: no-cache on dynamic responses so shared workstations can't
replay authenticated pages from browser history. Skip the cache headers
for 304 and for static asset MIME types (image, font, text/css,
application/javascript) that the existing ETag/Last-Modified path on
PrintFile already handles.

Per review feedback: the emitter is a private WriteHardeningHeaders that
writes each line via the socket directly from PrintHeader, not a public
helper returning a temporary VCString. Callers can override a default
value with AddHeader, or suppress one outright with the new public
OmitHardeningHeader(name).

Tests: drive PrintHeader on a CHTTPSock subclass that captures Write()
calls, then assert with gmock matchers (Contains(StartsWith(...))).
2026-04-29 20:29:47 +08:00
MarkLee131 099895b1f0 test: fix \xff hex escape parsing in Base64 test for stricter compilers
GCC parses "AA\xffA" greedily as \xffA (next character is a hex digit),
which is out of range for char and breaks the Linux CI build. Split the
literal into "AA\xff" "A" so the escape resolves before the next string,
yielding the intended four bytes (A, A, 0xff, A).
2026-04-29 19:33:30 +08:00
MarkLee131 c9d0677e4f Utils: prefer CRYPTO_memcmp in ConstantTimeEquals when OpenSSL is available
Per review feedback on #2017: a hand-rolled byte loop can in principle
be folded back into a short-circuiting compare by an aggressive optimizer.
Use CRYPTO_memcmp under HAVE_LIBSSL since OpenSSL is already a build
dependency for the SHA256 path. For non-OpenSSL builds, mark the
accumulator and pointers volatile and note in a comment that this is
best-effort.
2026-04-29 17:06:49 +08:00
MarkLee131 8d92fe7933 Update test/StringTest.cpp
Co-authored-by: Alexey Sokolov <alexey+github@asokolov.org>
2026-04-28 22:11:13 +08:00
MarkLee131 bee6d9443c Update test/StringTest.cpp
Co-authored-by: Alexey Sokolov <alexey+github@asokolov.org>
2026-04-28 22:11:02 +08:00
Alexey Sokolov 866303eef0 Merge pull request #2014 from MarkLee131/fix/parseservertime-clamp-range
Utils: reject out-of-range years in ParseServerTime
2026-04-27 01:43:24 +01:00
Alexey Sokolov 7456cbaf02 Merge pull request #2016 from MarkLee131/fix/addheader-crlf-guard
HTTPSock: reject CR/LF in AddHeader name/value
2026-04-27 01:38:00 +01:00
Alexey Sokolov 8f5425f99c Merge pull request #1999 from znc/dependabot/github_actions/codecov/codecov-action-6
Bump codecov/codecov-action from 5 to 6
2026-04-25 11:46:08 +01:00
Alexey Sokolov 2a1844ee4e Merge pull request #2000 from znc/dependabot/github_actions/docker/login-action-4
Bump docker/login-action from 3 to 4
2026-04-25 11:45:34 +01:00
Alexey Sokolov 939d2b6c30 Merge pull request #1998 from znc/dependabot/github_actions/docker/metadata-action-6
Bump docker/metadata-action from 5 to 6
2026-04-25 11:45:05 +01:00
Alexey Sokolov 7540979707 Merge pull request #1997 from znc/dependabot/github_actions/docker/build-push-action-7
Bump docker/build-push-action from 6 to 7
2026-04-25 11:44:40 +01:00
Alexey Sokolov 0f1c646e5e Merge pull request #1991 from znc/dependabot/github_actions/actions/upload-artifact-7
Bump actions/upload-artifact from 6 to 7
2026-04-25 11:44:23 +01:00
MarkLee131 20e8f73b03 HTTPSock: extract IsValidHeaderField helper and add tests (#2010) 2026-04-25 17:38:31 +08:00
MarkLee131 f0c3341e35 User,Utils: move ConstantTimeEquals to CUtils and add tests (#2011) 2026-04-25 17:37:33 +08:00
MarkLee131 7c47afa888 test: cover ParseServerTime out-of-range year rejection (#2008) 2026-04-25 17:34:58 +08:00
MarkLee131 d60f489c27 test: cover Base64Decode round-trip and out-of-alphabet bytes (#2013) 2026-04-25 17:34:11 +08:00
MarkLee131 c94df21130 test: cover empty-needle Replace and empty-delim Split (#2009) 2026-04-25 17:26:04 +08:00
MarkLee131 794ae6cd60 User: use constant-time compare for MD5/SHA256/plain password paths
CString::Equals falls through to strcmp, which short-circuits on the first
differing byte. That leaks the length of the common prefix between the
stored hash (or plain password) and the attacker's guess via response
timing. Argon2id already uses argon2id_verify which is constant-time.

Add a small ConstantTimeEquals helper and use it for the legacy MD5,
SHA256 and plain HASH_NONE branches. No new dependency: the helper is
~10 lines and works on builds without OpenSSL.
2026-04-25 10:39:13 +08:00
MarkLee131 04cf89beec HTTPSock: reject CR/LF in AddHeader name/value
AddHeader wrote its arguments straight into the response stream. No
in-tree caller reaches it with attacker-controlled bytes today, but the
public API is exposed to module authors; one bad caller would be a
header-injection bug. Filter at the entry rather than at every caller.
2026-04-25 10:38:31 +08:00
MarkLee131 514b47cad3 ZNCString: guard Replace/Split against empty-width arguments
CString::Replace with an empty sReplace underflowed 'p += uReplaceWidth - 1'
to SIZE_MAX and then the per-iteration 'p++' brought p back to the same
byte, so the function looped forever appending sWith to the output and
eventually OOMed.

CString::Split with empty sDelim and bAllowEmpty=false spun in the
prefix-skip loops because strncasecmp(p, "", 0) is unconditionally 0 and
p += 0 never advances.

No in-tree caller currently passes the bad argument, but the public
library API should not be a bear trap for module authors. Same shape as
#1994.
2026-04-25 10:38:02 +08:00
MarkLee131 b944299167 Utils: reject out-of-range years in ParseServerTime
cctz::parse into a microseconds time_point internally multiplies the
parsed seconds-since-epoch by 1,000,000 in signed int64. Years past ~292k
overflow, which is UB under UBSan or -ftrapv builds. In plain production
builds the overflow silently wraps and buffer playback shows a garbage
timestamp.

Reject anything with a year longer than 5 digits before calling into
cctz. 5 digits covers every realistic IRCv3 @time tag.
2026-04-25 10:36:53 +08:00
MarkLee131 026b88e2fa ZNCString: avoid left shift of negative value in Base64Decode
base64_table uses the sentinel 0xff for bytes outside the base64 alphabet.
The old code read that through (char), producing signed -1, which made the
three (c << N) expressions in Base64Decode undefined behaviour when the
input contained any invalid byte.

Keep c and c1 as unsigned char so the shifts are well-defined. Reachable
pre-auth via CHTTPSock::ReadLine for the Authorization: Basic value.
2026-04-25 10:34:06 +08:00