diff --git a/dialer/ssh/metadata.go b/dialer/ssh/metadata.go index 2fa8315..9ceafc8 100644 --- a/dialer/ssh/metadata.go +++ b/dialer/ssh/metadata.go @@ -1,11 +1,13 @@ package ssh import ( + "fmt" "os" "time" mdata "github.com/go-gost/core/metadata" mdutil "github.com/go-gost/core/metadata/util" + "github.com/zalando/go-keyring" "golang.org/x/crypto/ssh" ) @@ -20,9 +22,10 @@ type metadata struct { func (d *sshDialer) parseMetadata(md mdata.Metadata) (err error) { const ( - handshakeTimeout = "handshakeTimeout" - privateKeyFile = "privateKeyFile" - passphrase = "passphrase" + handshakeTimeout = "handshakeTimeout" + privateKeyFile = "privateKeyFile" + passphrase = "passphrase" + passphraseFromKeyring = "passphraseFromKeyring" ) if key := mdutil.GetString(md, privateKeyFile); key != "" { @@ -31,10 +34,19 @@ func (d *sshDialer) parseMetadata(md mdata.Metadata) (err error) { return err } - if pp := mdutil.GetString(md, passphrase); pp != "" { - d.md.signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(pp)) + var pp string + if mdutil.GetBool(md, "passphraseFromKeyring") { + pp, err = keyring.Get(fmt.Sprintf("SSH %s", key), d.options.Auth.Username()) + if err != nil { + return fmt.Errorf("unable to get secret(%s) from keyring: %w", key, err) + } } else { + pp = mdutil.GetString(md, passphrase) + } + if pp == "" { d.md.signer, err = ssh.ParsePrivateKey(data) + } else { + d.md.signer, err = ssh.ParsePrivateKeyWithPassphrase(data, []byte(pp)) } if err != nil { return err diff --git a/dialer/sshd/metadata.go b/dialer/sshd/metadata.go index 4a9b484..3185927 100644 --- a/dialer/sshd/metadata.go +++ b/dialer/sshd/metadata.go @@ -1,11 +1,13 @@ package sshd import ( + "fmt" "os" "time" mdata "github.com/go-gost/core/metadata" mdutil "github.com/go-gost/core/metadata/util" + "github.com/zalando/go-keyring" "golang.org/x/crypto/ssh" ) @@ -31,7 +33,15 @@ func (d *sshdDialer) parseMetadata(md mdata.Metadata) (err error) { return err } - pp := mdutil.GetString(md, passphrase) + var pp string + if mdutil.GetBool(md, "passphraseFromKeyring") { + pp, err = keyring.Get(fmt.Sprintf("SSH %s", key), key) + if err != nil { + return fmt.Errorf("unable to get secret(%s) from keyring: %w", key, err) + } + } else { + pp = mdutil.GetString(md, passphrase) + } if pp == "" { d.md.signer, err = ssh.ParsePrivateKey(data) } else { diff --git a/go.mod b/go.mod index 1b60dee..83cb1ce 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/xtaci/smux v1.5.24 github.com/xtaci/tcpraw v1.2.25 github.com/yl2chen/cidranger v1.0.2 + github.com/zalando/go-keyring v0.2.4 golang.org/x/crypto v0.17.0 golang.org/x/net v0.19.0 golang.org/x/sys v0.15.0 @@ -49,12 +50,14 @@ require ( require ( github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect + github.com/alessio/shellescape v1.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.10.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/coreos/go-iptables v0.5.0 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -64,6 +67,7 @@ require ( github.com/go-playground/validator/v10 v10.16.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 // indirect diff --git a/go.sum b/go.sum index 03a3bb1..84b4e18 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -26,6 +28,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-iptables v0.5.0 h1:mw6SAibtHKZcNzAsOxjoHIG0gy5YFHhypWSSNc6EjbQ= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -79,6 +83,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -214,6 +220,7 @@ github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -253,6 +260,8 @@ github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1Gg github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU= github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zalando/go-keyring v0.2.4 h1:wi2xxTqdiwMKbM6TWwi+uJCG/Tum2UV0jqaQhCa9/68= +github.com/zalando/go-keyring v0.2.4/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= diff --git a/listener/sshd/metadata.go b/listener/sshd/metadata.go index f4d3497..7d1b900 100644 --- a/listener/sshd/metadata.go +++ b/listener/sshd/metadata.go @@ -1,11 +1,13 @@ package ssh import ( + "fmt" "os" mdata "github.com/go-gost/core/metadata" mdutil "github.com/go-gost/core/metadata/util" ssh_util "github.com/go-gost/x/internal/util/ssh" + "github.com/zalando/go-keyring" "golang.org/x/crypto/ssh" ) @@ -34,7 +36,15 @@ func (l *sshdListener) parseMetadata(md mdata.Metadata) (err error) { return err } - pp := mdutil.GetString(md, passphrase) + var pp string + if mdutil.GetBool(md, "passphraseFromKeyring") { + pp, err = keyring.Get(fmt.Sprintf("SSH %s", key), l.options.Auth.Username()) + if err != nil { + return fmt.Errorf("unable to get secret(%s) from keyring: %w", key, err) + } + } else { + pp = mdutil.GetString(md, passphrase) + } if pp == "" { l.md.signer, err = ssh.ParsePrivateKey(data) } else {