From 2117ff7552fa16c8834c52f22bc366a0b2c23a68 Mon Sep 17 00:00:00 2001 From: "red-hat-konflux[bot]" <126015336+red-hat-konflux[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:45:17 +0000 Subject: [PATCH] chore(deps): update module github.com/kevinburke/ssh_config to v1.5.0 Signed-off-by: red-hat-konflux <126015336+red-hat-konflux[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- .../kevinburke/ssh_config/.gitattributes | 1 - .../kevinburke/ssh_config/.gitignore | 1 + .../kevinburke/ssh_config/AUTHORS.txt | 2 + .../kevinburke/ssh_config/CHANGELOG.md | 31 +++++- .../github.com/kevinburke/ssh_config/Makefile | 16 +-- .../kevinburke/ssh_config/README.md | 10 +- .../kevinburke/ssh_config/SECURITY.md | 63 ++++++++++++ .../kevinburke/ssh_config/config.go | 99 ++++++++++++++----- .../kevinburke/ssh_config/parser.go | 79 +++++++++++++-- vendor/modules.txt | 4 +- 12 files changed, 263 insertions(+), 49 deletions(-) delete mode 100644 vendor/github.com/kevinburke/ssh_config/.gitattributes create mode 100644 vendor/github.com/kevinburke/ssh_config/SECURITY.md diff --git a/go.mod b/go.mod index 8dd469e4c..a280d7fb6 100644 --- a/go.mod +++ b/go.mod @@ -119,7 +119,7 @@ require ( github.com/jonboulle/clockwork v0.5.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/kevinburke/ssh_config v1.5.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect diff --git a/go.sum b/go.sum index 3c9a17932..3a11a0458 100644 --- a/go.sum +++ b/go.sum @@ -286,8 +286,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.5.0 h1:3cPZmE54xb5j3G5xQCjSvokqNwU2uW+3ry1+PRLSPpA= +github.com/kevinburke/ssh_config v1.5.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= diff --git a/vendor/github.com/kevinburke/ssh_config/.gitattributes b/vendor/github.com/kevinburke/ssh_config/.gitattributes deleted file mode 100644 index 44db58188..000000000 --- a/vendor/github.com/kevinburke/ssh_config/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -testdata/dos-lines eol=crlf diff --git a/vendor/github.com/kevinburke/ssh_config/.gitignore b/vendor/github.com/kevinburke/ssh_config/.gitignore index e69de29bb..46620af33 100644 --- a/vendor/github.com/kevinburke/ssh_config/.gitignore +++ b/vendor/github.com/kevinburke/ssh_config/.gitignore @@ -0,0 +1 @@ +/coverage.out diff --git a/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt b/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt index 311aeb1b4..c316990b3 100644 --- a/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt +++ b/vendor/github.com/kevinburke/ssh_config/AUTHORS.txt @@ -5,5 +5,7 @@ Kevin Burke Mark Nevill Scott Lessans Sergey Lukjanov +Simon Josefsson +sio2boss Wayne Ashley Berry santosh653 <70637961+santosh653@users.noreply.github.com> diff --git a/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md b/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md index d32a3f510..f9441dda7 100644 --- a/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md +++ b/vendor/github.com/kevinburke/ssh_config/CHANGELOG.md @@ -1,7 +1,34 @@ # Changes -## Version 1.2 +## Unreleased +- Implement Match support. Most of the Match spec is implemented, including +`Match host`, `Match originalhost`, `Match user`, `Match localuser`, and `Match +all`. `Match exec` is not yet implemented. + +- Add SECURITY.md + +- Add Dependabot configuration + +## Version 1.4 (released August 19, 2025) + +- Remove .gitattributes file (which was used to test different line endings, and +caused issues in some build environments). Store tests/dos-lines as CRLF in git +directly instead. + +## Version 1.3 (released February 20, 2025) + +- Add go.mod file (although this project has no dependencies). + +- config: add UserSettings.ConfigFinder + +- Various updates to CI and build environment + +## Version 1.2 (released March 31, 2022) + +- config: add DecodeBytes to directly read a byte array. + +- Strip trailing whitespace from Host declarations and key/value pairs. Previously, if a Host declaration or a value had trailing whitespace, that whitespace would have been included as part of the value. This led to unexpected consequences. For example: @@ -17,3 +44,5 @@ unintuitive. Instead, we strip the trailing whitespace in the configuration, which leads to more intuitive behavior. + +- Add fuzz tests. diff --git a/vendor/github.com/kevinburke/ssh_config/Makefile b/vendor/github.com/kevinburke/ssh_config/Makefile index df7ee728b..25a357025 100644 --- a/vendor/github.com/kevinburke/ssh_config/Makefile +++ b/vendor/github.com/kevinburke/ssh_config/Makefile @@ -1,21 +1,21 @@ BUMP_VERSION := $(GOPATH)/bin/bump_version -STATICCHECK := $(GOPATH)/bin/staticcheck WRITE_MAILMAP := $(GOPATH)/bin/write_mailmap -$(STATICCHECK): - go get honnef.co/go/tools/cmd/staticcheck - -lint: $(STATICCHECK) +lint: go vet ./... - $(STATICCHECK) + go run honnef.co/go/tools/cmd/staticcheck@latest ./... -test: lint +test: @# the timeout helps guard against infinite recursion go test -timeout=250ms ./... -race-test: lint +race-test: go test -timeout=500ms -race ./... +coverage: + go test -trimpath -timeout=250ms -coverprofile=coverage.out -covermode=atomic ./... + go tool cover -func=coverage.out + $(BUMP_VERSION): go get -u github.com/kevinburke/bump_version diff --git a/vendor/github.com/kevinburke/ssh_config/README.md b/vendor/github.com/kevinburke/ssh_config/README.md index f14b2168f..705605e2f 100644 --- a/vendor/github.com/kevinburke/ssh_config/README.md +++ b/vendor/github.com/kevinburke/ssh_config/README.md @@ -82,11 +82,11 @@ file format. [blog]: https://kev.inburke.com/kevin/more-comment-preserving-configuration-parsers/ [hostsfile]: https://github.com/kevinburke/hostsfile -## Donating +## Sponsorships -I don't get paid to maintain this project. Donations free up time to make -improvements to the library, and respond to bug reports. You can send donations -via Paypal's "Send Money" feature to kev@inburke.com. Donations are not tax -deductible in the USA. +Thank you very much to Tailscale and Indeed for sponsoring development of this +library. [Sponsors][sponsors] will get their names featured in the README. You can also reach out about a consulting engagement: https://burke.services + +[sponsors]: https://github.com/sponsors/kevinburke diff --git a/vendor/github.com/kevinburke/ssh_config/SECURITY.md b/vendor/github.com/kevinburke/ssh_config/SECURITY.md new file mode 100644 index 000000000..adc2c5ab7 --- /dev/null +++ b/vendor/github.com/kevinburke/ssh_config/SECURITY.md @@ -0,0 +1,63 @@ +# ssh_config security policy + +## Supported Versions + +As of September 2025, we're not aware of any security problems with ssh_config, +past or present. That said, we recommend always using the latest version of +ssh_config, and of the Go programming language, to ensure you have the most +recent security fixes. + +## Reporting a Vulnerability + +We take security vulnerabilities seriously. If you discover a security vulnerability in ssh_config, please report it responsibly by following these steps: + +### How to Report + +Please follow the instructions outlined here to report a vulnerability +privately: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability + +If these are insufficient - it is not hard to find Kevin's contact information +on the Internet. + +### What to Include + +When reporting a vulnerability, please include a clear description of the vulnerability, steps to reproduce the issue, the potential impact, as well as any fixes you might have. + +### Response Timeline + +I'll try to acknowledge and patch the issue as quickly as possible. + +Security advisories for this project will be published through: +- GitHub Security Advisories on this repository +- an Issue on this repository +- The project's release notes +- Go vulnerability databases + +If you are using `ssh_config` and would like to be on a "pre-release" +distribution list for coordinating releases, please contact Kevin directly. + +### Security Considerations + +When using ssh_config, please be aware of these security considerations. + +#### File System Access + +This library reads SSH configuration files from the file system. Try to ensure +proper file permissions on SSH config files (typically 600 or 644), and be +cautious when parsing config files from untrusted sources. + +#### Input Validation + +The parser handles user-provided SSH configuration data. While we try our best +to parse the data appropriately, malformed configuration files could potentially +cause issues. Please try to validate and sanitize any configuration data from +external sources. + +#### Dependencies + +This project does not have any third party dependencies. Please try to keep your +Go version up to date. + +## Acknowledgments + +We appreciate security researchers and users who responsibly disclose vulnerabilities. Contributors who report valid security issues will be acknowledged in our security advisories (unless they prefer to remain anonymous). diff --git a/vendor/github.com/kevinburke/ssh_config/config.go b/vendor/github.com/kevinburke/ssh_config/config.go index 00d815c1a..30c9a4b36 100644 --- a/vendor/github.com/kevinburke/ssh_config/config.go +++ b/vendor/github.com/kevinburke/ssh_config/config.go @@ -8,7 +8,7 @@ // the host name to match on ("example.com"), and the second argument is the key // you want to retrieve ("Port"). The keywords are case insensitive. // -// port := ssh_config.Get("myhost", "Port") +// port := ssh_config.Get("myhost", "Port") // // You can also manipulate an SSH config file and then print it or write it back // to disk. @@ -24,9 +24,6 @@ // // // Write the cfg back to disk: // fmt.Println(cfg.String()) -// -// BUG: the Match directive is currently unsupported; parsing a config with -// a Match directive will trigger an error. package ssh_config import ( @@ -43,7 +40,7 @@ import ( "sync" ) -const version = "1.2" +const version = "1.5.0" var _ = version @@ -53,6 +50,8 @@ type configFinder func() string // files are parsed and cached the first time Get() or GetStrict() is called. type UserSettings struct { IgnoreErrors bool + customConfig *Config + customConfigFinder configFinder systemConfig *Config systemConfigFinder configFinder userConfig *Config @@ -203,6 +202,13 @@ func (u *UserSettings) GetStrict(alias, key string) (string, error) { if u.onceErr != nil && u.IgnoreErrors == false { return "", u.onceErr } + // TODO this is getting repetitive + if u.customConfig != nil { + val, err := findVal(u.customConfig, alias, key) + if err != nil || val != "" { + return val, err + } + } val, err := findVal(u.userConfig, alias, key) if err != nil || val != "" { return val, err @@ -228,6 +234,12 @@ func (u *UserSettings) GetAllStrict(alias, key string) ([]string, error) { if u.onceErr != nil && u.IgnoreErrors == false { return nil, u.onceErr } + if u.customConfig != nil { + val, err := findAll(u.customConfig, alias, key) + if err != nil || val != nil { + return val, err + } + } val, err := findAll(u.userConfig, alias, key) if err != nil || val != nil { return val, err @@ -243,16 +255,38 @@ func (u *UserSettings) GetAllStrict(alias, key string) ([]string, error) { return []string{}, nil } +// ConfigFinder will invoke f to try to find a ssh config file in a custom +// location on disk, instead of in /etc/ssh or $HOME/.ssh. f should return the +// name of a file containing SSH configuration. +// +// ConfigFinder must be invoked before any calls to Get or GetStrict and panics +// if f is nil. Most users should not need to use this function. +func (u *UserSettings) ConfigFinder(f func() string) { + if f == nil { + panic("cannot call ConfigFinder with nil function") + } + u.customConfigFinder = f +} + func (u *UserSettings) doLoadConfigs() { u.loadConfigs.Do(func() { - // can't parse user file, that's ok. var filename string + var err error + if u.customConfigFinder != nil { + filename = u.customConfigFinder() + u.customConfig, err = parseFile(filename) + // IsNotExist should be returned because a user specified this + // function - not existing likely means they made an error + if err != nil { + u.onceErr = err + } + return + } if u.userConfigFinder == nil { filename = userConfigFinder() } else { filename = u.userConfigFinder() } - var err error u.userConfig, err = parseFile(filename) //lint:ignore S1002 I prefer it this way if err != nil && os.IsNotExist(err) == false { @@ -351,9 +385,6 @@ func (c *Config) Get(alias, key string) (string, error) { case *KV: // "keys are case insensitive" per the spec lkey := strings.ToLower(t.Key) - if lkey == "match" { - panic("can't handle Match directives") - } if lkey == lowerKey { return t.Value, nil } @@ -386,9 +417,6 @@ func (c *Config) GetAll(alias, key string) ([]string, error) { case *KV: // "keys are case insensitive" per the spec lkey := strings.ToLower(t.Key) - if lkey == "match" { - panic("can't handle Match directives") - } if lkey == lowerKey { all = append(all, t.Value) } @@ -433,6 +461,9 @@ type Pattern struct { // String prints the string representation of the pattern. func (p Pattern) String() string { + if p.not { + return "!" + p.str + } return p.str } @@ -491,7 +522,7 @@ func NewPattern(s string) (*Pattern, error) { return &Pattern{str: s, regex: r, not: negated}, nil } -// Host describes a Host directive and the keywords that follow it. +// Host describes a Host or Match directive and the keywords that follow it. type Host struct { // A list of host patterns that should match this host. Patterns []*Pattern @@ -506,6 +537,11 @@ type Host struct { leadingSpace int // TODO: handle spaces vs tabs here. // The file starts with an implicit "Host *" declaration. implicit bool + // isMatch is true if this block was created by a Match directive. + isMatch bool + // matchKeyword stores the original text after "Match" (e.g. "Host" or + // "all") so we can round-trip correctly. + matchKeyword string } // Matches returns true if the Host matches for the given alias. For @@ -537,17 +573,36 @@ func (h *Host) String() string { //lint:ignore S1002 I prefer to write it this way if h.implicit == false { buf.WriteString(strings.Repeat(" ", int(h.leadingSpace))) - buf.WriteString("Host") - if h.hasEquals { - buf.WriteString(" = ") + if h.isMatch { + buf.WriteString("Match") + if h.hasEquals { + buf.WriteString(" = ") + } else { + buf.WriteString(" ") + } + buf.WriteString(h.matchKeyword) + if !strings.EqualFold(h.matchKeyword, "all") { + buf.WriteString(" ") + for i, pat := range h.Patterns { + buf.WriteString(pat.String()) + if i < len(h.Patterns)-1 { + buf.WriteString(" ") + } + } + } } else { - buf.WriteString(" ") - } - for i, pat := range h.Patterns { - buf.WriteString(pat.String()) - if i < len(h.Patterns)-1 { + buf.WriteString("Host") + if h.hasEquals { + buf.WriteString(" = ") + } else { buf.WriteString(" ") } + for i, pat := range h.Patterns { + buf.WriteString(pat.String()) + if i < len(h.Patterns)-1 { + buf.WriteString(" ") + } + } } buf.WriteString(h.spaceBeforeComment) if h.EOLComment != "" { diff --git a/vendor/github.com/kevinburke/ssh_config/parser.go b/vendor/github.com/kevinburke/ssh_config/parser.go index 2b1e718cb..4a6c04e7c 100644 --- a/vendor/github.com/kevinburke/ssh_config/parser.go +++ b/vendor/github.com/kevinburke/ssh_config/parser.go @@ -21,9 +21,9 @@ type sshParser struct { type sshParserStateFn func() sshParserStateFn // Formats and panics an error message based on a token -func (p *sshParser) raiseErrorf(tok *token, msg string, args ...interface{}) { +func (p *sshParser) raiseErrorf(tok *token, msg string) { // TODO this format is ugly - panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...)) + panic(tok.Position.String() + ": " + msg) } func (p *sshParser) raiseError(tok *token, err error) { @@ -105,9 +105,7 @@ func (p *sshParser) parseKV() sshParserStateFn { comment = tok.val } if strings.ToLower(key.val) == "match" { - // https://github.com/kevinburke/ssh_config/issues/6 - p.raiseErrorf(val, "ssh_config: Match directive parsing is unsupported") - return nil + return p.parseMatch(val, hasEquals, comment) } if strings.ToLower(key.val) == "host" { strPatterns := strings.Split(val.val, " ") @@ -118,7 +116,7 @@ func (p *sshParser) parseKV() sshParserStateFn { } pat, err := NewPattern(strPatterns[i]) if err != nil { - p.raiseErrorf(val, "Invalid host pattern: %v", err) + p.raiseErrorf(val, fmt.Sprintf("Invalid host pattern: %v", err)) return nil } patterns = append(patterns, pat) @@ -144,7 +142,7 @@ func (p *sshParser) parseKV() sshParserStateFn { return nil } if err != nil { - p.raiseErrorf(val, "Error parsing Include directive: %v", err) + p.raiseErrorf(val, fmt.Sprintf("Error parsing Include directive: %v", err)) return nil } lastHost.Nodes = append(lastHost.Nodes, inc) @@ -165,6 +163,73 @@ func (p *sshParser) parseKV() sshParserStateFn { return p.parseStart } +func (p *sshParser) parseMatch(val *token, hasEquals bool, comment string) sshParserStateFn { + // val.val contains everything after "Match ", e.g. "Host *.example.com" + // or "all". + trimmed := strings.TrimRightFunc(val.val, unicode.IsSpace) + spaceBeforeComment := val.val[len(trimmed):] + fields := strings.Fields(trimmed) + if len(fields) == 0 { + p.raiseErrorf(val, "ssh_config: Match directive requires at least one criterion") + return nil + } + criterion := strings.ToLower(fields[0]) + + switch criterion { + case "all": + // "Match all" is equivalent to "Host *" — matches everything. + p.config.Hosts = append(p.config.Hosts, &Host{ + Patterns: []*Pattern{matchAll}, + Nodes: make([]Node, 0), + EOLComment: comment, + spaceBeforeComment: spaceBeforeComment, + hasEquals: hasEquals, + isMatch: true, + matchKeyword: fields[0], // preserve original case + }) + return p.parseStart + + case "host": + patterns := make([]*Pattern, 0) + for _, s := range fields[1:] { + if s == "" { + continue + } + pat, err := NewPattern(s) + if err != nil { + p.raiseErrorf(val, fmt.Sprintf("Invalid host pattern: %v", err)) + return nil + } + patterns = append(patterns, pat) + } + if len(patterns) == 0 { + p.raiseErrorf(val, "ssh_config: Match Host requires at least one pattern") + return nil + } + p.config.Hosts = append(p.config.Hosts, &Host{ + Patterns: patterns, + Nodes: make([]Node, 0), + EOLComment: comment, + spaceBeforeComment: spaceBeforeComment, + hasEquals: hasEquals, + isMatch: true, + matchKeyword: fields[0], // preserve original case + }) + return p.parseStart + + case "exec": + // Match Exec runs arbitrary commands. Supporting it would allow + // untrusted SSH config files to execute code on the parsing + // machine. Reject it explicitly. + p.raiseErrorf(val, "ssh_config: Match Exec is not supported") + return nil + + default: + p.raiseErrorf(val, fmt.Sprintf("ssh_config: unsupported Match criterion %q", criterion)) + return nil + } +} + func (p *sshParser) parseComment() sshParserStateFn { comment := p.getToken() lastHost := p.config.Hosts[len(p.config.Hosts)-1] diff --git a/vendor/modules.txt b/vendor/modules.txt index 90e0e938b..ddb712c63 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -519,8 +519,8 @@ github.com/json-iterator/go # github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 ## explicit github.com/kballard/go-shellquote -# github.com/kevinburke/ssh_config v1.2.0 -## explicit +# github.com/kevinburke/ssh_config v1.5.0 +## explicit; go 1.18 github.com/kevinburke/ssh_config # github.com/klauspost/compress v1.18.0 ## explicit; go 1.22