• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

testdata/H25-Jul-2019-

.gitattributesH A D25-Jul-201928

.gitignoreH A D25-Jul-20190

.mailmapH A D25-Jul-201960

.travis.ymlH A D25-Jul-2019169

LICENSEH A D25-Jul-20192.2 KiB

MakefileH A D25-Jul-2019624

README.mdH A D25-Jul-20192.5 KiB

config.goH A D25-Jul-201917.2 KiB

config_test.goH A D25-Jul-20199.1 KiB

example_test.goH A D25-Jul-20191,012

lexer.goH A D25-Jul-20194 KiB

parser.goH A D25-Jul-20194.3 KiB

parser_test.goH A D25-Jul-2019423

position.goH A D25-Jul-2019711

token.goH A D25-Jul-2019847

validators.goH A D25-Jul-20198.2 KiB

validators_test.goH A D25-Jul-20191.2 KiB

README.md

1# ssh_config
2
3This is a Go parser for `ssh_config` files. Importantly, this parser attempts
4to preserve comments in a given file, so you can manipulate a `ssh_config` file
5from a program, if your heart desires.
6
7It's designed to be used with the excellent
8[x/crypto/ssh](https://golang.org/x/crypto/ssh) package, which handles SSH
9negotiation but isn't very easy to configure.
10
11The `ssh_config` `Get()` and `GetStrict()` functions will attempt to read values
12from `$HOME/.ssh/config` and fall back to `/etc/ssh/ssh_config`. The first
13argument is the host name to match on, and the second argument is the key you
14want to retrieve.
15
16```go
17port := ssh_config.Get("myhost", "Port")
18```
19
20You can also load a config file and read values from it.
21
22```go
23var config = `
24Host *.test
25  Compression yes
26`
27
28cfg, err := ssh_config.Decode(strings.NewReader(config))
29fmt.Println(cfg.Get("example.test", "Port"))
30```
31
32Some SSH arguments have default values - for example, the default value for
33`KeyboardAuthentication` is `"yes"`. If you call Get(), and no value for the
34given Host/keyword pair exists in the config, we'll return a default for the
35keyword if one exists.
36
37### Manipulating SSH config files
38
39Here's how you can manipulate an SSH config file, and then write it back to
40disk.
41
42```go
43f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
44cfg, _ := ssh_config.Decode(f)
45for _, host := range cfg.Hosts {
46    fmt.Println("patterns:", host.Patterns)
47    for _, node := range host.Nodes {
48        // Manipulate the nodes as you see fit, or use a type switch to
49        // distinguish between Empty, KV, and Include nodes.
50        fmt.Println(node.String())
51    }
52}
53
54// Print the config to stdout:
55fmt.Println(cfg.String())
56```
57
58## Spec compliance
59
60Wherever possible we try to implement the specification as documented in
61the `ssh_config` manpage. Unimplemented features should be present in the
62[issues][issues] list.
63
64Notably, the `Match` directive is currently unsupported.
65
66[issues]: https://github.com/kevinburke/ssh_config/issues
67
68## Errata
69
70This is the second [comment-preserving configuration parser][blog] I've written, after
71[an /etc/hosts parser][hostsfile]. Eventually, I will write one for every Linux
72file format.
73
74[blog]: https://kev.inburke.com/kevin/more-comment-preserving-configuration-parsers/
75[hostsfile]: https://github.com/kevinburke/hostsfile
76
77## Donating
78
79Donations free up time to make improvements to the library, and respond to
80bug reports. You can send donations via Paypal's "Send Money" feature to
81kev@inburke.com. Donations are not tax deductible in the USA.
82