Skip to content

fix(acceptor): upgrade sspi, use NTLM when no Kerberos#1143

Open
Guillaume Gelin (ramnes) wants to merge 1 commit intoDevolutions:masterfrom
formalco:ramnes/update-sspi
Open

fix(acceptor): upgrade sspi, use NTLM when no Kerberos#1143
Guillaume Gelin (ramnes) wants to merge 1 commit intoDevolutions:masterfrom
formalco:ramnes/update-sspi

Conversation

@ramnes
Copy link
Copy Markdown
Contributor

Upgrade sspi to incorporate latest changes. The new version introduces a real SPNEGO implementation in ServerMode::Negotiate, but some RDP clients seem to send raw NTLM tokens in CredSSP rather than SPNEGO-wrapped ones, which doesn't seem supported by sspi yet? In the meantime, we can use ServerMode::Ntlm directly when Kerberos is disabled, so that we maintain compatibility with previous sspi behavior.

Note: I can't get the dependencies right, looks like there's a picky rc.22 / getrandom conflict; any help appreciated here!

Upgrade sspi to incorporate latest changes. The new version introduces a real SPNEGO implementation in `ServerMode::Negotiate`, but some RDP clients seem to send raw NTLM tokens in CredSSP rather than SPNEGO-wrapped ones, which doesn't seem supported by sspi yet? In the meantime, we can use `ServerMode::Ntlm` directly when Kerberos is disabled, so that we maintain compatibility with previous sspi behavior.
@TheBestTvarynka
Copy link
Copy Markdown
Collaborator

Hi, yes, you are right. Let me add more context for others and for historical reasons 🙃

but some RDP clients seem to send raw NTLM tokens in CredSSP rather than SPNEGO-wrapped ones

Yep. mstsc and FreeRDP do so. I was the one who refactored SPNEGO implementation. We needed to improve SPNEGO to fix these issues: Devolutions/sspi-rs#433 and Devolutions/sspi-rs#476. sspi-rs is not only used for RDP but also for SMB and other protocols. So, we needed proper SPNEGO support.

which doesn't seem supported by sspi yet?

It is supported, but the user (the caller) must specify it explicitly via ClientMode::Ntlm rather than ClientMode::Negotiate. And I see you do exactly this 👍

We can use ServerMode::Ntlm directly when Kerberos is disabled

Currently, that's the only way to do so.

Greg Lamberson (glamberson) pushed a commit to lamco-admin/IronRDP that referenced this pull request Mar 28, 2026
Upgrade sspi from 0.18 to 0.19 and picky from rc.20 to rc.22.

sspi 0.19 introduces a proper SPNEGO implementation that expects
SPNEGO-wrapped tokens, but mstsc and FreeRDP send raw NTLM tokens
in CredSSP. Use ServerMode::Ntlm directly when Kerberos is disabled
to maintain compatibility.

Code changes:
- acceptor: use ServerMode::Ntlm(NtlmConfig) when no Kerberos config
  instead of ServerMode::Negotiate with NtlmConfig as ProtocolConfig
- acceptor: implement CredentialsProxy::auth_data (new trait method)
- connector: KerberosConfig.hostname conversion needs unwrap_or_default
  (sspi 0.19 changed client_computer_name from Option<String> to String)
- tokio/reqwest: use sspi types through ironrdp-connector re-export to
  avoid version mismatch between direct and transitive sspi deps
- ffi: bump sspi dep to 0.19

Dependency workaround:
- Pin uuid to <1.21 in ironrdp-client and ironrdp-mstsgu. uuid 1.21+
  pulls getrandom 0.4 which needs stable rand_core 0.10.0, conflicting
  with picky rc.22's pinned rand_core = "=0.10.0-rc-3". Remove this pin
  when picky ships with stable RustCrypto deps.

Based on investigation by @ramnes (PR Devolutions#1143) and @sfwwslm (issue Devolutions#1186).
@glamberson
Copy link
Copy Markdown
Contributor

sspi 0.19.2 was published to crates.io on Mar 27, which includes the SPNEGO refactor you needed. I put together PR #1188 that builds on your work here: it uses the published sspi 0.19 instead of the git rev pin, applies your ServerMode::Ntlm fix, and adds a few additional fixes needed for the full workspace build (new CredentialsProxy::auth_data trait method, reqwest.rs sspi re-export, uuid pin for a picky rand_core conflict documented in #1186).

Credited you in the PR description. Thanks for identifying the NTLM fallback issue and getting the ball rolling on this.

Greg Lamberson (glamberson) pushed a commit to lamco-admin/IronRDP that referenced this pull request Mar 28, 2026
Upgrade sspi from 0.18 to 0.19 and picky from rc.20 to rc.22.

sspi 0.19 introduces a proper SPNEGO implementation that expects
SPNEGO-wrapped tokens, but mstsc and FreeRDP send raw NTLM tokens
in CredSSP. Use ServerMode::Ntlm directly when Kerberos is disabled
to maintain compatibility.

Code changes:
- acceptor: use ServerMode::Ntlm(NtlmConfig) when no Kerberos config
  instead of ServerMode::Negotiate with NtlmConfig as ProtocolConfig
- acceptor: implement CredentialsProxy::auth_data (new trait method)
- connector: KerberosConfig.hostname conversion needs unwrap_or_default
  (sspi 0.19 changed client_computer_name from Option<String> to String)
- tokio/reqwest: use sspi types through ironrdp-connector re-export to
  avoid version mismatch between direct and transitive sspi deps
- ffi: bump sspi dep to 0.19

Dependency workaround:
- Pin uuid to <1.21 in ironrdp-client and ironrdp-mstsgu. uuid 1.21+
  pulls getrandom 0.4 which needs stable rand_core 0.10.0, conflicting
  with picky rc.22's pinned rand_core = "=0.10.0-rc-3". Remove this pin
  when picky ships with stable RustCrypto deps.

Based on investigation by @ramnes (PR Devolutions#1143) and @sfwwslm (issue Devolutions#1186).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants