Repository navigation
Conversation
With GSSAPI sealing, LdapCodec::decode unwrapped one SASL buffer, decoded one LDAP message from it, and kept the rest of the plaintext only if no more raw bytes had been read from the socket yet. Otherwise the rest was dropped. A message continued in the next buffer was lost too, and fewer than four buffered bytes was reported as an error. Active Directory seals a whole search page (a megabyte and more, hundreds of messages) as one buffer. When the reply to another operation on the same connection was read along with it, the rest of the page, its SearchResultDone included, was discarded and the search waited forever. Keep the unwrapped plaintext in its own buffer on the codec, separate from the raw sealed bytes. Return every complete message from it before unwrapping the next SASL buffer, append the next buffer's plaintext so messages can span buffers, and wait for more data on a partial length prefix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With SASL GSSAPI sealing,
LdapCodec::decodecan silently discard decrypted LDAP messages, and the operation waiting for them never completes. Against Active Directory it shows up as an intermittent hang: a paged search waits forever on an idle connection.The current decoder unwraps one SASL buffer and decodes one LDAP message from it. The rest of the plaintext is kept only if
bufis empty, meaning nothing more has been read from the socket. Otherwise it's dropped:Data is lost in three cases:
Err("invalid SASL buffer")instead ofOk(None).Reproduction
Windows client (SSPI, current user) against an AD domain controller (Server 2016/2019), plain LDAP with sealing:
*, 999 per page);1.1).9 of 15 runs hung. Instrumenting the unmodified decoder showed every hang logging, for example, "dropping 1146456 of 1148022 plain bytes (more messages in the frame) because 118496 raw bytes are buffered". Without sealing (LDAPS) the code path isn't used and nothing hangs.
Fix
has_decoded_data: boolis replaced bydecoded: BytesMuton the codec, which holds unwrapped plaintext separately from the raw sealed bytes.decode_saslreturns every complete message fromdecodedbefore unwrapping the next SASL buffer, and appends each buffer's plaintext so a message can span buffers.Ok(None)on a partial length prefix or a partial buffer.The decode logic takes the unwrap step as a closure, so it's unit-tested without a GSSAPI context:
cargo test --lib --no-default-features --features gssapipasses (31 tests), as doescargo testwith default features.With the fix, 48 of 48 runs against AD completed: 40 sealed, within one domain and across a parent/child trust, plus 8 over LDAPS.