diff options
Diffstat (limited to 'teleirc/matterbridge/vendor/github.com/shazow/ssh-chat/sshd/auth.go')
| -rw-r--r-- | teleirc/matterbridge/vendor/github.com/shazow/ssh-chat/sshd/auth.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/teleirc/matterbridge/vendor/github.com/shazow/ssh-chat/sshd/auth.go b/teleirc/matterbridge/vendor/github.com/shazow/ssh-chat/sshd/auth.go new file mode 100644 index 0000000..a140413 --- /dev/null +++ b/teleirc/matterbridge/vendor/github.com/shazow/ssh-chat/sshd/auth.go @@ -0,0 +1,74 @@ +package sshd + +import ( + "crypto/sha256" + "encoding/base64" + "errors" + "net" + + "github.com/shazow/ssh-chat/internal/sanitize" + "golang.org/x/crypto/ssh" +) + +// Auth is used to authenticate connections based on public keys. +type Auth interface { + // Whether to allow connections without a public key. + AllowAnonymous() bool + // Given address and public key and client agent string, returns nil if the connection should be allowed. + Check(net.Addr, ssh.PublicKey, string) error +} + +// MakeAuth makes an ssh.ServerConfig which performs authentication against an Auth implementation. +// TODO: Switch to using ssh.AuthMethod instead? +func MakeAuth(auth Auth) *ssh.ServerConfig { + config := ssh.ServerConfig{ + NoClientAuth: false, + // Auth-related things should be constant-time to avoid timing attacks. + PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { + err := auth.Check(conn.RemoteAddr(), key, sanitize.Data(string(conn.ClientVersion()), 64)) + if err != nil { + return nil, err + } + perm := &ssh.Permissions{Extensions: map[string]string{ + "pubkey": string(key.Marshal()), + }} + return perm, nil + }, + KeyboardInteractiveCallback: func(conn ssh.ConnMetadata, challenge ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) { + if !auth.AllowAnonymous() { + return nil, errors.New("public key authentication required") + } + err := auth.Check(conn.RemoteAddr(), nil, sanitize.Data(string(conn.ClientVersion()), 64)) + return nil, err + }, + } + + return &config +} + +// MakeNoAuth makes a simple ssh.ServerConfig which allows all connections. +// Primarily used for testing. +func MakeNoAuth() *ssh.ServerConfig { + config := ssh.ServerConfig{ + NoClientAuth: false, + // Auth-related things should be constant-time to avoid timing attacks. + PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { + perm := &ssh.Permissions{Extensions: map[string]string{ + "pubkey": string(key.Marshal()), + }} + return perm, nil + }, + KeyboardInteractiveCallback: func(conn ssh.ConnMetadata, challenge ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) { + return nil, nil + }, + } + + return &config +} + +// Fingerprint performs a SHA256 BASE64 fingerprint of the PublicKey, similar to OpenSSH. +// See: https://anongit.mindrot.org/openssh.git/commit/?id=56d1c83cdd1ac +func Fingerprint(k ssh.PublicKey) string { + hash := sha256.Sum256(k.Marshal()) + return "SHA256:" + base64.StdEncoding.EncodeToString(hash[:]) +} |
