diff --git a/internal/osbuild/users_stage.go b/internal/osbuild/users_stage.go index 6a1a303b7..fab65388e 100644 --- a/internal/osbuild/users_stage.go +++ b/internal/osbuild/users_stage.go @@ -36,6 +36,12 @@ func NewUsersStageOptions(userCustomizations []blueprint.UserCustomization, omit users := make(map[string]UsersStageOptionsUser, len(userCustomizations)) for _, uc := range userCustomizations { + // Don't hash empty passwords, set to nil to lock account + if uc.Password != nil && len(*uc.Password) == 0 { + uc.Password = nil + } + + // Hash non-empty un-hashed passwords if uc.Password != nil && !crypt.PasswordIsCrypted(*uc.Password) { cryptedPassword, err := crypt.CryptSHA512(*uc.Password) if err != nil { diff --git a/internal/osbuild/users_stage_test.go b/internal/osbuild/users_stage_test.go index 3db69c543..ec858bc73 100644 --- a/internal/osbuild/users_stage_test.go +++ b/internal/osbuild/users_stage_test.go @@ -1,9 +1,13 @@ package osbuild import ( + "strings" "testing" + "github.com/osbuild/osbuild-composer/internal/blueprint" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNewUsersStage(t *testing.T) { @@ -14,3 +18,43 @@ func TestNewUsersStage(t *testing.T) { actualStage := NewUsersStage(&UsersStageOptions{}) assert.Equal(t, expectedStage, actualStage) } + +func TestNewUsersStageOptionsPassword(t *testing.T) { + Pass := "testpass" + EmptyPass := "" + CryptPass := "$6$RWdHzrPfoM6BMuIP$gKYlBXQuJgP.G2j2twbOyxYjFDPUQw8Jp.gWe1WD/obX0RMyfgw5vt.Mn/tLLX4mQjaklSiIzoAW3HrVQRg4Q." // #nosec G101 + + users := []blueprint.UserCustomization{ + blueprint.UserCustomization{ + Name: "bart", + Password: &Pass, + }, + blueprint.UserCustomization{ + Name: "lisa", + Password: &CryptPass, + }, + blueprint.UserCustomization{ + Name: "maggie", + Password: &EmptyPass, + }, + blueprint.UserCustomization{ + Name: "homer", + }, + } + + options, err := NewUsersStageOptions(users, false) + require.Nil(t, err) + require.NotNil(t, options) + + // bart's password should now be a hash + assert.True(t, strings.HasPrefix(*options.Users["bart"].Password, "$6$")) + + // lisa's password should be left alone (already hashed) + assert.Equal(t, CryptPass, *options.Users["lisa"].Password) + + // maggie's password should now be nil (locked account) + assert.Nil(t, options.Users["maggie"].Password) + + // homer's password should still be nil (locked account) + assert.Nil(t, options.Users["homer"].Password) +}