mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-06-13 05:42:07 +03:00
move loading whitelist+ops from file to auth and save the loaded files fro reloading
This commit is contained in:
parent
7413539965
commit
1a533b023d
59
auth.go
59
auth.go
@ -9,6 +9,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"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"
|
||||||
@ -51,11 +53,14 @@ func newAuthAddr(addr net.Addr) string {
|
|||||||
// If the contained passphrase is not empty, it complements a whitelist.
|
// If the contained passphrase is not empty, it complements a whitelist.
|
||||||
type Auth struct {
|
type Auth struct {
|
||||||
passphraseHash []byte
|
passphraseHash []byte
|
||||||
|
WhitelistMode bool
|
||||||
bannedAddr *set.Set
|
bannedAddr *set.Set
|
||||||
bannedClient *set.Set
|
bannedClient *set.Set
|
||||||
banned *set.Set
|
banned *set.Set
|
||||||
whitelist *set.Set
|
whitelist *set.Set
|
||||||
ops *set.Set
|
ops *set.Set
|
||||||
|
opFile string
|
||||||
|
whitelistFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAuth creates a new empty Auth.
|
// NewAuth creates a new empty Auth.
|
||||||
@ -82,7 +87,7 @@ func (a *Auth) SetPassphrase(passphrase string) {
|
|||||||
|
|
||||||
// AllowAnonymous determines if anonymous users are permitted.
|
// AllowAnonymous determines if anonymous users are permitted.
|
||||||
func (a *Auth) AllowAnonymous() bool {
|
func (a *Auth) AllowAnonymous() bool {
|
||||||
return a.whitelist.Len() == 0 && a.passphraseHash == nil
|
return !a.WhitelistMode && a.passphraseHash == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptPassphrase determines if passphrase authentication is accepted.
|
// AcceptPassphrase determines if passphrase authentication is accepted.
|
||||||
@ -158,18 +163,38 @@ func (a *Auth) IsOp(key ssh.PublicKey) bool {
|
|||||||
return a.ops.In(authkey)
|
return a.ops.In(authkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: the *FromFile could be replaced by a single LoadFromFile taking the function (i.e. auth.Op/auth.Whitelist)
|
||||||
|
// TODO: consider reloading on empty path
|
||||||
|
|
||||||
|
// LoadOpsFromFile reads a file in authorized_keys format and makes public keys operators
|
||||||
|
func (a *Auth) LoadOpsFromFile(path string) error {
|
||||||
|
a.opFile = path
|
||||||
|
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.
|
||||||
func (a *Auth) Whitelist(key ssh.PublicKey, d time.Duration) {
|
func (a *Auth) Whitelist(key ssh.PublicKey, d time.Duration) {
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
authItem := newAuthItem(key)
|
authItem := newAuthItem(key)
|
||||||
if d != 0 {
|
if d != 0 {
|
||||||
a.whitelist.Set(set.Expire(authItem, d))
|
err = a.whitelist.Set(set.Expire(authItem, d))
|
||||||
} else {
|
} else {
|
||||||
a.whitelist.Set(authItem)
|
err = a.whitelist.Set(authItem)
|
||||||
}
|
}
|
||||||
logger.Debugf("Added to whitelist: %q (for %s)", authItem.Key(), d)
|
if err == nil {
|
||||||
|
logger.Debugf("Added to whitelist: %q (for %s)", authItem.Key(), d)
|
||||||
|
} else {
|
||||||
|
logger.Errorf("Error adding %q to whitelist for %s: %s", authItem.Key(), d, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadWhitelistFromFile reads a file in authorized_keys format and whitelists public keys
|
||||||
|
func (a *Auth) LoadWhitelistFromFile(path string) error {
|
||||||
|
a.whitelistFile = path
|
||||||
|
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.
|
||||||
@ -276,3 +301,29 @@ func (a *Auth) BanQuery(q string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fromFile(path string, handler func(ssh.PublicKey)) error {
|
||||||
|
if path == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
key, _, _, _, err := ssh.ParseAuthorizedKey(scanner.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
if err.Error() == "ssh: no key found" {
|
||||||
|
// TODO: do we really want to always ignore this?
|
||||||
|
continue // Skip line
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
handler(key)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -13,7 +12,6 @@ import (
|
|||||||
"github.com/alexcesaro/log"
|
"github.com/alexcesaro/log"
|
||||||
"github.com/alexcesaro/log/golog"
|
"github.com/alexcesaro/log/golog"
|
||||||
flags "github.com/jessevdk/go-flags"
|
flags "github.com/jessevdk/go-flags"
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
|
|
||||||
sshchat "github.com/shazow/ssh-chat"
|
sshchat "github.com/shazow/ssh-chat"
|
||||||
"github.com/shazow/ssh-chat/chat"
|
"github.com/shazow/ssh-chat/chat"
|
||||||
@ -138,35 +136,16 @@ func main() {
|
|||||||
auth.SetPassphrase(options.Passphrase)
|
auth.SetPassphrase(options.Passphrase)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fromFile(options.Admin, func(line []byte) error {
|
err = auth.LoadOpsFromFile(options.Admin)
|
||||||
key, _, _, _, err := ssh.ParseAuthorizedKey(line)
|
|
||||||
if err != nil {
|
|
||||||
if err.Error() == "ssh: no key found" {
|
|
||||||
return nil // Skip line
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
auth.Op(key, 0)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(5, "Failed to load admins: %v\n", err)
|
fail(5, "Failed to load admins: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fromFile(options.Whitelist, func(line []byte) error {
|
err = auth.LoadWhitelistFromFile(options.Whitelist)
|
||||||
key, _, _, _, err := ssh.ParseAuthorizedKey(line)
|
|
||||||
if err != nil {
|
|
||||||
if err.Error() == "ssh: no key found" {
|
|
||||||
return nil // Skip line
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
auth.Whitelist(key, 0)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(6, "Failed to load whitelist: %v\n", err)
|
fail(6, "Failed to load whitelist: %v\n", err)
|
||||||
}
|
}
|
||||||
|
auth.WhitelistMode = options.Whitelist != ""
|
||||||
|
|
||||||
if options.Motd != "" {
|
if options.Motd != "" {
|
||||||
host.GetMOTD = func() (string, error) {
|
host.GetMOTD = func() (string, error) {
|
||||||
@ -206,25 +185,3 @@ func main() {
|
|||||||
<-sig // Wait for ^C signal
|
<-sig // Wait for ^C signal
|
||||||
fmt.Fprintln(os.Stderr, "Interrupt signal detected, shutting down.")
|
fmt.Fprintln(os.Stderr, "Interrupt signal detected, shutting down.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromFile(path string, handler func(line []byte) error) error {
|
|
||||||
if path == "" {
|
|
||||||
// Skip
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
for scanner.Scan() {
|
|
||||||
err := handler(scanner.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user