Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make license parsing and protocol more resilient #436

Merged
merged 7 commits into from
Apr 25, 2024

Conversation

ibeckermayer
Copy link
Collaborator

@ibeckermayer ibeckermayer commented Apr 6, 2024

A user encountered

ConnectorError(Error { context: "decode SERVER_PLATFORM_CHALLENGE", kind: Pdu(Error { context: "<ironrdp_pdu::rdp::server_license::BlobHeader as ironrdp_pdu::PduDecode>::decode::{{c
losure}}", kind: InvalidMessage { field: "blobType", reason: "invalid blob type" }, source: None }), source: None })

This appears to be a bug in the parsing code for SERVER_PLATFORM_CHALLENGE which contains a Licensing Binary BLOB<12> with the following footnote:

The wBlobType field is unused in EncryptedPlatformChallenge (part of SERVER_PLATFORM_CHALLENGE PDU), which is sent by the server to the client.

suggesting that the blob type may not be one of the enumerated expected values.

This PR re-introduces resilient parsing for this field.

Putting this in draft mode pending an in-field test by the user.

Update:

After attempting to connect over xrdp, I discovered a larger refactor should be done to improve the resiliency of the licensing protocol. This has also now been tested against the standard windows rdp server.

@ibeckermayer ibeckermayer requested a review from CBenoit April 6, 2024 00:32
Copy link
Member

@CBenoit CBenoit left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good to me! Let’s merge once the user confirms everything is good.

@ibeckermayer ibeckermayer changed the title converts BlobType to resilient parsing style Makes license parsing and protocol more resilient Apr 12, 2024
Copy link

github-actions bot commented Apr 15, 2024

Coverage Report 🤖 ⚙️

Past:
Total lines: 29646
Covered lines: 17248 (58.18%)

New:
Total lines: 29661
Covered lines: 17335 (58.44%)

Diff: +0.26%

[this comment will be updated automatically]

@ibeckermayer ibeckermayer marked this pull request as ready for review April 16, 2024 16:33
@ibeckermayer ibeckermayer requested a review from CBenoit April 16, 2024 16:37
@ibeckermayer
Copy link
Collaborator Author

ibeckermayer commented Apr 16, 2024

Substantial changes have been made since approval see the Update section in the description.

@CBenoit @pacmancoder

ibeckermayer pushed a commit to gravitational/teleport that referenced this pull request Apr 16, 2024
…n PR (Devolutions/IronRDP#436) and thus the IronRDP hash should be frozen until those changes are merged and the hash updated to IronRDP latest master
github-merge-queue bot pushed a commit to gravitational/teleport that referenced this pull request Apr 16, 2024
* Updates commit-hash to IronRDP fix/resilient-blobtype HEAD

* Updates commit-hash to IronRDP fix/resilient-blobtype HEAD

* Updates to latest IronRDP hash. Note that this hash is of a still-open PR (Devolutions/IronRDP#436) and thus the IronRDP hash should be frozen until those changes are merged and the hash updated to IronRDP latest master
github-actions bot pushed a commit to gravitational/teleport that referenced this pull request Apr 16, 2024
…n PR (Devolutions/IronRDP#436) and thus the IronRDP hash should be frozen until those changes are merged and the hash updated to IronRDP latest master
github-merge-queue bot pushed a commit to gravitational/teleport that referenced this pull request Apr 16, 2024
* Updates commit-hash to IronRDP fix/resilient-blobtype HEAD

* Updates commit-hash to IronRDP fix/resilient-blobtype HEAD

* Updates to latest IronRDP hash. Note that this hash is of a still-open PR (Devolutions/IronRDP#436) and thus the IronRDP hash should be frozen until those changes are merged and the hash updated to IronRDP latest master
@pacmancoder pacmancoder self-assigned this Apr 16, 2024
@pacmancoder pacmancoder self-requested a review April 16, 2024 20:20
@pacmancoder
Copy link
Contributor

@ibeckermayer Benoit is on vacation, I'll take a look at it today👍

Copy link
Contributor

@pacmancoder pacmancoder left a comment

Choose a reason for hiding this comment

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

I have only a few minor comments to resolve before we merge, but overall a great job 👍

crates/ironrdp-connector/src/connection_finalization.rs Outdated Show resolved Hide resolved
crates/ironrdp-fuzzing/src/oracles/mod.rs Outdated Show resolved Hide resolved
crates/ironrdp-pdu/src/rdp/server_license.rs Outdated Show resolved Hide resolved
crates/ironrdp-connector/src/license_exchange.rs Outdated Show resolved Hide resolved
crates/ironrdp-connector/src/license_exchange.rs Outdated Show resolved Hide resolved
crates/ironrdp-connector/src/license_exchange.rs Outdated Show resolved Hide resolved
@@ -267,12 +268,13 @@ pub enum CapabilitySet {
BitmapCodecs(BitmapCodecs),

// other
FrameAcknowledge(FrameAcknowledge),
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe FrameAcknowledge should be moved above "other" comment as we already support/parse it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My understanding is that the groupings here are

@@ -322,6 +322,18 @@ pub enum ShareDataPdu {
ShutdownDenied,
SuppressOutput(SuppressOutputPdu),
RefreshRectangle(RefreshRectanglePdu),
Update(Vec<u8>),
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets separate "unparsed" variants with the comment (// Not implemented) as in CapabilitySet

Thought: (for follow-up refactoring at some time in future?) I don't like the idea of mixing named variants with parsed and unparsed data. If we implement new variant which was previously "unparsed", then we break the API each time a new feature is added. Maybe we need to refactor ShareDataPduType to be a struct with const's like BlobType, and then we could refactor ShareDataPdu to make is non_exhaustive and add a single Other variant for unparsed data like so:

Other {
    kind: ShareDataPduType,
    data: Vec<u8>
}

The same thing for the Capability set and similar types which can't be implemented in one go or could be extended in RDP standards.

cc @CBenoit

Copy link
Member

@CBenoit CBenoit Apr 18, 2024

Choose a reason for hiding this comment

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

I mostly agree! Here is an alternative:

struct ShareDataPduRaw<'a> {
    kind: ShareDataPduType,
    data: Cow<'a, [u8]>,
}

impl ShareDataPdu<'_> {
     fn parse(&self) -> Result<ShareDataPdu,> {}
}

With ShareDataPdu only including supported PDUs, and allowing graceful handling both known and unknown PDU types.

That being said, if the plan is to support all the different types soon enough, it’s probably fine to just add the new variants now instead. I don’t think the protocol will change that much by adding a new Share Data PDU type, and if it does, it will likely be controlled by compatibly flags during the handshake.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm going to punt on this one for now.

@CBenoit CBenoit changed the title Makes license parsing and protocol more resilient fix: make license parsing and protocol more resilient Apr 18, 2024
@CBenoit
Copy link
Member

CBenoit commented Apr 18, 2024

Thank you for this @ibeckermayer
I adjusted the name of the PR (for when it will be squashed). Otherwise I leave the rest to @pacmancoder 🙌

@ibeckermayer ibeckermayer mentioned this pull request Apr 24, 2024
4 tasks
Copy link
Contributor

@pacmancoder pacmancoder left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@pacmancoder pacmancoder merged commit 5c42ade into master Apr 25, 2024
7 checks passed
@pacmancoder pacmancoder deleted the fix/resilient-blobtype branch April 25, 2024 05:23
elmarco added a commit to elmarco/IronRDP that referenced this pull request Jun 10, 2024
According to
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73170ca2-5f82-4a2d-9d1b-b439f3d8dadc

wMsgSize is "the size in bytes of the licensing packet (including the
size of the preamble)". It must thus exclude BASIC_SECURITY_HEADER_SIZE.

Fixes mstsc connection to IronRDP server/acceptor.

Fixes 5c42ade ("fix: make license parsing and protocol more resilient (Devolutions#436)")
Signed-off-by: Marc-André Lureau <[email protected]>
CBenoit pushed a commit that referenced this pull request Jun 10, 2024
According to
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73170ca2-5f82-4a2d-9d1b-b439f3d8dadc

wMsgSize is "the size in bytes of the licensing packet (including the
size of the preamble)". It must thus exclude BASIC_SECURITY_HEADER_SIZE.

Fixes mstsc connection to IronRDP server/acceptor.

Fixes 5c42ade ("fix: make license parsing and protocol more resilient (#436)")
Signed-off-by: Marc-André Lureau <[email protected]>
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