https://bugs.kde.org/show_bug.cgi?id=526514

            Bug ID: 526514
           Summary: When connecting to KRDP server from Windows 10/11
                    native Remote Desktop Connection (`mstsc.exe`),
                    authentication consistently fails with **"Logon
                    credentials failed"**
    Classification: Plasma
           Product: KRdp
      Version First 6.6.6
       Reported In:
          Platform: Ubuntu
                OS: Linux
            Status: REPORTED
          Severity: critical
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

# Bug Report: Windows RDP Fails Authentication on FreeRDP >= 3.32 due to Unset
`FreeRDP_ExtSecurity` in KRDP

**Target Component:** KDE KRDP (`src/RdpConnection.cpp`)  
**Upstream Repositories:**
[invent.kde.org/plasma/krdp](https://invent.kde.org/plasma/krdp) / FreeRDP 3  
**Related Upstream Reports:** [KDE Bug
521776](https://bugs.kde.org/show_bug.cgi?id=521776), [KDE Bug
522139](https://bugs.kde.org/show_bug.cgi?id=522139)

---

## 1. Summary

When connecting to KRDP server from Windows 10/11 native Remote Desktop
Connection (`mstsc.exe`), authentication consistently fails with **"Logon
credentials failed"** if the server host runs **FreeRDP >= 3.32.0**.

The setup worked flawlessly on **FreeRDP 3.31.0** and earlier, but immediately
broke when system package managers (e.g., Ubuntu unattended-upgrades) updated
`libfreerdp3-3` and `libfreerdp-server3-3` from `3.31.0` to `3.32.0`.

---

## 2. Environment

* **Server OS:** Ubuntu 26.04 LTS (Kubuntu / arm64, kernel 6.18)
* **Desktop Environment:** KDE Plasma 6.6.4 (Wayland)
* **KRDP Version:** 6.6.4 (verified present in upstream `Plasma/6.6`,
`Plasma/6.7`, `Plasma/6.8`, and git `master`)
* **FreeRDP Version:**
  * **Working:** `3.31.0+dfsg-0ubuntu0.26.04.1`
  * **Broken:** `3.32.0+dfsg-0ubuntu0.26.04.1`
* **Client OS:** Windows 11 Pro (`mstsc.exe`, RDP client version 10.0.22631)
* **KRDP Auth Mode:** System User PAM Authentication (`SystemUserEnabled=true`
in `~/.config/krdpserverrc`)

---

## 3. Steps to Reproduce

1. Install and enable KRDP on a Wayland Plasma session with PAM authentication
enabled (`SystemUserEnabled=true`).
2. Ensure FreeRDP server libraries are updated to `3.32.0`
(`libfreerdp-server3-3`, `libfreerdp3-3`).
3. From a Windows 11 machine, launch `mstsc.exe` and connect to the KRDP host.
4. When prompted by Windows RDP credentials dialog, enter valid system username
and password.

### Expected Result
Windows establishes a TLS connection, submits credentials over TLS, KRDP PAM
authenticates the Linux user (`pam_authenticate`), and the Wayland session
opens.

### Actual Result
Connection immediately drops with Windows dialog: **"Logon credentials
failed"**.

---

## 4. Root Cause Analysis (Code Level)

In `src/RdpConnection.cpp`, KRDP initializes FreeRDP server settings in
`RdpConnection::initialize()`:

```cpp
freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, false);
freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, usePamAuthentication);
freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity,
!usePamAuthentication);
```

### The Bug:
When `usePamAuthentication` is `true` (standard system user login):
* KRDP sets `FreeRDP_NlaSecurity = false`.
* KRDP sets `FreeRDP_TlsSecurity = true`.
* **KRDP omits setting `FreeRDP_ExtSecurity = false` (Key index 1091).**

### Why this breaks with FreeRDP >= 3.32:
1. In FreeRDP 3 (`libfreerdp/core/settings.c`), `FreeRDP_ExtSecurity` (Extended
NLA / Early User Auth / `PROTOCOL_HYBRID_EX`) defaults to **`TRUE`**.
2. Windows 11 `mstsc.exe` connects advertising support for `RDSTLS:0 NLA:1
EXT:1 TLS:1 RDP:0`.
3. In FreeRDP 3.32, server negotiation in `rdp_server_accept_nego()`
prioritizes `PROTOCOL_HYBRID_EX` over `PROTOCOL_SSL`:
   ```c
   else if ((settings->ExtSecurity) && (RequestedProtocols &
PROTOCOL_HYBRID_EX))
   {
       SelectedProtocol = PROTOCOL_HYBRID_EX;
   }
   else if ((settings->TlsSecurity) && (RequestedProtocols & PROTOCOL_SSL))
   {
       SelectedProtocol = PROTOCOL_SSL;
   }
   ```
4. Because KRDP forgot to set `FreeRDP_ExtSecurity = false`, the server
advertises `EXT:1`:
   ```text
   Client Security:     RDSTLS:0 NLA:1 EXT:1 TLS:1 RDP:0
   Server Security:     RDSTLS:0 NLA:0 EXT:1 TLS:1 RDP:0
   Negotiated Security: RDSTLS:0 NLA:0 EXT:1 TLS:0 RDP:0  <-- EXT:1 selected!
   ```
5. FreeRDP triggers CredSSP / Early User Auth. Under `EXT:1`, the client sends
an NTLM challenge-response rather than plaintext credentials.
6. KRDP does not provide NLA SAM credentials for system users (it requires
plaintext credentials to authenticate against Linux `/sbin/unix_chkpwd` via
PAM). WinPR fails immediately with:
   ```text
   [DEBUG][com.winpr.sspi.NTLM] - [ntlm_read_negotiate_flags]: Read flags
[0xe20882b7]
   [ERROR][com.winpr.sspi.NTLM] - [ntlm_fetch_ntlm_v2_hash]: Error: Could not
find user in SAM database
   [WARN][com.winpr.sspi] - [winpr_AcceptSecurityContext]:
AcceptSecurityContext status SEC_E_NO_CREDENTIALS [0x8009030e]
   [ERROR][com.freerdp.core.auth] - [credssp_auth_authenticate]:
AcceptSecurityContext status SEC_E_NO_CREDENTIALS [0x8009030e]
   [ERROR][com.freerdp.core.transport] - [transport_accept_nla]: client
authentication failure
   ```

### Why it worked in FreeRDP 3.31.0:
In FreeRDP 3.31.0, the server advertised `Server Security: RDSTLS:0 NLA:0 TLS:1
RDP:0`. FreeRDP naturally negotiated `TLS:1`. The client established the TLS
tunnel and sent credentials inside the encrypted channel, whereupon
`pam_authenticate()` authenticated the system user successfully.

---

## 5. Suggested Patch for KRDP

In `src/RdpConnection.cpp`, update `RdpConnection::initialize()` to explicitly
set `FreeRDP_ExtSecurity`:

```diff
--- a/src/RdpConnection.cpp
+++ b/src/RdpConnection.cpp
@@ -450,6 +450,7 @@ void RdpConnection::initialize()
     freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, false);
     freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity,
usePamAuthentication);
     freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity,
!usePamAuthentication);
+    freerdp_settings_set_bool(settings, FreeRDP_ExtSecurity,
!usePamAuthentication);

     freerdp_settings_set_uint32(settings, FreeRDP_OsMajorType,
OSMAJORTYPE_UNIX);
     // PSEUDO_XSERVER is apparently required for things to work properly.
```

If NLA is disabled for PAM, Extended NLA (`FreeRDP_ExtSecurity`) must also be
disabled. This forces FreeRDP to negotiate `TLS:1` when interacting with
Windows RDP clients.

---

## 6. Available Workarounds

Until KRDP releases this patch upstream:

1. **Downgrade FreeRDP to 3.31.0 (Recommended):**
   Downgrade `libfreerdp-server3-3`, `libfreerdp3-3`, `libwinpr3-3`, and
`libfreerdp-client3-3` to version `3.31.0` and pin them with `apt-mark hold`.
2. **Runtime LD_PRELOAD Interceptor:**
   Preload a small shared library on `krdpserver.service` that hooks
`freerdp_settings_set_bool` and forces `FreeRDP_ExtSecurity = FALSE` whenever
NLA is disabled.
3. **Windows Client Workaround:**
   Save connection to an `.rdp` file and add `enablecredsspsupport:i:0` to
force Windows `mstsc` to request TLS instead of NLA/EXT.




Operating System: Ubuntu 26.04
KDE Plasma Version: 6.6.6
KDE Frameworks Version: 6.24.0
Qt Version: 6.10.2
Kernel Version: 6.18.44-g61025ec85b88 (64-bit)
Graphics Platform: Wayland
Processors: 8 × ARM Cortex-A55
Memory: 3.7 GiB of usable RAM
Graphics Processor 1: Mali-G57 MC1
Graphics Processor 2: Mali-G57 MC1
Product Name: OrangePi 4A

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to