Skip to content

Conversation

@artemredkin
Copy link
Contributor

Motivation:
RFC 4253, section 4.2 allows for server to send some lines before
version in version exchange. Right now we expect that version start with
SSH- only. We should support this.

Modifications:

  • Modifies version verification to allow clients tolerate lines before
    version
  • Adds tests that verify that client accepts lines and server doesn't

Result:
Closes #74

@artemredkin artemredkin force-pushed the support_lines_before_version branch 3 times, most recently from ee8bd24 to a3293de Compare February 19, 2021 11:56
@artemredkin artemredkin requested a review from Lukasa February 19, 2021 11:56
@Lukasa Lukasa added the 🔨 semver/patch No public API change. label Feb 19, 2021
Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

Cool, great start @artemredkin! I've got a few notes.

throw NIOSSHError.unsupportedVersion(version)
}

private func validateVersion<S: StringProtocol>(_ version: S) throws -> Bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's no real reason to make this generic over StringProtocol: we're only gonna operate on Substring so let's just accept that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we call this function with both String and Substring, we call it with string on line 66. Maybe alternative is to covert string to subtring there?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh yeah, let's do that. String -> Substring conversion is free.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

private func validateVersion<S: StringProtocol>(_ version: S) throws -> Bool {
if version.hasPrefix("SSH-") {
let start = version.index(version.startIndex, offsetBy: 4)
let end = version.index(start, offsetBy: 3)
Copy link
Contributor

Choose a reason for hiding this comment

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

These indices need to be validated: if the string was "SSH-" then both would be ineligible to be subscripted and the slice would be invalid. We need to confirm that the total count is appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right, fixed

}

private func validateVersion<S: StringProtocol>(_ version: S) throws -> Bool {
if version.hasPrefix("SSH-") {
Copy link
Contributor

Choose a reason for hiding this comment

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

Also all of this is being done on the grapheme clusters. We should consider doing all the work on the String UTF8View instead, which will give us much better performance as we don't need to worry about unicode here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

great idea, done!

return
}
}
throw NIOSSHError.protocolViolation(protocolName: "version exchange", violation: "version string not found")
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we have a test for this error, do we?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch, yes, added a test

@artemredkin artemredkin force-pushed the support_lines_before_version branch 2 times, most recently from ac54309 to 6eb89b7 Compare February 19, 2021 13:50
Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

One minor nit.

switch role {
case .client:
// split by \n
for line in banner.utf8.split(separator: 10) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We can give this a useful name: let carriageReturn = UInt8(ascii: "\n").

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah, looks nice, fixed

Motivation:
RFC 4253, section 4.2 allows for server to send some lines before
version in version exchange. Right now we expect that version start with
`SSH-` only. We should support this.

Modifications:
 - Modifies version verification to allow clients tolerate lines before
   version
 - Adds tests that verify that client accepts lines and server doesn't

Result:
Closes apple#74
@artemredkin artemredkin force-pushed the support_lines_before_version branch from 6eb89b7 to 22a5477 Compare February 19, 2021 15:03
Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

Nice, LGTM.

@Lukasa Lukasa merged commit 64179a8 into apple:main Feb 19, 2021
@artemredkin artemredkin deleted the support_lines_before_version branch March 3, 2021 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clients should tolerate arbitrary lines before SSH version in banner

2 participants