Skip to content

Commit

Permalink
Refactor code to use libplugin.NewSkelPlugin for plugin/kubernetes/ma…
Browse files Browse the repository at this point in the history
…in.go

Add YAML Plugin skel.go for plugin/yaml
  • Loading branch information
tg123 committed Oct 24, 2024
1 parent 63aefe7 commit da53065
Show file tree
Hide file tree
Showing 6 changed files with 492 additions and 454 deletions.
149 changes: 85 additions & 64 deletions libplugin/skel.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ type SkelPipe interface {
}

type SkelPipeFrom interface {
Match(conn ConnMetadata) (SkelPipeTo, error)
MatchConn(conn ConnMetadata) (SkelPipeTo, error)
}

type SkelPipeFromPassword interface {
SkelPipeFrom

TestPassword(conn ConnMetadata, password []byte) (bool, error)
}

type SkelPipeFromPublicKey interface {
Expand All @@ -62,14 +64,14 @@ type SkelPipeTo interface {

type SkelPipeToPassword interface {
SkelPipeTo

OverridePassword(conn ConnMetadata) ([]byte, error)
}

type SkelPipeToPrivateKey interface {
SkelPipeTo

PrivateKey(conn ConnMetadata) ([]byte, error)

// Certificate() ([]byte, error) TODO support later
PrivateKey(conn ConnMetadata) ([]byte, []byte, error)
}

func (p *SkelPlugin) CreateConfig() *SshPiperPluginConfig {
Expand Down Expand Up @@ -130,7 +132,7 @@ func (p *SkelPlugin) VerifyHostKeyCallback(conn ConnMetadata, hostname, netaddr
return VerifyHostKeyFromKnownHosts(bytes.NewBuffer(data), hostname, netaddr, key)
}

func (p *SkelPlugin) match(conn ConnMetadata, filter SkelPluginAuthMethod) (SkelPipeFrom, SkelPipeTo, error) {
func (p *SkelPlugin) match(conn ConnMetadata, verify func(SkelPipeFrom) (bool, error)) (SkelPipeFrom, SkelPipeTo, error) {
pipes, err := p.listPipe()
if err != nil {
return nil, nil, err
Expand All @@ -139,33 +141,39 @@ func (p *SkelPlugin) match(conn ConnMetadata, filter SkelPluginAuthMethod) (Skel
for _, pipe := range pipes {
for _, from := range pipe.From() {

switch from.(type) {
case SkelPipeFromPublicKey:
if filter&SkelPluginAuthMethodPublicKey == 0 {
continue
}
default:
if filter&SkelPluginAuthMethodPassword == 0 {
continue
}
to, err := from.MatchConn(conn)
if err != nil {
return nil, nil, err
}

to, err := from.Match(conn)
if to == nil {
continue
}

ok, err := verify(from)
if err != nil {
return nil, nil, err
}

if to != nil {
if ok {
return from, to, nil
}
}
}

return nil, nil, fmt.Errorf("no matching pipe for username [%v] found using auth [%v]", conn.User(), filter)
return nil, nil, fmt.Errorf("no matching pipe for username [%v] found", conn.User())
}

func (p *SkelPlugin) PasswordCallback(conn ConnMetadata, password []byte) (*Upstream, error) {
_, to, err := p.match(conn, SkelPluginAuthMethodPassword)
_, to, err := p.match(conn, func(from SkelPipeFrom) (bool, error) {
frompass, ok := from.(SkelPipeFromPassword)

if !ok {
return false, nil
}

return frompass.TestPassword(conn, password)
})
if err != nil {
return nil, err
}
Expand All @@ -175,7 +183,22 @@ func (p *SkelPlugin) PasswordCallback(conn ConnMetadata, password []byte) (*Upst
return nil, err
}

u.Auth = CreatePasswordAuth(password)
toPass, ok := to.(SkelPipeToPassword)
if !ok {
return nil, fmt.Errorf("pipe to does not support password")
}

pass, err := toPass.OverridePassword(conn)
if err != nil {
return nil, err
}

if pass != nil {
u.Auth = CreatePasswordAuth(pass)
} else {
u.Auth = CreatePasswordAuth(password)
}

return u, nil

}
Expand All @@ -201,62 +224,60 @@ func (p *SkelPlugin) PublicKeyCallback(conn ConnMetadata, publicKey []byte) (*Up
}
}

from, to, err := p.match(conn, SkelPluginAuthMethodPublicKey)
if err != nil {
return nil, err
}

fromPubKey, ok := from.(SkelPipeFromPublicKey)
if !ok {
return nil, fmt.Errorf("pipe from does not support public key")
}

// verify public key

verified := false

if isCert {
rest, err := fromPubKey.TrustedUserCAKeys(conn)
if err != nil {
return nil, err
_, to, err := p.match(conn, func(from SkelPipeFrom) (bool, error) {
// verify public key
fromPubKey, ok := from.(SkelPipeFromPublicKey)
if !ok {
return false, nil
}

log.Debugf("trusted user ca keys: %v", rest)
verified := false

var trustedca ssh.PublicKey
for len(rest) > 0 {
trustedca, _, _, rest, err = ssh.ParseAuthorizedKey(rest)
if isCert {
rest, err := fromPubKey.TrustedUserCAKeys(conn)
if err != nil {
return nil, err
return false, err
}

if subtle.ConstantTimeCompare(trustedca.Marshal(), pkcert.SignatureKey.Marshal()) == 1 {
verified = true
break
}
}
} else {
rest, err := fromPubKey.AuthorizedKeys(conn)
if err != nil {
return nil, err
}
log.Debugf("trusted user ca keys: %v", rest)

var trustedca ssh.PublicKey
for len(rest) > 0 {
trustedca, _, _, rest, err = ssh.ParseAuthorizedKey(rest)
if err != nil {
return false, err
}

var authedPubkey ssh.PublicKey
for len(rest) > 0 {
authedPubkey, _, _, rest, err = ssh.ParseAuthorizedKey(rest)
if subtle.ConstantTimeCompare(trustedca.Marshal(), pkcert.SignatureKey.Marshal()) == 1 {
verified = true
break
}
}
} else {
rest, err := fromPubKey.AuthorizedKeys(conn)
if err != nil {
return nil, err
return false, err
}

if subtle.ConstantTimeCompare(authedPubkey.Marshal(), publicKey) == 1 {
verified = true
break
var authedPubkey ssh.PublicKey
for len(rest) > 0 {
authedPubkey, _, _, rest, err = ssh.ParseAuthorizedKey(rest)
if err != nil {
return false, err
}

if subtle.ConstantTimeCompare(authedPubkey.Marshal(), publicKey) == 1 {
verified = true
break
}
}
}
}

if !verified {
return nil, fmt.Errorf("public key verification failed")
return verified, nil
})

if err != nil {
return nil, err
}

u, err := p.createUpstream(conn, to)
Expand All @@ -269,12 +290,12 @@ func (p *SkelPlugin) PublicKeyCallback(conn ConnMetadata, publicKey []byte) (*Up
return nil, fmt.Errorf("pipe to does not support private key")
}

priv, err := toPrivateKey.PrivateKey(conn)
priv, cert, err := toPrivateKey.PrivateKey(conn)
if err != nil {
return nil, err
}

u.Auth = CreatePrivateKeyAuth(priv)
u.Auth = CreatePrivateKeyAuth(priv, cert)

return u, nil
}
Expand Down
Loading

0 comments on commit da53065

Please sign in to comment.