Skip to content

Commit

Permalink
Implemented Password Hashing using bcrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
ukane-philemon committed Dec 25, 2021
1 parent 2e6789a commit e8e5864
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 38 deletions.
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func loadConfig() (*config, error) {
}
return nil, err
}

// Set the active network.
minRequired := 1
switch cfg.Network {
Expand Down
11 changes: 5 additions & 6 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var (
lastAddressIndexK = []byte("lastaddressindex")
// altSignAddrBktK stores alternate signing addresses.
altSignAddrBktK = []byte("altsigbkt")
//AdminPassHash is the hashed form of the AdminPass
//adminPassHashK stores the hash of cfg.AdminPass
adminPassHashK = []byte("adminPassHash")
)

Expand Down Expand Up @@ -461,26 +461,25 @@ func (vdb *VspDatabase) CheckIntegrity(ctx context.Context, params *chaincfg.Par
return nil
}

// UpdateAdminPass stores admin password hash in Database.
func (vdb *VspDatabase) UpdateAdminPass(adminPassHash string) error {
return vdb.db.Update(func(tx *bolt.Tx) error {
vspBkt := tx.Bucket(vspBktK)

// Add AdminPassHash to database.
return vspBkt.Put(adminPassHashK, []byte(adminPassHash))
})
}

// GetAdminHash retrieves admin password hash from Database.
func (vdb *VspDatabase) GetAdminHash() ([]byte, error) {
var adminPassHash []byte
err := vdb.db.View(func(tx *bolt.Tx) error {
vspBkt := tx.Bucket(vspBktK)

adminPassHash = vspBkt.Get(adminPassHashK)
if adminPassHash == nil {
return errors.New("AdminPassHash has not been set")
return errors.New("admin password hash has not been set")
}
return nil
})

return adminPassHash, err
}
}
47 changes: 26 additions & 21 deletions vspd.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 The Decred developers
// Copyright (c) 2021 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -38,11 +38,10 @@ func main() {
}
}

//Implementing password hash to increase security for AdminPass
//hashPassword hash cfg.AdminPass and returns the hash.
// hashPassword hashes cfg.AdminPass and returns the hash.
func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 15)
return string(bytes), err
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 15)
return string(bytes), err
}

// run is the main startup and teardown logic performed by the main package. It
Expand Down Expand Up @@ -82,27 +81,33 @@ func run(ctx context.Context) error {
}
defer db.Close()

//Check if adminPass Hash is set in db.
// Check if admin password hash is set in database.
hash, err := db.GetAdminHash()

//Ensure adminpass option is set
if cfg.AdminPass == "" && err != nil {
return errors.New("the adminpass option is not set")
if cfg.AdminPass == "" && err != nil {
log.Errorf("Admin password is not yet set: %v.", err)
return err
}

if hash != nil && cfg.AdminPass != "" {
//Hash the cfg.AdminPass value
cfg.AdminPass, err = hashPassword(cfg.AdminPass)

if err != nil {
return fmt.Errorf("Hashing AdminPass Failed: %w", err)
if cfg.AdminPass != "" {
// Hash cfg.AdminPass
cfg.AdminPass, err = hashPassword(cfg.AdminPass)
if err != nil {
log.Errorf("Hashing admin password failed: %v", err)
return err
}

// If cfg.adminPass is set,
// overwrite the saved admin password hash in database and shutdown.
db.UpdateAdminPass(cfg.AdminPass)
log.Info("Admin password has been hashed and saved successfully.\n Remove the admin password from config file and command line before running vspd again.")
log.Info("To reset admin password, provide admin password via config or commandline.")
requestShutdown()
shutdownWg.Wait()
}

//if adminpass is set, overwrite the saved adminpass hash in database.
db.UpdateAdminPass(cfg.AdminPass)

}

// Assign Hash Value to cfg.AdminPass
cfg.AdminPass = string(hash)

// Create RPC client for local dcrd instance (used for broadcasting and
// checking the status of fee transactions).
dcrd := rpc.SetupDcrd(cfg.DcrdUser, cfg.DcrdPass, cfg.DcrdHost, cfg.dcrdCert, nil)
Expand Down
15 changes: 5 additions & 10 deletions webapi/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,23 +198,18 @@ func ticketSearch(c *gin.Context) {
})
}

//checkPasswordHash compare hash value of given AdminPass with AdminPass hash.
func CheckPasswordHash(hash []byte, password string) bool {
err := bcrypt.CompareHashAndPassword(hash, []byte(password))
// checkPasswordHash compares the hash value of the provided password with
// the provided hash.
func checkPasswordHash(hash, password string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}

// adminLogin is the handler for "POST /admin". If a valid password is provided,
// the current session will be authenticated as an admin.
func adminLogin(c *gin.Context) {
password := c.PostForm("password")
hashedPass, err := db.GetAdminHash()
if err != nil {
log.Warnf("Not able to get Admin Hash: %w", err)
}

ok := CheckPasswordHash(hashedPass, password)

ok := checkPasswordHash(cfg.AdminPass, password)
if !ok {
log.Warnf("Failed login attempt from %s", c.ClientIP())
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
Expand Down

0 comments on commit e8e5864

Please sign in to comment.