68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package api
|
|
|
|
import (
|
|
"errors"
|
|
"golang.org/x/crypto/ssh"
|
|
"linkport/internal/model"
|
|
"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 !model.IsSSH(p.Type) {
|
|
return nil
|
|
}
|
|
keys := append([]string(nil), p.SSH.AuthorizedKeys...)
|
|
for _, account := range p.GatewayAccounts {
|
|
keys = append(keys, account.AuthorizedKeys...)
|
|
}
|
|
for _, key := range keys {
|
|
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")
|
|
}
|
|
if _, err = model.SSHCertificateSigner(p.SSH.Certificate, signer); err != nil {
|
|
return errors.New("SSH certificate does not match the private key")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateGateway(p *model.Proxy) error {
|
|
if p.TargetID == "" || p.TargetAccountID == "" {
|
|
return p.ValidateGateway()
|
|
}
|
|
return p.Validate()
|
|
}
|
|
|
|
func supportedKey(k ssh.PublicKey) bool {
|
|
return k != nil && (k.Type() == ssh.KeyAlgoED25519 || k.Type() == ssh.KeyAlgoRSA)
|
|
}
|