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

host matching: handle wildcards with non-standard port #10

Merged
merged 1 commit into from
Jul 16, 2024

Conversation

evanelias
Copy link
Contributor

In OpenSSH, wildcard host pattern entries in a known_hosts file can match hosts regardless of their port number. However, x/crypto/ssh/knownhosts does not follow this behavior, instead requiring strict port equality; see bug golang/go#52056 for background, as well as discussion in previous PR #9.

This PR implements a workaround in skeema/knownhosts, which is enabled when using the NewDB constructor. Conceptually, the workaround works like this:

  • At constructor time, when re-reading the known_hosts file (originally to look for @cert-authority lines), also look for lines that have wildcards in the host pattern and no port number specified. Track these lines in a new field of the HostKeyDB struct for later use.

  • When a host key callback returns no matches (KeyError with empty Want slice) and the host had a nonstandard (non-22) port number, try the callback again, this time manipulating the host arg to be on port 22.

  • If this second call returned nil error, that means the host key now matched a known_hosts entry on port 22, so consider the host as known.

  • If this second call returned a KeyError with non-empty Want slice, filter down the resulting keys to only correspond to lines with known wildcards, using the preprocessed information from the first step. This ensures we aren't incorrectly returning non-wildcard entries among the Want slice.

The implementation for the latter 3 bullets gets embedded directly in the host key callback returned by HostKeyDB.HostKeyCallback, by way of some nested callback wrapping. This only happens if the first bullet actually found at least one wildcard in the file.

In OpenSSH, wildcard host pattern entries in a known_hosts file can match
hosts regardless of their port number. However, x/crypto/ssh/knownhosts does
not follow this behavior, instead requiring strict port equality; see bug
golang/go#52056 for background.

This commit implements a workaround in skeema/knownhosts, which is enabled
when using the NewDB constructor. Conceptually, the workaround works like
this:

* At constructor time, when re-reading the known_hosts file (originally to
  look for @cert-authority lines), also look for lines that have wildcards
  in the host pattern and no port number specified. Track these lines in a
  new field of the HostKeyDB struct for later use.

* When a host key callback returns no matches (KeyError with empty Want slice)
  and the host had a nonstandard (non-22) port number, try the callback again,
  this time manipulating the host arg to be on port 22.

* If this second call returned nil error, that means the host key now matched
  a known_hosts entry on port 22, so consider the host as known.

* If this second call returned a KeyError with non-empty Want slice, filter
  down the resulting keys to only correspond to lines with known wildcards,
  using the preprocessed information from the first step. This ensures we
  aren't incorrectly returning non-wildcard entries among the Want slice.

The implementation for the latter 3 bullets gets embedded directly in the
host key callback returned by HostKeyDB.HostKeyCallback, by way of some
nested callback wrapping. This only happens if the first bullet actually
found at least one wildcard in the file.
Copy link

Coverage Status

coverage: 93.305% (+0.4%) from 92.857%
when pulling 9706e13 on fix-wildcards-port-match
into 7c797a4 on main.

@evanelias
Copy link
Contributor Author

Merging momentarily based on positive feedback in #9 (comment) providing real-world confirmation it's working correctly, in addition to the unit tests

@evanelias evanelias merged commit 8b8ca37 into main Jul 16, 2024
4 checks passed
@evanelias evanelias deleted the fix-wildcards-port-match branch July 16, 2024 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant