Skip to content

Reset http_buf_len on NTLM proxy retry to prevent assert crash - #252

Merged
parfeon merged 6 commits into
masterfrom
CLEN-3631-fix-proxy-retry-assertion
Jul 30, 2026
Merged

Reset http_buf_len on NTLM proxy retry to prevent assert crash#252
parfeon merged 6 commits into
masterfrom
CLEN-3631-fix-proxy-retry-assertion

Conversation

@parfeon

@parfeon parfeon commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

feat(ntlm): parse domain from username in SSPI identity for NTLM proxy auth

fill_sspi_identity now splits DOMAIN\user and user@domain formats into separate User and
Domain fields so proxies requiring domain-qualified credentials can authenticate.

fix(proxy): reset http_buf_len on NTLM proxy retry to prevent assert crash

Reset http_buf_len to 0 in pbproxyFinRetry so the stale 407 body length does not trip the
assert guarding proxy_saved_path memcpy on the next CONNECT attempt.

fix(ntlm): correct inverted SSPI max-token guard in pbntlm_packer_sspi.c

The warning fired on the normal case instead of when SSPI needs more space than our buffer provides.
Flip the comparison and update the log message.

refactor(ntlm): use dynamic allocation for Type-2 challenge decode in pbntlm_core_handle

Replace the 512-byte stack buffer with pbbase64_decode_alloc_std so large NTLM Type-2 challenges
from domain-joined proxies are no longer silently dropped.

refactor(ntlm): raise PUBNUB_NTLM_MAX_TOKEN from 1024 to 4096

NTLMv2 Type-3 with extended target info and MIC frequently exceeds 1024 bytes. Raised to 4096 to
cover all known SSPI scenarios.

test(proxy): add NTLM proxy regression tests

Add tests for oversized 407 body triggering retry-path assert, and direct pbntlm_core_handle
tests with 600, 2048, and 4200 byte challenges.

parfeon added 2 commits July 27, 2026 16:50
…y auth

`fill_sspi_identity` now splits `DOMAIN\user` and `user@domain` formats into separate User and
Domain fields so proxies requiring domain-qualified credentials can authenticate.

fix(proxy): reset `http_buf_len` on NTLM proxy retry to prevent assert crash

Reset `http_buf_len` to 0 in `pbproxyFinRetry` so the stale 407 body length does not trip the
assert guarding `proxy_saved_path` memcpy on the next CONNECT attempt.

fix(ntlm): correct inverted SSPI max-token guard in `pbntlm_packer_sspi.c`

The warning fired on the normal case instead of when SSPI needs more space than our buffer provides.
Flip the comparison and update the log message.

refactor(ntlm): use dynamic allocation for Type-2 challenge decode in `pbntlm_core_handle`

Replace the 512-byte stack buffer with `pbbase64_decode_alloc_std` so large NTLM Type-2 challenges
from domain-joined proxies are no longer silently dropped.

refactor(ntlm): raise `PUBNUB_NTLM_MAX_TOKEN` from 1024 to 4096

NTLMv2 Type-3 with extended target info and MIC frequently exceeds 1024 bytes. Raised to 4096 to
cover all known SSPI scenarios.

test(proxy): add NTLM proxy regression tests

Add tests for oversized 407 body triggering retry-path assert, and direct `pbntlm_core_handle`
tests with 600, 2048, and 4200 byte challenges.
…inkage

Add two sample apps demonstrating synchronous publish through an NTLM proxy: manual configuration
with explicit host/port/credentials and automatic detection from Windows system settings.

build(proxy): link `pbntlm_packer_sspi.c` on Windows instead of the stub `pbntlm_packer_std.c`

Move `pbntlm_packer_std.c` to `PROXY_SOURCE_FILES_POSIX` and add `pbntlm_packer_sspi.c` to
`PROXY_SOURCE_FILES_WINDOWS` so the Windows library build has functional NTLM authentication.
@parfeon parfeon self-assigned this Jul 27, 2026
@parfeon parfeon added status: done This issue is considered resolved. priority: high This PR should be reviewed ASAP. type: feature This PR contains new feature. type: fix This PR contains fixes to existing features. labels Jul 27, 2026

@Xavrax Xavrax left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me.
Verify my comments and can be released.

BTW. I see changes in makefiles, shouldn't we update CMake too?

Comment thread core/pbntlm_core.c
Comment on lines +45 to +47
data = pbbase64_decode_alloc_std(base64_msg, length);
if (NULL == data.ptr) {
PUBNUB_LOG_ERROR(pb, "Base64 decode (alloc) of NTLM challenge failed");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like these change in case of readability, however we're losing potentially part of the info (I see that it might return values like -14 and -15. (which is meaningless without a code to debug, but still).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly, we will loose those but I'm not really sure about possibility that it will happen here.

Comment thread core/pbntlm_packer_sspi.c
Comment on lines +77 to 85
if (sspi_max_token > PUBNUB_NTLM_MAX_TOKEN) {
PUBNUB_LOG_WARNING(
context,
"NTLM token for SSPI is smaller (%lu) that maximum allowed (%d).",
"SSPI max token (%lu) exceeds PUBNUB_NTLM_MAX_TOKEN (%d). "
"Type-2 challenges larger than %d bytes will be rejected.",
sspi_max_token,
PUBNUB_NTLM_MAX_TOKEN,
PUBNUB_NTLM_MAX_TOKEN);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's kinda specific change. Why we reverse that? (I mean, why the previous log is no longer needed)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, before there were strange warning, that token surprisingly smaller than configured max limit - there is nothing wrong with token to be smaller than allocated maximum size :)
It was just misleading.

Comment thread core/pbntlm_core.c Outdated
pbntlm_core_deinit(pb);
return;
}
(void)pbntlm_unpack_type2(pb, &pb->ntlm_context, data);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that we can omit this value?
As I understood, it might fail for SPI build (passes the std one).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As when it fails on SPI, there is assertion in unpack_type3 which verifies if the size of data is higher than 0 (whereas fail of this function does it).

Ofc, handling error earlier won't safe the whole thing, but it will be consistent between build types.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

Added error handling - now we check the return value and deinit/abort on failure, consistent with the other error paths in this function. Also added a test for invalid base64 input.


/** Maximum supported length of the NTLM token (message) */
#define PUBNUB_NTLM_MAX_TOKEN 1024
#define PUBNUB_NTLM_MAX_TOKEN 4096

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We extended the maximum amount of characters for the proxy however at core/pubnub_netcore.c:1340, we have defined header variable that is hardcoded to 1024.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

Added PUBNUB_PROXY_AUTH_HEADER_MAX_SIZE macro that derives the proper buffer size from PUBNUB_NTLM_MAX_TOKEN (base64 expansion + header prefix room) and used it for hedr in pubnub_netcore.c.

parfeon and others added 2 commits July 30, 2026 22:38
Check the return value of `pbntlm_unpack_type2` and abort the NTLM handshake on failure instead of
advancing to the Authenticate state with empty token data.

fix(proxy): size proxy auth header buffer for base64-encoded NTLM tokens

Add `PUBNUB_PROXY_AUTH_HEADER_MAX_SIZE` macro derived from `PUBNUB_NTLM_MAX_TOKEN` and use it for
the `hedr` buffer in `pubnub_netcore.c` so it can hold a full base64-encoded 4096-byte token.

test(proxy): add invalid base64 failure path test for `pbntlm_core_handle`

Add `NTLM_core_handle_rejects_invalid_base64` and update the oversized-token test to verify the
context is properly deinited on unpack failure.
@parfeon

parfeon commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

BTW. I see changes in makefiles, shouldn't we update CMake too?

Those are test apps for manual NTLM testing

@parfeon

parfeon commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@pubnub-release-bot release

@parfeon
parfeon merged commit 80cd7be into master Jul 30, 2026
7 checks passed
@parfeon
parfeon deleted the CLEN-3631-fix-proxy-retry-assertion branch July 30, 2026 20:41
@pubnub-release-bot

Copy link
Copy Markdown
Contributor

🚀 Release successfully completed 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: high This PR should be reviewed ASAP. status: done This issue is considered resolved. type: feature This PR contains new feature. type: fix This PR contains fixes to existing features.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants