From 4fe03fb233d2f7de24a0031437d993ddc7d67928 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Wed, 25 Mar 2020 19:38:32 +0000 Subject: Add a configuration parameter making it possible to avoid listening to the web port --- cmd/grumble/server.go | 104 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index 8dc0f21..ac6963b 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -1355,6 +1355,12 @@ func (server *Server) Port() int { return port } +// ListenWebPort returns true if we should listen to the +// web port, otherwise false +func (server *Server) ListenWebPort() bool { + return !server.cfg.BoolValue("NoWebServer") +} + // WebPort returns the port the web server will listen on when it is // started. func (server *Server) WebPort() int { @@ -1396,6 +1402,7 @@ func (server *Server) Start() (err error) { host := server.HostAddress() port := server.Port() webport := server.WebPort() + shouldListenWeb := server.ListenWebPort() // Setup our UDP listener server.udpconn, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP(host), Port: port}) @@ -1434,37 +1441,42 @@ func (server *Server) Start() (err error) { } server.tlsl = tls.NewListener(server.tcpl, server.tlscfg) - // Create HTTP server and WebSocket "listener" - webaddr := &net.TCPAddr{IP: net.ParseIP(host), Port: webport} - server.webtlscfg = &tls.Config{ - Certificates: []tls.Certificate{cert}, - ClientAuth: tls.NoClientCert, - NextProtos: []string{"http/1.1"}, - } - server.webwsl = web.NewListener(webaddr, server.Logger) - mux := http.NewServeMux() - mux.Handle("/", server.webwsl) - server.webhttp = &http.Server{ - Addr: webaddr.String(), - Handler: mux, - TLSConfig: server.webtlscfg, - ErrorLog: server.Logger, - - // Set sensible timeouts, in case no reverse proxy is in front of Grumble. - // Non-conforming (or malicious) clients may otherwise block indefinitely and cause - // file descriptors (or handles, depending on your OS) to leak and/or be exhausted - ReadTimeout: 5 * time.Second, - WriteTimeout: 10 * time.Second, - IdleTimeout: 2 * time.Minute, + if shouldListenWeb { + // Create HTTP server and WebSocket "listener" + webaddr := &net.TCPAddr{IP: net.ParseIP(host), Port: webport} + server.webtlscfg = &tls.Config{ + Certificates: []tls.Certificate{cert}, + ClientAuth: tls.NoClientCert, + NextProtos: []string{"http/1.1"}, + } + server.webwsl = web.NewListener(webaddr, server.Logger) + mux := http.NewServeMux() + mux.Handle("/", server.webwsl) + server.webhttp = &http.Server{ + Addr: webaddr.String(), + Handler: mux, + TLSConfig: server.webtlscfg, + ErrorLog: server.Logger, + + // Set sensible timeouts, in case no reverse proxy is in front of Grumble. + // Non-conforming (or malicious) clients may otherwise block indefinitely and cause + // file descriptors (or handles, depending on your OS) to leak and/or be exhausted + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 2 * time.Minute, + } + go func() { + err := server.webhttp.ListenAndServeTLS("", "") + if err != http.ErrServerClosed { + server.Fatalf("Fatal HTTP server error: %v", err) + } + }() + + server.Printf("Started: listening on %v and %v", server.tcpl.Addr(), server.webwsl.Addr()) + } else { + server.Printf("Started: listening on %v", server.tcpl.Addr()) } - go func() { - err := server.webhttp.ListenAndServeTLS("", "") - if err != http.ErrServerClosed { - server.Fatalf("Fatal HTTP server error: %v", err) - } - }() - server.Printf("Started: listening on %v and %v", server.tcpl.Addr(), server.webwsl.Addr()) server.running = true // Open a fresh freezer log @@ -1487,10 +1499,17 @@ func (server *Server) Start() (err error) { // for the servers. Each network goroutine defers a call to // netwg.Done(). In the Stop() we close all the connections // and call netwg.Wait() to wait for the goroutines to end. - server.netwg.Add(3) + numWG := 2 + if shouldListenWeb { + numWG++ + } + + server.netwg.Add(numWG) go server.udpListenLoop() go server.acceptLoop(server.tlsl) - go server.acceptLoop(server.webwsl) + if shouldListenWeb { + go server.acceptLoop(server.webwsl) + } // Schedule a server registration update (if needed) go func() { @@ -1520,12 +1539,19 @@ func (server *Server) Stop() (err error) { // This does not apply to opened WebSockets, which were forcibly closed when // all clients were disconnected. ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second)) - err = server.webhttp.Shutdown(ctx) - cancel() - if err == context.DeadlineExceeded { - server.Println("Forcibly shutdown HTTP server while stopping") - } else if err != nil { - return err + if server.ListenWebPort() { + err = server.webhttp.Shutdown(ctx) + cancel() + if err == context.DeadlineExceeded { + server.Println("Forcibly shutdown HTTP server while stopping") + } else if err != nil { + return err + } + + err = server.webwsl.Close() + if err != nil { + return err + } } // Close the listeners @@ -1533,10 +1559,6 @@ func (server *Server) Stop() (err error) { if err != nil { return err } - err = server.webwsl.Close() - if err != nil { - return err - } // Close the UDP connection err = server.udpconn.Close() -- cgit v1.2.3 From 58f77685e7334cd682b797292ba62016054e5ed2 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Wed, 25 Mar 2020 19:49:19 +0000 Subject: Make it possible to change configuration parameters on a server --- cmd/grumble/server.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index 8dc0f21..dccda0f 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -1562,3 +1562,8 @@ func (server *Server) Stop() (err error) { return nil } + +// Set will set a configuration value +func (server *Server) Set(key string, value string) { + server.cfg.Set(key, value) +} -- cgit v1.2.3 From 8d351aedb06a96bc27093b2d75cc91788bebb067 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 14:00:01 +0000 Subject: Extract a LogTarget interface to make it easier to manage logging --- cmd/grumble/grumble.go | 2 +- cmd/grumble/server.go | 2 +- pkg/logtarget/logtarget.go | 20 ++++++++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cmd/grumble/grumble.go b/cmd/grumble/grumble.go index 56eaa9a..c47e2de 100644 --- a/cmd/grumble/grumble.go +++ b/cmd/grumble/grumble.go @@ -44,7 +44,7 @@ func main() { } log.SetPrefix("[G] ") log.SetFlags(log.LstdFlags | log.Lmicroseconds) - log.SetOutput(&logtarget.Target) + log.SetOutput(logtarget.Target) log.Printf("Grumble") log.Printf("Using data directory: %s", Args.DataDir) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index 64b4dd8..7877830 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -156,7 +156,7 @@ func NewServer(id int64) (s *Server, err error) { s.Channels[0] = NewChannel(0, "Root") s.nextChanId = 1 - s.Logger = log.New(&logtarget.Target, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) + s.Logger = log.New(logtarget.Target, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) return } diff --git a/pkg/logtarget/logtarget.go b/pkg/logtarget/logtarget.go index 46a2eb2..144654c 100644 --- a/pkg/logtarget/logtarget.go +++ b/pkg/logtarget/logtarget.go @@ -7,15 +7,23 @@ package logtarget import ( "bytes" + "io" "os" "sync" ) +type LogTarget interface { + io.Writer + + OpenFile(string) error + Rotate() error +} + // LogTarget implements the io.Writer interface, allowing // LogTarget to be registered with the regular Go log package. // LogTarget multiplexes its incoming writes to multiple optional // output writers, and one main output writer (the log file). -type LogTarget struct { +type FileLogTarget struct { mu sync.Mutex logfn string file *os.File @@ -24,8 +32,12 @@ type LogTarget struct { var Target LogTarget +func init() { + Target = &FileLogTarget{} +} + // Write writes a log message to all registered io.Writers -func (target *LogTarget) Write(in []byte) (int, error) { +func (target *FileLogTarget) Write(in []byte) (int, error) { target.mu.Lock() defer target.mu.Unlock() @@ -48,7 +60,7 @@ func (target *LogTarget) Write(in []byte) (int, error) { // OpenFile opens the main log file for writing. // This method will open the file in append-only mode. -func (target *LogTarget) OpenFile(fn string) (err error) { +func (target *FileLogTarget) OpenFile(fn string) (err error) { target.logfn = fn target.file, err = os.OpenFile(target.logfn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) if err != nil { @@ -61,7 +73,7 @@ func (target *LogTarget) OpenFile(fn string) (err error) { // This method holds a lock while rotating the log file, // and all log writes will be held back until the rotation // is complete. -func (target *LogTarget) Rotate() error { +func (target *FileLogTarget) Rotate() error { target.mu.Lock() defer target.mu.Unlock() -- cgit v1.2.3 From dd6f383d3e57dd3fcd589e289a23ec5d3b292d5f Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 14:04:14 +0000 Subject: Rename the default logtarget to not stutter. Also hide the default file log target implementation --- cmd/grumble/grumble.go | 4 ++-- cmd/grumble/server.go | 2 +- cmd/grumble/signal_unix.go | 2 +- pkg/logtarget/logtarget.go | 20 ++++++++++---------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cmd/grumble/grumble.go b/cmd/grumble/grumble.go index c47e2de..6d2c93a 100644 --- a/cmd/grumble/grumble.go +++ b/cmd/grumble/grumble.go @@ -37,14 +37,14 @@ func main() { dataDir.Close() // Set up logging - err = logtarget.Target.OpenFile(Args.LogPath) + err = logtarget.Default.OpenFile(Args.LogPath) if err != nil { fmt.Fprintf(os.Stderr, "Unable to open log file (%v): %v", Args.LogPath, err) return } log.SetPrefix("[G] ") log.SetFlags(log.LstdFlags | log.Lmicroseconds) - log.SetOutput(logtarget.Target) + log.SetOutput(logtarget.Default) log.Printf("Grumble") log.Printf("Using data directory: %s", Args.DataDir) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index 7877830..4f2bb4d 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -156,7 +156,7 @@ func NewServer(id int64) (s *Server, err error) { s.Channels[0] = NewChannel(0, "Root") s.nextChanId = 1 - s.Logger = log.New(logtarget.Target, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) + s.Logger = log.New(logtarget.Default, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) return } diff --git a/cmd/grumble/signal_unix.go b/cmd/grumble/signal_unix.go index 7127f24..9066b49 100644 --- a/cmd/grumble/signal_unix.go +++ b/cmd/grumble/signal_unix.go @@ -20,7 +20,7 @@ func SignalHandler() { signal.Notify(sigchan, syscall.SIGUSR2, syscall.SIGTERM, syscall.SIGINT) for sig := range sigchan { if sig == syscall.SIGUSR2 { - err := logtarget.Target.Rotate() + err := logtarget.Default.Rotate() if err != nil { fmt.Fprintf(os.Stderr, "unable to rotate log file: %v", err) } diff --git a/pkg/logtarget/logtarget.go b/pkg/logtarget/logtarget.go index 144654c..6ad43f5 100644 --- a/pkg/logtarget/logtarget.go +++ b/pkg/logtarget/logtarget.go @@ -12,6 +12,10 @@ import ( "sync" ) +// LogTarget implements the io.Writer interface, allowing +// LogTarget to be registered with the regular Go log package. +// LogTarget multiplexes its incoming writes to multiple optional +// output writers, and one main output writer (the log file). type LogTarget interface { io.Writer @@ -19,25 +23,21 @@ type LogTarget interface { Rotate() error } -// LogTarget implements the io.Writer interface, allowing -// LogTarget to be registered with the regular Go log package. -// LogTarget multiplexes its incoming writes to multiple optional -// output writers, and one main output writer (the log file). -type FileLogTarget struct { +type fileLogTarget struct { mu sync.Mutex logfn string file *os.File memLog *bytes.Buffer } -var Target LogTarget +var Default LogTarget func init() { - Target = &FileLogTarget{} + Default = &fileLogTarget{} } // Write writes a log message to all registered io.Writers -func (target *FileLogTarget) Write(in []byte) (int, error) { +func (target *fileLogTarget) Write(in []byte) (int, error) { target.mu.Lock() defer target.mu.Unlock() @@ -60,7 +60,7 @@ func (target *FileLogTarget) Write(in []byte) (int, error) { // OpenFile opens the main log file for writing. // This method will open the file in append-only mode. -func (target *FileLogTarget) OpenFile(fn string) (err error) { +func (target *fileLogTarget) OpenFile(fn string) (err error) { target.logfn = fn target.file, err = os.OpenFile(target.logfn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) if err != nil { @@ -73,7 +73,7 @@ func (target *FileLogTarget) OpenFile(fn string) (err error) { // This method holds a lock while rotating the log file, // and all log writes will be held back until the rotation // is complete. -func (target *FileLogTarget) Rotate() error { +func (target *fileLogTarget) Rotate() error { target.mu.Lock() defer target.mu.Unlock() -- cgit v1.2.3 From 9c082d3516187cbf2a334f0dbe907717afcaedf1 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 14:09:03 +0000 Subject: Make OpenFile a factory function instead of a method on LogTarget. Use this to initialize the default logging target --- cmd/grumble/grumble.go | 2 +- pkg/logtarget/logtarget.go | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/cmd/grumble/grumble.go b/cmd/grumble/grumble.go index 6d2c93a..04f87c7 100644 --- a/cmd/grumble/grumble.go +++ b/cmd/grumble/grumble.go @@ -37,7 +37,7 @@ func main() { dataDir.Close() // Set up logging - err = logtarget.Default.OpenFile(Args.LogPath) + logtarget.Default, err = logtarget.OpenFile(Args.LogPath) if err != nil { fmt.Fprintf(os.Stderr, "Unable to open log file (%v): %v", Args.LogPath, err) return diff --git a/pkg/logtarget/logtarget.go b/pkg/logtarget/logtarget.go index 6ad43f5..950458a 100644 --- a/pkg/logtarget/logtarget.go +++ b/pkg/logtarget/logtarget.go @@ -19,7 +19,6 @@ import ( type LogTarget interface { io.Writer - OpenFile(string) error Rotate() error } @@ -32,8 +31,17 @@ type fileLogTarget struct { var Default LogTarget -func init() { - Default = &fileLogTarget{} +// OpenFile creates a LogTarget pointing to a log file +// and returns it. +// This method will open the file in append-only mode. +func OpenFile(fileName string) (t LogTarget, err error) { + target := &fileLogTarget{} + target.logfn = fileName + target.file, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) + if err != nil { + return nil, err + } + return target, nil } // Write writes a log message to all registered io.Writers @@ -58,17 +66,6 @@ func (target *fileLogTarget) Write(in []byte) (int, error) { return len(in), nil } -// OpenFile opens the main log file for writing. -// This method will open the file in append-only mode. -func (target *fileLogTarget) OpenFile(fn string) (err error) { - target.logfn = fn - target.file, err = os.OpenFile(target.logfn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) - if err != nil { - return err - } - return nil -} - // Rotate rotates the current log file. // This method holds a lock while rotating the log file, // and all log writes will be held back until the rotation -- cgit v1.2.3 From d6c4d9f766137c7115eaa38e7a6206bd087e091a Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 14:10:33 +0000 Subject: Remove unused field --- pkg/logtarget/logtarget.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pkg/logtarget/logtarget.go b/pkg/logtarget/logtarget.go index 950458a..5cf99da 100644 --- a/pkg/logtarget/logtarget.go +++ b/pkg/logtarget/logtarget.go @@ -6,7 +6,6 @@ package logtarget import ( - "bytes" "io" "os" "sync" @@ -23,10 +22,9 @@ type LogTarget interface { } type fileLogTarget struct { - mu sync.Mutex - logfn string - file *os.File - memLog *bytes.Buffer + mu sync.Mutex + logfn string + file *os.File } var Default LogTarget -- cgit v1.2.3 From 8b2c7901ee2512c4adfd33ee59be5c3b787c05e7 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 14:20:13 +0000 Subject: Use MultiWriter to simplify the writing implementation. Also make it possible to initialize the log target to variable amounts of writers, and doesn't hardcode the use of StdErr as output --- cmd/grumble/grumble.go | 2 +- pkg/logtarget/logtarget.go | 52 +++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/cmd/grumble/grumble.go b/cmd/grumble/grumble.go index 04f87c7..139eadc 100644 --- a/cmd/grumble/grumble.go +++ b/cmd/grumble/grumble.go @@ -37,7 +37,7 @@ func main() { dataDir.Close() // Set up logging - logtarget.Default, err = logtarget.OpenFile(Args.LogPath) + logtarget.Default, err = logtarget.OpenFile(Args.LogPath, os.Stderr) if err != nil { fmt.Fprintf(os.Stderr, "Unable to open log file (%v): %v", Args.LogPath, err) return diff --git a/pkg/logtarget/logtarget.go b/pkg/logtarget/logtarget.go index 5cf99da..1b69a3b 100644 --- a/pkg/logtarget/logtarget.go +++ b/pkg/logtarget/logtarget.go @@ -21,57 +21,66 @@ type LogTarget interface { Rotate() error } -type fileLogTarget struct { +// logTarget is the default implementation of a log +// target. It can write to more than one writer at the same time +// but only rotate one file +type logTarget struct { mu sync.Mutex logfn string file *os.File + w io.Writer + ws []io.Writer } +// Default is the default log target for the application +// It has to be initialized before used var Default LogTarget +// OpenWriters returns a log target that will +// log to all the given writers at the same time +func OpenWriters(ws ...io.Writer) LogTarget { + target := &logTarget{} + target.w = io.MultiWriter(ws...) + return target +} + // OpenFile creates a LogTarget pointing to a log file // and returns it. // This method will open the file in append-only mode. -func OpenFile(fileName string) (t LogTarget, err error) { - target := &fileLogTarget{} +// It also takes a variable number of writers that are +// other log targets +func OpenFile(fileName string, ws ...io.Writer) (t LogTarget, err error) { + target := &logTarget{} target.logfn = fileName target.file, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0650) if err != nil { return nil, err } + target.ws = ws + target.w = io.MultiWriter(append(ws, target.file)...) return target, nil } // Write writes a log message to all registered io.Writers -func (target *fileLogTarget) Write(in []byte) (int, error) { +func (target *logTarget) Write(out []byte) (int, error) { target.mu.Lock() defer target.mu.Unlock() - if target.file == nil { - panic("no log file opened") - } - - n, err := os.Stderr.Write(in) - if err != nil { - return n, err - } - - n, err = target.file.Write(in) - if err != nil { - return n, err - } - - return len(in), nil + return target.Write(out) } -// Rotate rotates the current log file. +// Rotate rotates the current log file, if one is opened. // This method holds a lock while rotating the log file, // and all log writes will be held back until the rotation // is complete. -func (target *fileLogTarget) Rotate() error { +func (target *logTarget) Rotate() error { target.mu.Lock() defer target.mu.Unlock() + if target.file == nil { + return nil + } + // Close the existing log file err := target.file.Close() if err != nil { @@ -82,6 +91,7 @@ func (target *fileLogTarget) Rotate() error { if err != nil { return err } + target.w = io.MultiWriter(append(target.ws, target.file)...) return nil } -- cgit v1.2.3 From dd9b5531a3dc4ee55b7bff86ec924e56ec573be5 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 15:00:08 +0000 Subject: Extract more generic versions of setting and checking configuration passwords --- cmd/grumble/server.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index 64b4dd8..bca43aa 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -175,8 +175,7 @@ func (server *Server) RootChannel() *Channel { return root } -// Set password as the new SuperUser password -func (server *Server) SetSuperUserPassword(password string) { +func (server *Server) setConfigPassword(key, password string) { saltBytes := make([]byte, 24) _, err := rand.Read(saltBytes) if err != nil { @@ -190,7 +189,6 @@ func (server *Server) SetSuperUserPassword(password string) { digest := hex.EncodeToString(hasher.Sum(nil)) // Could be racy, but shouldn't really matter... - key := "SuperUserPassword" val := "sha1$" + salt + "$" + digest server.cfg.Set(key, val) @@ -199,9 +197,13 @@ func (server *Server) SetSuperUserPassword(password string) { } } -// CheckSuperUserPassword checks whether password matches the set SuperUser password. -func (server *Server) CheckSuperUserPassword(password string) bool { - parts := strings.Split(server.cfg.StringValue("SuperUserPassword"), "$") +// Set password as the new SuperUser password +func (server *Server) SetSuperUserPassword(password string) { + server.setConfigPassword("SuperUserPassword", password) +} + +func (server *Server) checkConfigPassword(key, password string) bool { + parts := strings.Split(server.cfg.StringValue(key), "$") if len(parts) != 3 { return false } @@ -239,6 +241,11 @@ func (server *Server) CheckSuperUserPassword(password string) bool { return false } +// CheckSuperUserPassword checks whether password matches the set SuperUser password. +func (server *Server) CheckSuperUserPassword(password string) bool { + return server.checkConfigPassword("SuperUserPassword", password) +} + // Called by the server to initiate a new client connection. func (server *Server) handleIncomingClient(conn net.Conn) (err error) { client := new(Client) -- cgit v1.2.3 From b076a994922b0357be25848672f42e49f792b318 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 15:03:05 +0000 Subject: Add new methods for setting and checking a potential server password --- cmd/grumble/server.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index bca43aa..edc6a6f 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -197,11 +197,16 @@ func (server *Server) setConfigPassword(key, password string) { } } -// Set password as the new SuperUser password +// SetSuperUserPassword sets password as the new SuperUser password func (server *Server) SetSuperUserPassword(password string) { server.setConfigPassword("SuperUserPassword", password) } +// SetServerPassword sets password as the new Server password +func (server *Server) SetServerPassword(password string) { + server.setConfigPassword("ServerPassword", password) +} + func (server *Server) checkConfigPassword(key, password string) bool { parts := strings.Split(server.cfg.StringValue(key), "$") if len(parts) != 3 { @@ -246,6 +251,11 @@ func (server *Server) CheckSuperUserPassword(password string) bool { return server.checkConfigPassword("SuperUserPassword", password) } +// CheckServerPassword checks whether password matches the set Server password. +func (server *Server) CheckServerPassword(password string) bool { + return server.checkConfigPassword("ServerPassword", password) +} + // Called by the server to initiate a new client connection. func (server *Server) handleIncomingClient(conn net.Conn) (err error) { client := new(Client) -- cgit v1.2.3 From 495d699ec82b30187eca72cadfdd1c755798b6e5 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 26 Mar 2020 16:11:47 +0000 Subject: Try to authenticate using server password if user authentication hasn't happened --- cmd/grumble/server.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmd/grumble/server.go b/cmd/grumble/server.go index edc6a6f..663b791 100644 --- a/cmd/grumble/server.go +++ b/cmd/grumble/server.go @@ -256,6 +256,10 @@ func (server *Server) CheckServerPassword(password string) bool { return server.checkConfigPassword("ServerPassword", password) } +func (server *Server) hasServerPassword() bool { + return server.cfg.StringValue("ServerPassword") != "" +} + // Called by the server to initiate a new client connection. func (server *Server) handleIncomingClient(conn net.Conn) (err error) { client := new(Client) @@ -535,6 +539,13 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) { } } + if client.user == nil && server.hasServerPassword() { + if auth.Password == nil || !server.CheckServerPassword(*auth.Password) { + client.RejectAuth(mumbleproto.Reject_WrongServerPW, "Invalid server password") + return + } + } + // Setup the cryptstate for the client. err = client.crypt.GenerateKey(client.CryptoMode) if err != nil { -- cgit v1.2.3 From 84c57c38c3a547c62b3e9801e81fba7cce570519 Mon Sep 17 00:00:00 2001 From: Derrick Date: Sat, 11 Apr 2020 13:00:36 -0700 Subject: Updated Dockerfile. Dockerfile now uses go 1.14, pulls in the required build packages to build the required modules, and exposes the server ports for use. --- Dockerfile | 10 +++++++--- Dockerfile.arm32v6 | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index f30ac8e..d976431 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,12 @@ -FROM golang:1.9-alpine as builder +FROM golang:1.14-alpine as builder COPY . /go/src/mumble.info/grumble WORKDIR /go/src/mumble.info/grumble -RUN apk add --no-cache git \ - && go get -v -t ./... \ +RUN apk add --no-cache git build-base + +RUN go get -v -t ./... \ && go build mumble.info/grumble/cmd/grumble \ && go test -v ./... @@ -21,4 +22,7 @@ WORKDIR /data VOLUME /data +EXPOSE 64738/tcp +EXPOSE 64738/udp + ENTRYPOINT [ "/usr/bin/grumble", "--datadir", "/data", "--log", "/data/grumble.log" ] diff --git a/Dockerfile.arm32v6 b/Dockerfile.arm32v6 index 4638f99..a32951a 100644 --- a/Dockerfile.arm32v6 +++ b/Dockerfile.arm32v6 @@ -1,11 +1,12 @@ -FROM arm32v6/golang:1.9-alpine as builder +FROM arm32v6/golang:1.14-alpine as builder COPY . /go/src/mumble.info/grumble WORKDIR /go/src/mumble.info/grumble -RUN apk add --no-cache git \ - && go get -v -t ./... \ +RUN apk add --no-cache git build-base + +RUN go get -v -t ./... \ && go build mumble.info/grumble/cmd/grumble \ && go test -v ./... @@ -21,4 +22,7 @@ WORKDIR /data VOLUME /data +EXPOSE 64738/tcp +EXPOSE 64738/udp + ENTRYPOINT [ "/usr/bin/grumble", "--datadir", "/data", "--log", "/data/grumble.log" ] -- cgit v1.2.3 From a11c186b3ad3b1b9881fa20155a709a0470bbec3 Mon Sep 17 00:00:00 2001 From: Derrick Date: Sat, 11 Apr 2020 14:01:29 -0700 Subject: Update README. Update the readme to link to travis-ci.com instead of .org. Also move the code into proper code blocks. --- README.md | 64 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index cd93c7a..d9b904f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Linux CI (Travis CI): -[![Build Status](https://travis-ci.com/mumble-voip/grumble.svg?branch=master)](https://travis-ci.org/mumble-voip/grumble) +[![Build Status](https://travis-ci.com/mumble-voip/grumble.svg?branch=master)](https://travis-ci.com/mumble-voip/grumble) Windows CI (AppVeyor): @@ -23,18 +23,21 @@ https://golang.org/dl/ Once Go is installed, you should set up a GOPATH to avoid clobbering your Go environment's root directory with third party packages. Set up a GOPATH. On Unix, do something like this - - $ export GOPATH=$HOME/gocode - $ mkdir -p $GOPATH +```shell script +$ export GOPATH=$HOME/gocode +$ mkdir -p $GOPATH +``` and on Windows, do something like this (for cmd.exe): - - c:\> set GOPATH=%USERPROFILE%\gocode - c:\> mkdir %GOPATH% +```shell script +c:\> set GOPATH=%USERPROFILE%\gocode +c:\> mkdir %GOPATH% +``` Then, it's time to install Grumble. The following line should do the trick: - - $ go get mumble.info/grumble/cmd/grumble +```shell script +$ go get mumble.info/grumble/cmd/grumble +``` And that should be it. Grumble has been built, and is available in $GOPATH/bin as 'grumble'. @@ -61,29 +64,32 @@ Docker ## Getting the image ### Building - - $ git clone https://github.com/mumble-voip/grumble.git - $ cd grumble/ - $ docker build -t mumble-voip/grumble . +```shell script +$ git clone https://github.com/mumble-voip/grumble.git +$ cd grumble/ +$ docker build -t mumble-voip/grumble . +``` ## Running ### Command line - - $ docker run \ - -v $HOME/.grumble:/data \ - -p 64738:64738 \ - -p 64738:64738/udp \ - mumble-voip/grumble +```shell script +$ docker run \ + -v $HOME/.grumble:/data \ + -p 64738:64738 \ + -p 64738:64738/udp \ + mumble-voip/grumble +``` ### Compose - - version: '3' - services: - grumble: - image: mumble-voip/grumble - ports: - - 64738:64738 - - 64738:64738/udp - volumes: - - $HOME/.grumble:/data +```yaml +version: '3' +services: + grumble: + image: mumble-voip/grumble + ports: + - 64738:64738 + - 64738:64738/udp + volumes: + - $HOME/.grumble:/data +``` -- cgit v1.2.3