diff --git a/client.go b/client.go index 044363b..85f7f05 100644 --- a/client.go +++ b/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Grumble Authors +// Copyright (c) 2010-2011 The Grumble Authors // The use of this source code is goverened by a BSD-style // license that can be found in the LICENSE-file. @@ -95,6 +95,21 @@ func (client *Client) ForceDisconnect() { client.disconnect(true) } +// Reject an authentication attempt +func (client *Client) RejectAuth(kind, reason string) { + var reasonString *string = nil + if len(reason) > 0 { + reasonString = proto.String(reason) + } + + client.sendProtoMessage(MessageReject, &mumbleproto.Reject{ + Type: mumbleproto.NewReject_RejectType(mumbleproto.Reject_RejectType_value[kind]), + Reason: reasonString, + }) + + client.ForceDisconnect() +} + // Read a protobuf message from a client func (client *Client) readProtoMessage() (msg *Message, err os.Error) { var length uint32 diff --git a/murmurdb.go b/murmurdb.go index c0e58f8..e3b63d0 100644 --- a/murmurdb.go +++ b/murmurdb.go @@ -306,7 +306,7 @@ func populateUsers(server *Server, db *sqlite.Conn) (err os.Error) { } if UserId == 0 { - server.superUserPassword = "sha1" + SHA1Password + server.superUserPassword = "sha1$$" + SHA1Password continue } diff --git a/server.go b/server.go index 7323afc..b0276e5 100644 --- a/server.go +++ b/server.go @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Grumble Authors +// Copyright (c) 2010-2011 The Grumble Authors // The use of this source code is goverened by a BSD-style // license that can be found in the LICENSE-file. @@ -18,6 +18,8 @@ import ( "goprotobuf.googlecode.com/hg/proto" "mumbleproto" "cryptstate" + "hash" + "strings" ) // The default port a Murmur server listens on @@ -117,6 +119,42 @@ func NewServer(id int64, addr string, port int) (s *Server, err os.Error) { return } +// Check whether password matches the set SuperUser password. +func (server *Server) CheckSuperUserPassword(password string) bool { + parts := strings.Split(server.superUserPassword, "$", -1) + if len(parts) != 3 { + return false + } + + if len(parts[2]) == 0 { + return false + } + + var h hash.Hash + switch parts[0] { + case "sha1": + h = sha1.New() + default: + // no such hash + return false + } + + // salt + if len(parts[1]) > 0 { + h.Write([]byte(parts[1])) + } + + // password + h.Write([]byte(password)) + + sum := hex.EncodeToString(h.Sum()) + if parts[2] == sum { + return true + } + + return false +} + // Called by the server to initiate a new client connection. func (server *Server) NewClient(conn net.Conn) (err os.Error) { client := new(Client) @@ -345,8 +383,20 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) { server.hclients[host] = append(server.hclients[host], client) server.hmutex.Unlock() + // SuperUser login check if client.Username == "SuperUser" { - client.UserId = 0 + // No password specified + if auth.Password == nil { + client.RejectAuth("WrongUserPW", "") + return + } else { + if server.CheckSuperUserPassword(*auth.Password) { + client.UserId = 0 + } else { + client.RejectAuth("WrongUserPW", "") + return + } + } } userstate := &mumbleproto.UserState{