54 lines
1.4 KiB
Go
54 lines
1.4 KiB
Go
package api
|
|
|
|
import (
|
|
"agentdb/internal/model"
|
|
"errors"
|
|
"golang.org/x/crypto/ssh"
|
|
"strings"
|
|
)
|
|
|
|
func editable(p map[string]any) error {
|
|
for _, k := range []string{"id", "enabled"} {
|
|
if _, ok := p[k]; ok {
|
|
return errors.New(k + " is server managed")
|
|
}
|
|
}
|
|
if v, ok := p["ssh"].(map[string]any); ok {
|
|
for _, k := range []string{"hostKey", "targetHostKey"} {
|
|
if _, ok := v[k]; ok {
|
|
return errors.New("SSH host keys must use the confirmation flow")
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateKeys(p model.Proxy) error {
|
|
if p.Type != "ssh" {
|
|
return nil
|
|
}
|
|
for _, key := range p.SSH.AuthorizedKeys {
|
|
pub, _, opts, rest, e := ssh.ParseAuthorizedKey([]byte(key))
|
|
if e != nil || len(opts) > 0 || len(strings.TrimSpace(string(rest))) > 0 || !supportedKey(pub) {
|
|
return errors.New("each authorized key must be a single valid SSH public key")
|
|
}
|
|
}
|
|
if p.SSH.AuthMethod == "privatekey" {
|
|
var signer ssh.Signer
|
|
var err error
|
|
if p.SSH.Passphrase != "" {
|
|
signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(p.SSH.PrivateKey), []byte(p.SSH.Passphrase))
|
|
} else {
|
|
signer, err = ssh.ParsePrivateKey([]byte(p.SSH.PrivateKey))
|
|
}
|
|
if err != nil || !supportedKey(signer.PublicKey()) {
|
|
return errors.New("invalid or unsupported SSH private key or passphrase")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func supportedKey(k ssh.PublicKey) bool {
|
|
return k != nil && (k.Type() == ssh.KeyAlgoED25519 || k.Type() == ssh.KeyAlgoRSA)
|
|
}
|