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

Provide a function to easily return Hosts #60

Open
Dentrax opened this issue Sep 17, 2023 · 4 comments
Open

Provide a function to easily return Hosts #60

Dentrax opened this issue Sep 17, 2023 · 4 comments

Comments

@Dentrax
Copy link

Dentrax commented Sep 17, 2023

Currently we have to manually decode the configuration file:

f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
cfg, _ := ssh_config.Decode(f)
// cfg.Hosts

It'd be nice to have a function like ssh_config.GetHosts(). It should defaults to DefaultUserSettings unless overridden the config path from the parameters.

@kke
Copy link

kke commented Mar 21, 2024

The ssh_config does not define a list of "hosts" but a list of host matchers, global options, includes and match blocks. There's no point in getting a "list of hosts".

You can have something like:

Host *.example.com
  Port 31

Host secure.example.com
  StrictHostKeyChecking yes

Host !secure.example.com,*.example.com
  IdentityFile ~/foo

This will apply Port and StrictHostKeyChecking when connecting to secure.example.com and Port and IdentityFile when connecting to something-else.example.com.

@firelizzard18
Copy link

There is definitely a point: if for no other reason, I want tab-completion for my shell command, like what is available for the ssh command.

@kke
Copy link

kke commented Apr 25, 2024

There is definitely a point: if for no other reason, I want tab-completion for my shell command, like what is available for the ssh command.

I checked how the ssh completion works:

If you have already entered ssh -F <configname> it uses <configname> as the config filename, otherwise it uses the default locations (/etc/ssh/known_hosts and ~/.ssh/known_hosts and a couple of deprecated ones). It doesn't seem to follow any Include directives inside the configs.

It then scans the config(s) and looks for known_hosts file paths in GlobalKnownHostsFile and UserKnownHostsFile directives or falls back to default locations and then parses hostnames from the known hosts files.

It also looks for files in the ssh directories called key_22_<hostname>.pub and uses the <hostname> part.

Then, if it was invoked with the -a param (seems to be by default at least on mac) it uses sed on the ssh configs to find lines matching HostName or Host with params that do not contain wildcard patterns. (I spotted a bug here, it doesn't exclude lines that contain !negated.matchers for Host.) It doesn't look at the HostKeyAlias fields (perhaps intentionally, perhaps an omission?)

Then it tries to complete the hostnames using avahi-browses completion mechanism.

Finally it falls back to the completion system's internal hostname function (which looks at /etc/hosts).

It doesn't use anything but sed to "parse" the ssh configs, the ssh binary is only used for completing things like cipher names.

So, parsing the ssh config is just a small part of the ssh command's hostname completion and even that doesn't do it properly (doesn't follow Includes). If you want to duplicate that, you're better off using the same function in your completion, it's part of the bash_completion package itself, so if the user has bash completion, they also have the _known_hosts_real function available for use.

I didn't look into how it's done for other shells, but quite often it's done by leveraging the existing bash completion scripts.

@firelizzard18
Copy link

Or I could add a ForEach(func(*Host)) method, tweak Pattern to track if the pattern has meta characters, and use that to return a list of matching hosts. Which I did. And it was a lot easier than screwing around with someone else's shell functions.

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

No branches or pull requests

3 participants