sshpoke/internal/server/driver/ssh/sshtun/auth.go

92 lines
1.8 KiB
Go

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
}