-
Notifications
You must be signed in to change notification settings - Fork 57
Support unknown global request types #18
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
Conversation
Motivation: SSH would throw errors when an unknown global request was received, and the message would be ignored (in violation of spec). Solution: Now, a message of SSH_MSG_REQUEST_FAILURE will be returned to the sender, and the unknown message is passed through far enough that potential future implementations could handle custom global requests.
|
Can one of the admins verify this patch? |
3 similar comments
|
Can one of the admins verify this patch? |
|
Can one of the admins verify this patch? |
|
Can one of the admins verify this patch? |
This adds (passing) tests for parsing and serialization. It also adds a broken test to verify that a reply of type SSH_MSG_REQUEST_FAILURE was received.
|
@Lukasa I could use a review on this PR. But in addition to a review, there is one broken test that needs to verify that |
Lukasa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few notes, but basically this patch looks great. I think your various test cases are already covered, so I don't think you have anything to do here: feel free to promote this into a full PR.
|
@swift-server-bot add to whitelist |
|
@Lukasa I assume that it looks great if the test succeeds, right? Or do you believe that test to be unnecessary? I appreciate the nitpicking, it's clever to preface those the way you did. I'll take that page out of your book :) |
|
Haha yes, naturally the CI needs to pass, but the code doesn't seem structurally wrong. |
|
This changes the global request implementation to support sending unknown global requests and changes the exposed types to support these cases as well. In addition, the pending global requests can now receive unknown responses and emit failures.
Lukasa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't strongly object to this change, but I think we need to refactor the code internally. There are more promises flowing around than we need. We only need a promise when the user is giving us something that they want to be notified on completion of. As we see all inbound and outbound messages, we never need promises internally, and so we shouldn't allocate them.
|
I strongly agree with your architectural vision without promises, especially for the internals. The vision that's consistently present throughout this project is one I look forward to applying elsewhere. Reflecting back upon this bit of code, I'd recommend making the helper initializer on |
Expose the GlobalRequestResponse type publicly whilst allowing future additions to the API. Fixed the bugs to pass the tests and updates the code according to feedback with the exception of one promise allocation.
Change the internal storage of the global requests queue to support a variety of expected successful responses
|
All the tests succeed locally. As I don't have access to the CI, I cannot see why the first test failed. |
|
The |
|
|
|
For reference: PR #24 is what I ran into, and should prevent people from running into the same issue later on. |
Lukasa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, looking really good. A few notes here and there, nothing substantial, just minor code structure feedback.
Update TCPForwardingResponse's comment to match the new situation. Make use of the `fail` helper on a pending global request in dropAllPendingGlobalRequests. Mak the RequestSuccessMessage internal again. Remove an redundant line of documentation.
Lukasa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, looks really good here. Two minor notes.
Lukasa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, ok, we're really close here. I have a tiny nit in the diff and we need to fix up the merge conflict. When that's done I'll do a sanity review to confirm the merge went ok, and then we should be ready to go!
Co-authored-by: Cory Benfield <[email protected]>
Lukasa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, looks fantastic. Thanks so much for this! ✨ 🍰
Fixed #17
Motivation:
Global requests come in many flavours, but are by no means a definitive list. The list is also not exhaustively populated by requests to forward a TCP socket. Especially the OpenSSH implementation(s) have a lot of custom global requests. More on that here.
Before this change, an unknown global request would throw an error which would be caught by the NIO.Channel wrapping this (global) SSH connection. This in turn tends to close the connection, which closes all running operations as well.
Modifications:
This PR tackles the above problems by introducing a new
GlobalRequestMessage"unknown". The unknown case contains the message type and the remainder of the payload. Since the payload's format changes depending on the message type, there is no way to parse this payload into something immediately useful.Instead, this unknown case can be ignored if the server does not want a reply. If it does want a reply, it's necessary to reply with
SSH_MSG_REQUEST_FAILURE.Result:
The message is not ignored, instead it can be handled by
receiveGlobalRequestwhere future updates can allow extension of the SSH protocol through here. No errors are thrown to the channel, which (potentially) leads to a closed TCP connection. Instead, the appropriate SSH_MSG_REQUEST_FAILURE is returned to the sender.TODO:
SSH_MSG_REQUEST_FAILURE