go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/_motor/providers/ssh/defaults.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package ssh
     5  
     6  import (
     7  	"os"
     8  	"os/user"
     9  	"path/filepath"
    10  
    11  	"github.com/mitchellh/go-homedir"
    12  	"github.com/rs/zerolog/log"
    13  	"go.mondoo.com/cnquery/motor/providers"
    14  	"go.mondoo.com/cnquery/motor/vault"
    15  )
    16  
    17  // ApplyDefaults applies all ssh defaults to the transport. It specifically set
    18  // - default port
    19  // - loads ssh keys from known locations
    20  // - configures ssh agent authentication
    21  func ApplyDefaults(cc *providers.Config, username string, identityFile string, password string) error {
    22  	// set default port for ssh
    23  	if cc.Port == 0 {
    24  		cc.Port = 22
    25  	}
    26  
    27  	// fallback to current user if no username was provided
    28  	if username == "" {
    29  		usr, err := user.Current()
    30  		if err != nil {
    31  			log.Warn().Err(err).Msg("could not fallback do current user")
    32  		}
    33  		username = usr.Username
    34  	}
    35  
    36  	// handle credentials cases:
    37  	// if identity file is provided but no password -> private key
    38  	// if identity file is provided with password -> encrypted private key
    39  	// if no identity file is provided but a password -> password
    40  	if identityFile != "" {
    41  		credential, err := vault.NewPrivateKeyCredentialFromPath(username, identityFile, password)
    42  		if err != nil {
    43  			return err
    44  		}
    45  		cc.AddCredential(credential)
    46  	} else if password != "" {
    47  		credential := vault.NewPasswordCredential(username, password)
    48  		cc.AddCredential(credential)
    49  	}
    50  
    51  	// add default identities
    52  	ApplyDefaultIdentities(cc, username, password)
    53  
    54  	return nil
    55  }
    56  
    57  // ApplyDefaultIdentities loads user's ssh identifies from ~/.ssh/
    58  func ApplyDefaultIdentities(cc *providers.Config, username string, password string) *providers.Config {
    59  	// ssh config overwrite like: IdentityFile ~/.foo/identity is done in ReadSSHConfig()
    60  	// fallback to default paths 	~/.ssh/id_rsa and ~/.ssh/id_dsa if they exist
    61  	home, err := homedir.Dir()
    62  	if err == nil {
    63  		files := []string{
    64  			filepath.Join(home, ".ssh", "id_rsa"),
    65  			filepath.Join(home, ".ssh", "id_dsa"),
    66  			filepath.Join(home, ".ssh", "id_ed25519"),
    67  			filepath.Join(home, ".ssh", "id_ecdsa"),
    68  			// specific handling for google compute engine, see https://cloud.google.com/compute/docs/instances/connecting-to-instance
    69  			filepath.Join(home, ".ssh", "google_compute_engine"),
    70  		}
    71  
    72  		// filter keys by existence
    73  		for i := range files {
    74  			f := files[i]
    75  			_, err := os.Stat(f)
    76  			if err == nil {
    77  				log.Debug().Str("key", f).Msg("load ssh identity")
    78  				credential, err := vault.NewPrivateKeyCredentialFromPath(username, f, password)
    79  				if err != nil {
    80  					log.Warn().Err(err).Str("key", f).Msg("could not load ssh identity")
    81  				} else {
    82  					cc.AddCredential(credential)
    83  				}
    84  			}
    85  		}
    86  	}
    87  
    88  	// enable ssh-agent authentication as default
    89  	cc.AddCredential(&vault.Credential{Type: vault.CredentialType_ssh_agent, User: username})
    90  
    91  	return cc
    92  }