From 68b1dc9e7249c6c386f920fc380f4199cb26aeea Mon Sep 17 00:00:00 2001 From: Daniel Oaks Date: Fri, 6 Oct 2017 00:03:53 +1000 Subject: [PATCH] Split passwd into its' own subpackage --- irc/accountreg.go | 3 +- irc/config.go | 9 +++-- irc/database.go | 4 ++- irc/{password_salted.go => passwd/salted.go} | 36 +++++++++++--------- irc/{password.go => passwd/unsalted.go} | 2 +- irc/server.go | 9 ++--- oragono.go | 3 +- 7 files changed, 37 insertions(+), 29 deletions(-) rename irc/{password_salted.go => passwd/salted.go} (54%) rename irc/{password.go => passwd/unsalted.go} (98%) diff --git a/irc/accountreg.go b/irc/accountreg.go index 0b2931f2..19f182f2 100644 --- a/irc/accountreg.go +++ b/irc/accountreg.go @@ -14,6 +14,7 @@ import ( "github.com/goshuirc/irc-go/ircfmt" "github.com/goshuirc/irc-go/ircmsg" + "github.com/oragono/oragono/irc/passwd" "github.com/oragono/oragono/irc/sno" "github.com/tidwall/buntdb" ) @@ -224,7 +225,7 @@ func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage) b var creds AccountCredentials // always set passphrase salt - creds.PassphraseSalt, err = NewSalt() + creds.PassphraseSalt, err = passwd.NewSalt() if err != nil { return fmt.Errorf("Could not create passphrase salt: %s", err.Error()) } diff --git a/irc/config.go b/irc/config.go index a476b35d..825a68b9 100644 --- a/irc/config.go +++ b/irc/config.go @@ -14,12 +14,11 @@ import ( "strings" "time" + "code.cloudfoundry.org/bytefmt" "github.com/oragono/oragono/irc/custime" "github.com/oragono/oragono/irc/logger" + "github.com/oragono/oragono/irc/passwd" "github.com/oragono/oragono/irc/utils" - - "code.cloudfoundry.org/bytefmt" - "gopkg.in/yaml.v2" ) @@ -48,7 +47,7 @@ func (conf *TLSListenConfig) Config() (*tls.Config, error) { // PasswordBytes returns the bytes represented by the password hash. func (conf *PassConfig) PasswordBytes() []byte { - bytes, err := DecodePasswordHash(conf.Password) + bytes, err := passwd.DecodePasswordHash(conf.Password) if err != nil { log.Fatal("decode password error: ", err) } @@ -102,7 +101,7 @@ type OperConfig struct { // PasswordBytes returns the bytes represented by the password hash. func (conf *OperConfig) PasswordBytes() []byte { - bytes, err := DecodePasswordHash(conf.Password) + bytes, err := passwd.DecodePasswordHash(conf.Password) if err != nil { log.Fatal("decode password error: ", err) } diff --git a/irc/database.go b/irc/database.go index f5c15bda..a347c92e 100644 --- a/irc/database.go +++ b/irc/database.go @@ -11,6 +11,8 @@ import ( "os" "strings" + "github.com/oragono/oragono/irc/passwd" + "github.com/tidwall/buntdb" ) @@ -36,7 +38,7 @@ func InitDB(path string) { err = store.Update(func(tx *buntdb.Tx) error { // set base db salt - salt, err := NewSalt() + salt, err := passwd.NewSalt() encodedSalt := base64.StdEncoding.EncodeToString(salt) if err != nil { log.Fatal("Could not generate cryptographically-secure salt for the user:", err.Error()) diff --git a/irc/password_salted.go b/irc/passwd/salted.go similarity index 54% rename from irc/password_salted.go rename to irc/passwd/salted.go index 61609244..299cf318 100644 --- a/irc/password_salted.go +++ b/irc/passwd/salted.go @@ -1,7 +1,7 @@ // Copyright (c) 2016 Daniel Oaks // released under the MIT license -package irc +package passwd import ( "crypto/rand" @@ -9,8 +9,12 @@ import ( "golang.org/x/crypto/bcrypt" ) -const newSaltLen = 30 -const defaultPasswordCost = 14 +const ( + // newSaltLen is how many bytes long newly-generated salts are. + newSaltLen = 30 + // defaultPasswordCost is the bcrypt cost we use for passwords. + defaultPasswordCost = 14 +) // NewSalt returns a salt for crypto uses. func NewSalt() ([]byte, error) { @@ -25,22 +29,22 @@ func NewSalt() ([]byte, error) { return salt, nil } -// PasswordManager supports the hashing and comparing of passwords with the given salt. -type PasswordManager struct { +// SaltedManager supports the hashing and comparing of passwords with the given salt. +type SaltedManager struct { salt []byte } -// NewPasswordManager returns a new PasswordManager with the given salt. -func NewPasswordManager(salt []byte) PasswordManager { - var pwm PasswordManager - pwm.salt = salt - return pwm +// NewSaltedManager returns a new SaltedManager with the given salt. +func NewSaltedManager(salt []byte) SaltedManager { + var sm SaltedManager + sm.salt = salt + return sm } // assemblePassword returns an assembled slice of bytes for the given password details. -func (pwm *PasswordManager) assemblePassword(specialSalt []byte, password string) []byte { +func (sm *SaltedManager) assemblePassword(specialSalt []byte, password string) []byte { var assembledPasswordBytes []byte - assembledPasswordBytes = append(assembledPasswordBytes, pwm.salt...) + assembledPasswordBytes = append(assembledPasswordBytes, sm.salt...) assembledPasswordBytes = append(assembledPasswordBytes, '-') assembledPasswordBytes = append(assembledPasswordBytes, specialSalt...) assembledPasswordBytes = append(assembledPasswordBytes, '-') @@ -49,14 +53,14 @@ func (pwm *PasswordManager) assemblePassword(specialSalt []byte, password string } // GenerateFromPassword encrypts the given password. -func (pwm *PasswordManager) GenerateFromPassword(specialSalt []byte, password string) ([]byte, error) { - assembledPasswordBytes := pwm.assemblePassword(specialSalt, password) +func (sm *SaltedManager) GenerateFromPassword(specialSalt []byte, password string) ([]byte, error) { + assembledPasswordBytes := sm.assemblePassword(specialSalt, password) return bcrypt.GenerateFromPassword(assembledPasswordBytes, defaultPasswordCost) } // CompareHashAndPassword compares a hashed password with its possible plaintext equivalent. // Returns nil on success, or an error on failure. -func (pwm *PasswordManager) CompareHashAndPassword(hashedPassword []byte, specialSalt []byte, password string) error { - assembledPasswordBytes := pwm.assemblePassword(specialSalt, password) +func (sm *SaltedManager) CompareHashAndPassword(hashedPassword []byte, specialSalt []byte, password string) error { + assembledPasswordBytes := sm.assemblePassword(specialSalt, password) return bcrypt.CompareHashAndPassword(hashedPassword, assembledPasswordBytes) } diff --git a/irc/password.go b/irc/passwd/unsalted.go similarity index 98% rename from irc/password.go rename to irc/passwd/unsalted.go index 652f525a..bedb2228 100644 --- a/irc/password.go +++ b/irc/passwd/unsalted.go @@ -1,7 +1,7 @@ // Copyright (c) 2012-2014 Jeremy Latt // released under the MIT license -package irc +package passwd import ( "encoding/base64" diff --git a/irc/server.go b/irc/server.go index 54e95999..51048d01 100644 --- a/irc/server.go +++ b/irc/server.go @@ -26,6 +26,7 @@ import ( "github.com/oragono/oragono/irc/caps" "github.com/oragono/oragono/irc/isupport" "github.com/oragono/oragono/irc/logger" + "github.com/oragono/oragono/irc/passwd" "github.com/oragono/oragono/irc/sno" "github.com/oragono/oragono/irc/utils" "github.com/tidwall/buntdb" @@ -108,7 +109,7 @@ type Server struct { operators map[string]Oper operclasses map[string]OperClass password []byte - passwords *PasswordManager + passwords *passwd.SaltedManager registeredChannels map[string]*RegisteredChannel registeredChannelsMutex sync.RWMutex rehashMutex sync.Mutex @@ -474,7 +475,7 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { // check the provided password password := []byte(msg.Params[0]) - if ComparePassword(server.password, password) != nil { + if passwd.ComparePassword(server.password, password) != nil { client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect") client.Send(nil, server.name, "ERROR", "Password incorrect") return true @@ -1140,7 +1141,7 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { server.configurableStateMutex.RUnlock() password := []byte(msg.Params[1]) - err = ComparePassword(oper.Pass, password) + err = passwd.ComparePassword(oper.Pass, password) if (oper.Pass == nil) || (err != nil) { client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, "Password incorrect") return true @@ -1523,7 +1524,7 @@ func (server *Server) loadDatastore(datastorePath string) error { return err } - pwm := NewPasswordManager(salt) + pwm := passwd.NewSaltedManager(salt) server.passwords = &pwm return nil }) diff --git a/oragono.go b/oragono.go index 80836995..17bded77 100644 --- a/oragono.go +++ b/oragono.go @@ -16,6 +16,7 @@ import ( "github.com/docopt/docopt-go" "github.com/oragono/oragono/irc" "github.com/oragono/oragono/irc/logger" + "github.com/oragono/oragono/irc/passwd" "github.com/oragono/oragono/mkcerts" stackimpact "github.com/stackimpact/stackimpact-go" "golang.org/x/crypto/ssh/terminal" @@ -58,7 +59,7 @@ Options: log.Fatal("Error reading password:", err.Error()) } password := string(bytePassword) - encoded, err := irc.GenerateEncodedPassword(password) + encoded, err := passwd.GenerateEncodedPassword(password) if err != nil { log.Fatal("encoding error:", err.Error()) }