blueprint: Hash all user passwords

This commit changes blueprint behavior to always store the hash of the
password for the 'customizations.user' accounts. Note that missing or
blank passwords are not hashed and should be dealt with at a lower
layer.

Resolves: rhbz#2107358
This commit is contained in:
Brian C. Lane 2022-07-14 14:48:57 -07:00 committed by Tom Gundersen
parent 963c53ce09
commit 20bf0c4836
2 changed files with 70 additions and 0 deletions

View file

@ -5,6 +5,8 @@ import (
"encoding/json"
"fmt"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/coreos/go-semver/semver"
)
@ -74,6 +76,12 @@ func (b *Blueprint) Initialize() error {
if err != nil {
return fmt.Errorf("Invalid 'version', must use Semantic Versioning: %s", err.Error())
}
err = b.CryptPasswords()
if err != nil {
return fmt.Errorf("Error hashing passwords: %s", err.Error())
}
return nil
}
@ -126,3 +134,29 @@ func (p Package) ToNameVersion() string {
return p.Name + "-" + p.Version
}
// CryptPasswords ensures that all blueprint passwords are hashed
func (b *Blueprint) CryptPasswords() error {
if b.Customizations == nil {
return nil
}
// Any passwords for users?
for i := range b.Customizations.User {
// Missing or empty password
if b.Customizations.User[i].Password == nil || len(*b.Customizations.User[i].Password) == 0 {
continue
}
if !crypt.PasswordIsCrypted(*b.Customizations.User[i].Password) {
pw, err := crypt.CryptSHA512(*b.Customizations.User[i].Password)
if err != nil {
return err
}
// Replace the password with the
b.Customizations.User[i].Password = &pw
}
}
return nil
}

View file

@ -2,6 +2,7 @@ package blueprint
import (
"encoding/json"
"strings"
"testing"
"github.com/BurntSushi/toml"
@ -213,3 +214,38 @@ func TestKernelNameCustomization(t *testing.T) {
}
}
}
// TestBlueprintPasswords check to make sure all passwords are hashed
func TestBlueprintPasswords(t *testing.T) {
blueprint := `
name = "test"
description = "Test"
version = "0.0.0"
[[customizations.user]]
name = "bart"
password = "nobodysawmedoit"
[[customizations.user]]
name = "lisa"
password = "$6$RWdHzrPfoM6BMuIP$gKYlBXQuJgP.G2j2twbOyxYjFDPUQw8Jp.gWe1WD/obX0RMyfgw5vt.Mn/tLLX4mQjaklSiIzoAW3HrVQRg4Q."
[[customizations.user]]
name = "maggie"
password = ""
`
var bp Blueprint
err := toml.Unmarshal([]byte(blueprint), &bp)
require.Nil(t, err)
require.Nil(t, bp.Initialize())
// Note: User entries are in the same order as the toml
users := bp.Customizations.GetUsers()
assert.Equal(t, "bart", users[0].Name)
assert.True(t, strings.HasPrefix(*users[0].Password, "$6$"))
assert.Equal(t, "lisa", users[1].Name)
assert.Equal(t, "$6$RWdHzrPfoM6BMuIP$gKYlBXQuJgP.G2j2twbOyxYjFDPUQw8Jp.gWe1WD/obX0RMyfgw5vt.Mn/tLLX4mQjaklSiIzoAW3HrVQRg4Q.", *users[1].Password)
assert.Equal(t, "maggie", users[2].Name)
assert.Equal(t, "", *users[2].Password)
}