From 97747ea0f3178f7f5890512d483fdccaa82846b0 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 9 Oct 2021 21:10:29 +0300 Subject: vetting and linting and some code restyling --- internal/ssh/client/authmethods.go | 41 ++++++++++++++++++++----------- internal/ssh/client/customkeycallback.go | 3 +-- internal/ssh/client/knownhostscallback.go | 19 +++----------- internal/ssh/server/hostkey.go | 3 ++- internal/ssh/server/publickeycallback.go | 27 +++++++++++--------- internal/ssh/ssh.go | 4 --- 6 files changed, 48 insertions(+), 49 deletions(-) (limited to 'internal/ssh') diff --git a/internal/ssh/client/authmethods.go b/internal/ssh/client/authmethods.go index 4508319..ced1fb9 100644 --- a/internal/ssh/client/authmethods.go +++ b/internal/ssh/client/authmethods.go @@ -11,7 +11,10 @@ import ( ) // InitSSHAuthMethods initialises all known SSH auth methods on the client side. -func InitSSHAuthMethods(sshAuthMethods []gossh.AuthMethod, hostKeyCallback gossh.HostKeyCallback, trustAllHosts bool, throttleCh chan struct{}, privateKeyPath string) ([]gossh.AuthMethod, HostKeyCallback) { +func InitSSHAuthMethods(sshAuthMethods []gossh.AuthMethod, + hostKeyCallback gossh.HostKeyCallback, trustAllHosts bool, throttleCh chan struct{}, + privateKeyPath string) ([]gossh.AuthMethod, HostKeyCallback) { + if len(sshAuthMethods) > 0 { simpleCallback, err := NewSimpleCallback() if err != nil { @@ -19,20 +22,21 @@ func InitSSHAuthMethods(sshAuthMethods []gossh.AuthMethod, hostKeyCallback gossh } return sshAuthMethods, simpleCallback } - return initKnownHostsAuthMethods(trustAllHosts, throttleCh, privateKeyPath) } -func initKnownHostsAuthMethods(trustAllHosts bool, throttleCh chan struct{}, privateKeyPath string) ([]gossh.AuthMethod, HostKeyCallback) { - var sshAuthMethods []gossh.AuthMethod +func initKnownHostsAuthMethods(trustAllHosts bool, throttleCh chan struct{}, + privateKeyPath string) ([]gossh.AuthMethod, HostKeyCallback) { + var sshAuthMethods []gossh.AuthMethod knownHostsPath := os.Getenv("HOME") + "/.ssh/known_hosts" - knownHostsCallback, err := NewKnownHostsCallback(knownHostsPath, trustAllHosts, throttleCh) + knownHostsCallback, err := NewKnownHostsCallback(knownHostsPath, trustAllHosts, + throttleCh) if err != nil { dlog.Common.FatalPanic(knownHostsPath, err) } - dlog.Common.Debug("initKnownHostsAuthMethods", "Added known hosts file path", knownHostsPath) - + dlog.Common.Debug("initKnownHostsAuthMethods", "Added known hosts file path", + knownHostsPath) if config.Common.ExperimentalFeaturesEnable { sshAuthMethods = append(sshAuthMethods, gossh.Password("experimental feature test")) dlog.Common.Debug("initKnownHostsAuthMethods", "Added experimental method to list of auth methods") @@ -43,7 +47,9 @@ func initKnownHostsAuthMethods(trustAllHosts bool, throttleCh chan struct{}, pri authMethod, err := ssh.PrivateKey(privateKeyPath) if err == nil { sshAuthMethods = append(sshAuthMethods, authMethod) - dlog.Common.Debug("initKnownHostsAuthMethods", "Added path to list of auth methods, not adding further methods", privateKeyPath) + dlog.Common.Debug("initKnownHostsAuthMethods", + "Added path to list of auth methods, not adding further methods", + privateKeyPath) return sshAuthMethods, knownHostsCallback } dlog.Common.FatalPanic("Unable to use private SSH key", privateKeyPath, err) @@ -53,30 +59,35 @@ func initKnownHostsAuthMethods(trustAllHosts bool, throttleCh chan struct{}, pri authMethod, err := ssh.Agent() if err == nil { sshAuthMethods = append(sshAuthMethods, authMethod) - dlog.Common.Debug("initKnownHostsAuthMethods", "Added SSH Agent (SSH_AUTH_SOCK) to list of auth methods, not adding further methods") + dlog.Common.Debug("initKnownHostsAuthMethods", "Added SSH Agent (SSH_AUTH_SOCK)"+ + "to list of auth methods, not adding further methods") return sshAuthMethods, knownHostsCallback } - dlog.Common.Debug("initKnownHostsAuthMethods", "Unable to init SSH Agent auth method", err) + dlog.Common.Debug("initKnownHostsAuthMethods", + "Unable to init SSH Agent auth method", err) // Third, try Linux/UNIX default key paths privateKeyPath = os.Getenv("HOME") + "/.ssh/id_rsa" authMethod, err = ssh.PrivateKey(privateKeyPath) if err == nil { sshAuthMethods = append(sshAuthMethods, authMethod) - dlog.Common.Debug("initKnownHostsAuthmethods", "Added path to list of auth methods, not adding further methods", privateKeyPath) + dlog.Common.Debug("initKnownHostsAuthmethods", + "Added path to list of auth methods, not adding further methods", privateKeyPath) return sshAuthMethods, knownHostsCallback } - dlog.Common.Debug("initKnownHostsAuthMethods", "Unable to use private key", privateKeyPath, err) + dlog.Common.Debug("initKnownHostsAuthMethods", "Unable to use private key", + privateKeyPath, err) privateKeyPath = os.Getenv("HOME") + "/.ssh/id_dsa" authMethod, err = ssh.PrivateKey(privateKeyPath) if err == nil { sshAuthMethods = append(sshAuthMethods, authMethod) - dlog.Common.Debug("initKnownHostsAuthmethods", "Added path to list of auth methods, not adding further methods", privateKeyPath) + dlog.Common.Debug("initKnownHostsAuthmethods", + "Added path to list of auth methods, not adding further methods", privateKeyPath) return sshAuthMethods, knownHostsCallback } - dlog.Common.Debug("initKnownHostsAuthMethods", "Unable to use private key", privateKeyPath, err) - + dlog.Common.Debug("initKnownHostsAuthMethods", "Unable to use private key", + privateKeyPath, err) dlog.Common.FatalPanic("Unable to find private SSH key information") // Never reach this point. diff --git a/internal/ssh/client/customkeycallback.go b/internal/ssh/client/customkeycallback.go index 73e5289..53b8e3c 100644 --- a/internal/ssh/client/customkeycallback.go +++ b/internal/ssh/client/customkeycallback.go @@ -7,8 +7,7 @@ import ( ) // CustomCallback is a custom host key callback wrapper. -type CustomCallback struct { -} +type CustomCallback struct{} // NewCustomCallback returns a new wrapper. func NewCustomCallback() (*CustomCallback, error) { diff --git a/internal/ssh/client/knownhostscallback.go b/internal/ssh/client/knownhostscallback.go index a73d612..65a590a 100644 --- a/internal/ssh/client/knownhostscallback.go +++ b/internal/ssh/client/knownhostscallback.go @@ -46,8 +46,9 @@ type KnownHostsCallback struct { } // NewKnownHostsCallback returns a new wrapper. -func NewKnownHostsCallback(knownHostsPath string, trustAllHosts bool, throttleCh chan struct{}) (HostKeyCallback, error) { - // Ensure file exists +func NewKnownHostsCallback(knownHostsPath string, trustAllHosts bool, + throttleCh chan struct{}) (HostKeyCallback, error) { + os.OpenFile(knownHostsPath, os.O_RDONLY|os.O_CREATE, 0666) untrustedHosts := make(map[string]bool) @@ -59,11 +60,9 @@ func NewKnownHostsCallback(knownHostsPath string, trustAllHosts bool, throttleCh untrustedHosts: untrustedHosts, mutex: &sync.Mutex{}, } - if trustAllHosts { close(c.trustAllHostsCh) } - return c, nil } @@ -75,14 +74,12 @@ func (c KnownHostsCallback) Wrap() ssh.HostKeyCallback { if err != nil { return err } - // Check for valid entry in known_hosts file err = knownHostsCb(server, remote, key) if err == nil { // OK return nil } - // Make sure that interactive user callback does not interfere with // SSH connection throttler. <-c.throttleCh @@ -96,11 +93,9 @@ func (c KnownHostsCallback) Wrap() ssh.HostKeyCallback { ipLine: knownhosts.Line([]string{remote.String()}, key), responseCh: make(chan response), } - dlog.Common.Warn("Encountered unknown host", unknown) // Notify user that there is an unknown host c.unknownCh <- unknown - // Wait for user input. switch <-unknown.responseCh { case trustHost: @@ -112,7 +107,6 @@ func (c KnownHostsCallback) Wrap() ssh.HostKeyCallback { c.mutex.Lock() defer c.mutex.Unlock() c.untrustedHosts[server] = true - return err } } @@ -121,7 +115,6 @@ func (c KnownHostsCallback) Wrap() ssh.HostKeyCallback { // be added to the known hosts or not. func (c KnownHostsCallback) PromptAddHosts(ctx context.Context) { var hosts []unknownHost - for { // Check whether there is a unknown host select { @@ -147,7 +140,6 @@ func (c KnownHostsCallback) PromptAddHosts(ctx context.Context) { func (c KnownHostsCallback) promptAddHosts(hosts []unknownHost) { var servers []string - for _, host := range hosts { servers = append(servers, host.server) } @@ -165,7 +157,6 @@ func (c KnownHostsCallback) promptAddHosts(hosts []unknownHost) { strings.Join(servers, ","), "Do you want to trust these hosts?", ) - p := prompt.New(question) a := prompt.Answer{ @@ -223,7 +214,6 @@ func (c KnownHostsCallback) promptAddHosts(hosts []unknownHost) { func (c KnownHostsCallback) trustHosts(hosts []unknownHost) { tmpKnownHostsPath := fmt.Sprintf("%s.tmp", c.knownHostsPath) - newFd, err := os.OpenFile(tmpKnownHostsPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) if err != nil { panic(fmt.Sprintf("%s: %s", tmpKnownHostsPath, err.Error())) @@ -232,7 +222,6 @@ func (c KnownHostsCallback) trustHosts(hosts []unknownHost) { // Newly trusted hosts in normalized form addresses := make(map[string]struct{}) - // First write to new known hosts file, and keep track of addresses for _, unknown := range hosts { unknown.responseCh <- trustHost @@ -255,7 +244,6 @@ func (c KnownHostsCallback) trustHosts(hosts []unknownHost) { defer oldFd.Close() scanner := bufio.NewScanner(oldFd) - // Now, append all still valid old entries to the new host file for scanner.Scan() { line := scanner.Text() @@ -283,6 +271,5 @@ func (c KnownHostsCallback) Untrusted(server string) bool { c.mutex.Lock() defer c.mutex.Unlock() _, ok := c.untrustedHosts[server] - return ok } diff --git a/internal/ssh/server/hostkey.go b/internal/ssh/server/hostkey.go index 20de1f0..33bd4e8 100644 --- a/internal/ssh/server/hostkey.go +++ b/internal/ssh/server/hostkey.go @@ -24,7 +24,8 @@ func PrivateHostKey() []byte { pem := ssh.EncodePrivateKeyToPEM(privateKey) if err := ioutil.WriteFile(hostKeyFile, pem, 0600); err != nil { - dlog.Common.Error("Unable to write private server RSA host key to file", hostKeyFile, err) + dlog.Common.Error("Unable to write private server RSA host key to file", + hostKeyFile, err) } return pem } diff --git a/internal/ssh/server/publickeycallback.go b/internal/ssh/server/publickeycallback.go index 59d1f31..ebc428a 100644 --- a/internal/ssh/server/publickeycallback.go +++ b/internal/ssh/server/publickeycallback.go @@ -13,25 +13,28 @@ import ( gossh "golang.org/x/crypto/ssh" ) -// PublicKeyCallback is for the server to check whether a public SSH key is authorized ot not. -func PublicKeyCallback(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) { +// PublicKeyCallback is for the server to check whether a public SSH key is +// authorized ot not. +func PublicKeyCallback(c gossh.ConnMetadata, + offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) { + user, err := user.New(c.User(), c.RemoteAddr().String()) if err != nil { return nil, err } - dlog.Common.Info(user, "Incoming authorization") + dlog.Common.Info(user, "Incoming authorization") cwd, err := os.Getwd() if err != nil { return nil, fmt.Errorf("Unable to get current working directory|%s|", err.Error()) } - if config.ServerRelaxedAuthEnable { dlog.Common.Fatal(user, "Granting permissions via relaxed-auth") return nil, nil } - authorizedKeysFile := fmt.Sprintf("%s/%s/%s.authorized_keys", cwd, config.Common.CacheDir, user.Name) + authorizedKeysFile := fmt.Sprintf("%s/%s/%s.authorized_keys", cwd, + config.Common.CacheDir, user.Name) if _, err := os.Stat(authorizedKeysFile); os.IsNotExist(err) { user, err := osUser.Lookup(user.Name) if err != nil { @@ -44,23 +47,25 @@ func PublicKeyCallback(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey) (*go dlog.Common.Info(user, "Reading", authorizedKeysFile) authorizedKeysBytes, err := ioutil.ReadFile(authorizedKeysFile) if err != nil { - return nil, fmt.Errorf("Unable to read authorized keys file|%s|%s|%s", authorizedKeysFile, user, err.Error()) + return nil, fmt.Errorf("Unable to read authorized keys file|%s|%s|%s", + authorizedKeysFile, user, err.Error()) } authorizedKeysMap := map[string]bool{} for len(authorizedKeysBytes) > 0 { authorizedPubKey, _, _, restBytes, err := gossh.ParseAuthorizedKey(authorizedKeysBytes) if err != nil { - return nil, fmt.Errorf("Unable to parse authorized keys bytes|%s|%s", user, err.Error()) + return nil, fmt.Errorf("Unable to parse authorized keys bytes|%s|%s", + user, err.Error()) } authorizedKeysMap[string(authorizedPubKey.Marshal())] = true authorizedKeysBytes = restBytes - - dlog.Common.Debug(user, "Authorized public key fingerprint", gossh.FingerprintSHA256(authorizedPubKey)) + dlog.Common.Debug(user, "Authorized public key fingerprint", + gossh.FingerprintSHA256(authorizedPubKey)) } - dlog.Common.Debug(user, "Offered public key fingerprint", gossh.FingerprintSHA256(offeredPubKey)) - + dlog.Common.Debug(user, "Offered public key fingerprint", + gossh.FingerprintSHA256(offeredPubKey)) if authorizedKeysMap[string(offeredPubKey.Marshal())] { return &gossh.Permissions{ Extensions: map[string]string{ diff --git a/internal/ssh/ssh.go b/internal/ssh/ssh.go index 56494a7..db5aaf1 100644 --- a/internal/ssh/ssh.go +++ b/internal/ssh/ssh.go @@ -24,12 +24,10 @@ func GeneratePrivateRSAKey(size int) (*rsa.PrivateKey, error) { if err != nil { return nil, err } - err = privateKey.Validate() if err != nil { return nil, err } - return privateKey, nil } @@ -42,7 +40,6 @@ func EncodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte { Headers: nil, Bytes: derFormat, } - return pem.EncodeToMemory(&block) } @@ -80,7 +77,6 @@ func KeyFile(keyFile string) (gossh.AuthMethod, error) { if err != nil { return nil, err } - key, err := gossh.ParsePrivateKey(buffer) if err != nil { return nil, err -- cgit v1.2.3