package sshtun import ( "errors" "fmt" "os" "path" "strings" "github.com/Neur0toxine/sshpoke/pkg/proto/ssh" "github.com/Neur0toxine/sshpoke/pkg/smarttypes" ) func AuthKeyFile(keyFile smarttypes.Path) (ssh.AuthMethod, error) { key, err := readKey(keyFile) if err != nil { return nil, err } return ssh.PublicKeys(key), nil } func AuthKeyDir(keyDir smarttypes.Path) (ssh.AuthMethod, error) { keys, err := readKeys(keyDir) if err != nil { return nil, err } return ssh.PublicKeys(keys...), nil } func AuthPassword(password string) ssh.AuthMethod { return ssh.Password(password) } func readKeys(keyDir smarttypes.Path) ([]ssh.Signer, error) { dir, err := keyDir.Directory() if err != nil { return nil, fmt.Errorf("cannot parse keys: %s", err) } entries, err := os.ReadDir(dir) if err != nil { return nil, fmt.Errorf("cannot read key directory: %s", err) } keys := []ssh.Signer{} for _, entry := range entries { if entry.IsDir() { continue } info, err := entry.Info() if err != nil { continue } if strings.HasSuffix(entry.Name(), ".pub") { continue } if entry.Name() == "config" { continue } if entry.Name() == "known_hosts" { continue } // this file is too small to be a private key if info.Size() < 256 { continue } key, err := readKey(smarttypes.Path(path.Join(dir, entry.Name()))) if err != nil { continue } keys = append(keys, key) } if len(keys) == 0 { return nil, errors.New("no keys in the provided directory") } return keys, nil } func readKey(keyFile smarttypes.Path) (ssh.Signer, error) { fileName, err := keyFile.File() if err != nil { return nil, err } keyData, err := os.ReadFile(fileName) if err != nil { return nil, err } key, err := ssh.ParsePrivateKey(keyData) if err != nil { return nil, err } return key, nil }