85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
package ssh2
|
|
|
|
import (
|
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/ssh2/sshkeys"
|
|
"github.com/gliderlabs/ssh"
|
|
)
|
|
|
|
func (ssh2 *SSH2) setupAuth(server *ssh.Server) {
|
|
server.PublicKeyHandler = ssh2.handleAuth
|
|
}
|
|
|
|
// ssh2Key is a type of context keys for this package
|
|
type ssh2Key int
|
|
|
|
const (
|
|
// permissions represents the permissions for the given session
|
|
permission ssh2Key = iota
|
|
)
|
|
|
|
func setPermissions(context ssh.Context, permissions map[string]bool) {
|
|
context.SetValue(permission, permissions)
|
|
}
|
|
|
|
// hasPermission checks if the given context permits access to the given slug.
|
|
// The empty slug checks for global access.
|
|
func hasPermission(context ssh.Context, slug string) bool {
|
|
value, ok := context.Value(permission).(map[string]bool)
|
|
return ok && value[slug]
|
|
}
|
|
|
|
// getAnyPermission gets some instance the user has access to.
|
|
// If the user does not have access to anything, returns "", false.
|
|
// If the user has superuser access, but there are no instances, returns "", true.
|
|
func getAnyPermission(context ssh.Context) (string, bool) {
|
|
value, ok := context.Value(permission).(map[string]bool)
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
|
|
for slug, ok := range value {
|
|
if ok && slug != "" {
|
|
return slug, true
|
|
}
|
|
}
|
|
|
|
return "", (false || value[""])
|
|
}
|
|
|
|
func (ssh2 *SSH2) handleAuth(ctx ssh.Context, key ssh.PublicKey) bool {
|
|
return sshkeys.Slowdown(func() (ok bool) {
|
|
permissions := make(map[string]bool)
|
|
|
|
// grab the global permissions
|
|
{
|
|
globalKeys, err := ssh2.Dependencies.Keys.Admin(ctx)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
permissions[""] = sshkeys.KeyOneOf(globalKeys, key)
|
|
ok = permissions[""]
|
|
}
|
|
|
|
// grab permissions for each instance
|
|
{
|
|
instances, err := ssh2.Dependencies.Instances.All(ctx)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
for _, instance := range instances {
|
|
ikeys, err := instance.SSH().Keys(ctx)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
access := sshkeys.KeyOneOf(ikeys, key)
|
|
|
|
permissions[instance.Slug] = access || permissions[""]
|
|
ok = ok || access
|
|
}
|
|
}
|
|
|
|
setPermissions(ctx, permissions)
|
|
return
|
|
})
|
|
}
|