This commit is contained in:
mik2k2 2021-07-06 12:57:51 +02:00
parent efab623a6a
commit 253302a057
3 changed files with 26 additions and 26 deletions

12
auth.go
View File

@ -1,16 +1,16 @@
package sshchat package sshchat
import ( import (
"bufio"
"crypto/sha256" "crypto/sha256"
"crypto/subtle" "crypto/subtle"
"encoding/csv" "encoding/csv"
"errors" "errors"
"fmt" "fmt"
"net" "net"
"os"
"strings" "strings"
"time" "time"
"os"
"bufio"
"github.com/shazow/ssh-chat/set" "github.com/shazow/ssh-chat/set"
"github.com/shazow/ssh-chat/sshd" "github.com/shazow/ssh-chat/sshd"
@ -59,8 +59,8 @@ type Auth struct {
banned *set.Set banned *set.Set
whitelist *set.Set whitelist *set.Set
ops *set.Set ops *set.Set
opFile string opFile string
whitelistFile string whitelistFile string
} }
// NewAuth creates a new empty Auth. // NewAuth creates a new empty Auth.
@ -169,7 +169,7 @@ func (a *Auth) IsOp(key ssh.PublicKey) bool {
// LoadOpsFromFile reads a file in authorized_keys format and makes public keys operators // LoadOpsFromFile reads a file in authorized_keys format and makes public keys operators
func (a *Auth) LoadOpsFromFile(path string) error { func (a *Auth) LoadOpsFromFile(path string) error {
a.opFile = path a.opFile = path
return fromFile(path, func(key ssh.PublicKey){a.Op(key, 0)}) return fromFile(path, func(key ssh.PublicKey) { a.Op(key, 0) })
} }
// Whitelist will set a public key as a whitelisted user. // Whitelist will set a public key as a whitelisted user.
@ -194,7 +194,7 @@ func (a *Auth) Whitelist(key ssh.PublicKey, d time.Duration) {
// LoadWhitelistFromFile reads a file in authorized_keys format and whitelists public keys // LoadWhitelistFromFile reads a file in authorized_keys format and whitelists public keys
func (a *Auth) LoadWhitelistFromFile(path string) error { func (a *Auth) LoadWhitelistFromFile(path string) error {
a.whitelistFile = path a.whitelistFile = path
return fromFile(path, func(key ssh.PublicKey){a.Whitelist(key, 0)}) return fromFile(path, func(key ssh.PublicKey) { a.Whitelist(key, 0) })
} }
// Ban will set a public key as banned. // Ban will set a public key as banned.

30
host.go
View File

@ -13,10 +13,10 @@ import (
"github.com/shazow/rateio" "github.com/shazow/rateio"
"github.com/shazow/ssh-chat/chat" "github.com/shazow/ssh-chat/chat"
"github.com/shazow/ssh-chat/set"
"github.com/shazow/ssh-chat/chat/message" "github.com/shazow/ssh-chat/chat/message"
"github.com/shazow/ssh-chat/internal/humantime" "github.com/shazow/ssh-chat/internal/humantime"
"github.com/shazow/ssh-chat/internal/sanitize" "github.com/shazow/ssh-chat/internal/sanitize"
"github.com/shazow/ssh-chat/set"
"github.com/shazow/ssh-chat/sshd" "github.com/shazow/ssh-chat/sshd"
) )
@ -711,12 +711,12 @@ func (h *Host) InitCommands(c *chat.Commands) {
// TODO: "panic" (?) command for (import + on + reverify)? // TODO: "panic" (?) command for (import + on + reverify)?
// TODO: "print" command with a format for saving to the whitelist file? // TODO: "print" command with a format for saving to the whitelist file?
// -> hard because the whitelist set only saves fingerprints // -> hard because the whitelist set only saves fingerprints
Op: true, Op: true,
Prefix: "/whitelist", Prefix: "/whitelist",
PrefixHelp: "COMMAND [ARGS...]", PrefixHelp: "COMMAND [ARGS...]",
Help: "Manipulate the whitelist or whitelist state. See /whitelist help for subcommands", Help: "Manipulate the whitelist or whitelist state. See /whitelist help for subcommands",
Handler: func(room *chat.Room, msg message.CommandMsg) error { Handler: func(room *chat.Room, msg message.CommandMsg) error {
if !room.IsOp(msg.From()){ if !room.IsOp(msg.From()) {
return errors.New("must be op") return errors.New("must be op")
} }
@ -727,14 +727,14 @@ func (h *Host) InitCommands(c *chat.Commands) {
// send exactly one message to preserve order // send exactly one message to preserve order
replyLines := []string{} replyLines := []string{}
sendMsg := func(content string, formatting ...interface{}){ sendMsg := func(content string, formatting ...interface{}) {
replyLines = append(replyLines, fmt.Sprintf(content, formatting...)) replyLines = append(replyLines, fmt.Sprintf(content, formatting...))
} }
forConnectedUsers := func(cmd func(*chat.Member, ssh.PublicKey) error)error{ forConnectedUsers := func(cmd func(*chat.Member, ssh.PublicKey) error) error {
return h.Members.Each(func(key string, item set.Item) error{ return h.Members.Each(func(key string, item set.Item) error {
v := item.Value() v := item.Value()
if v == nil { // expired between Each and here if v == nil { // expired between Each and here
return nil return nil
} }
user := v.(*chat.Member) user := v.(*chat.Member)
@ -748,14 +748,14 @@ func (h *Host) InitCommands(c *chat.Commands) {
invalidKeys := []string{} invalidKeys := []string{}
noKeyUsers := []string{} noKeyUsers := []string{}
var keyType string var keyType string
for _, v := range args[1:]{ for _, v := range args[1:] {
switch { switch {
case keyType != "": case keyType != "":
pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keyType + " " + v)) pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keyType + " " + v))
if err == nil { if err == nil {
cmd(pk) cmd(pk)
} else { } else {
invalidKeys = append(invalidKeys, keyType + " " + v) invalidKeys = append(invalidKeys, keyType+" "+v)
} }
keyType = "" keyType = ""
case strings.HasPrefix(v, "ssh-"): case strings.HasPrefix(v, "ssh-"):
@ -800,9 +800,9 @@ func (h *Host) InitCommands(c *chat.Commands) {
case "off": case "off":
h.auth.WhitelistMode = false h.auth.WhitelistMode = false
case "add": case "add":
forPubkeyUser(func(pk ssh.PublicKey){h.auth.Whitelist(pk, 0)}) forPubkeyUser(func(pk ssh.PublicKey) { h.auth.Whitelist(pk, 0) })
case "remove": case "remove":
forPubkeyUser(func(pk ssh.PublicKey){h.auth.Whitelist(pk, 1)}) forPubkeyUser(func(pk ssh.PublicKey) { h.auth.Whitelist(pk, 1) })
case "import": case "import":
var since time.Duration var since time.Duration
var err error var err error
@ -843,7 +843,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
sendMsg("whitelist is disabled, so nobody will be kicked") sendMsg("whitelist is disabled, so nobody will be kicked")
break break
} }
forConnectedUsers(func(user *chat.Member, pk ssh.PublicKey)error{ forConnectedUsers(func(user *chat.Member, pk ssh.PublicKey) error {
if !h.auth.IsOp(pk) && h.auth.CheckPublicKey(pk) != nil { // TODO: why doesn't CheckPublicKey do this? if !h.auth.IsOp(pk) && h.auth.CheckPublicKey(pk) != nil { // TODO: why doesn't CheckPublicKey do this?
user.Close() // TODO: some message anywhere? user.Close() // TODO: some message anywhere?
} }
@ -860,7 +860,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
// TODO: this can probably be optimized // TODO: this can probably be optimized
h.auth.whitelist.Each(func(key string, item set.Item) error { h.auth.whitelist.Each(func(key string, item set.Item) error {
keyFP := item.Key() keyFP := item.Key()
if forConnectedUsers(func (user *chat.Member, pk ssh.PublicKey) error { if forConnectedUsers(func(user *chat.Member, pk ssh.PublicKey) error {
if pk != nil && sshd.Fingerprint(pk) == keyFP { if pk != nil && sshd.Fingerprint(pk) == keyFP {
whitelistedUsers = append(whitelistedUsers, user.Name()) whitelistedUsers = append(whitelistedUsers, user.Name())
return errors.New("not an actual error, but exit early because we found the key") return errors.New("not an actual error, but exit early because we found the key")

View File

@ -49,7 +49,7 @@ func TestStripPrompt(t *testing.T) {
}, },
{ {
Input: "[foo] \x1b[6D\x1b[K-> From your friendly system.\r", Input: "[foo] \x1b[6D\x1b[K-> From your friendly system.\r",
Want: "From your friendly system.\r", Want: "From your friendly system.\r",
}, },
} }
@ -201,12 +201,12 @@ func TestHostWhitelistCommand(t *testing.T) {
go host.Serve() go host.Serve()
users := make(chan *message.User) users := make(chan *message.User)
host.OnUserJoined = func(u *message.User){ host.OnUserJoined = func(u *message.User) {
users <- u users <- u
} }
sshd.ConnectShell(s.Addr().String(), "foo", func(r io.Reader, w io.WriteCloser) error { sshd.ConnectShell(s.Addr().String(), "foo", func(r io.Reader, w io.WriteCloser) error {
<- users <-users
m, ok := host.MemberByID("foo") m, ok := host.MemberByID("foo")
if !ok { if !ok {
t.Fatal("can't get member foo") t.Fatal("can't get member foo")
@ -216,7 +216,7 @@ func TestHostWhitelistCommand(t *testing.T) {
scanner.Scan() // Joined scanner.Scan() // Joined
// <- messages // <- messages
assertLineEq := func(expected string){ assertLineEq := func(expected string) {
if !scanner.Scan() { if !scanner.Scan() {
t.Error("no line available") t.Error("no line available")
} }
@ -224,7 +224,7 @@ func TestHostWhitelistCommand(t *testing.T) {
t.Errorf("expected %q, got %q", expected, actual) t.Errorf("expected %q, got %q", expected, actual)
} }
} }
sendCmd := func(cmd string, formatting ...interface{}){ sendCmd := func(cmd string, formatting ...interface{}) {
host.HandleMsg(message.ParseInput(fmt.Sprintf(cmd, formatting...), m.User)) host.HandleMsg(message.ParseInput(fmt.Sprintf(cmd, formatting...), m.User))
} }