Skip to content

Commit dce09a3

Browse files
authored
fix(host,host-deployer): host-deployer add password quality check (#23876)
1 parent 0971950 commit dce09a3

File tree

18 files changed

+2984
-302
lines changed

18 files changed

+2984
-302
lines changed

pkg/baremetal/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3063,10 +3063,12 @@ func (s *SBaremetalServer) SyncPartitionSize(term *ssh.Client, rootDisk *disktoo
30633063

30643064
func (s *SBaremetalServer) DoDeploy(tool *disktool.SSHPartitionTool, term *ssh.Client, data jsonutils.JSONObject, isInit bool) (jsonutils.JSONObject, error) {
30653065
publicKey := deployapi.GetKeys(data)
3066+
isRandomPassword := false
30663067
password, _ := data.GetString("password")
30673068
resetPassword := jsonutils.QueryBoolean(data, "reset_password", false)
30683069
if resetPassword && len(password) == 0 {
30693070
password = seclib.RandomPassword(12)
3071+
isRandomPassword = true
30703072
}
30713073
deployArray := make([]*deployapi.DeployContent, 0)
30723074
if data.Contains("deploys") {
@@ -3077,7 +3079,7 @@ func (s *SBaremetalServer) DoDeploy(tool *disktool.SSHPartitionTool, term *ssh.C
30773079
}
30783080
userData, _ := s.desc.GetString("user_data")
30793081
deployInfo := deployapi.NewDeployInfo(publicKey, deployArray,
3080-
password, isInit, true, o.Options.LinuxDefaultRootUser, o.Options.WindowsDefaultAdminUser, false, "",
3082+
password, isRandomPassword, isInit, true, o.Options.LinuxDefaultRootUser, o.Options.WindowsDefaultAdminUser, false, "",
30813083
false, "",
30823084
userData,
30833085
)

pkg/hostman/guestfs/core.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,7 @@ func DoDeployGuestFs(rootfs fsdriver.IRootFsDriver, guestDesc *deployapi.GuestDe
179179
return nil, errors.Wrap(err, "DeployPublicKey")
180180
}
181181
var secret string
182-
if secret, err = rootfs.ChangeUserPasswd(partition, account, gid,
183-
deployInfo.PublicKey.PublicKey, deployInfo.Password); err != nil {
182+
if secret, err = rootfs.ChangeUserPasswd(partition, account, gid, deployInfo.PublicKey.PublicKey, deployInfo.Password, deployInfo.IsRandomPassword); err != nil {
184183
return nil, errors.Wrap(err, "ChangeUserPasswd")
185184
}
186185
if len(secret) > 0 {

pkg/hostman/guestfs/fsdriver/android.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func (m *sBaseAndroidRootFs) DeployPublicKey(rootfs IDiskPartition, uname string
7878
return nil
7979
}
8080

81-
func (m *sBaseAndroidRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string) (string, error) {
81+
func (m *sBaseAndroidRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
8282
return "", nil
8383
}
8484

pkg/hostman/guestfs/fsdriver/esxi.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func (m *SEsxiRootFs) GetOs() string {
5656
return "VMWare"
5757
}
5858

59-
func (m *SEsxiRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string) (string, error) {
59+
func (m *SEsxiRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
6060
return utils.EncryptAESBase64(gid, "(blank)")
6161
}
6262

pkg/hostman/guestfs/fsdriver/interface.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ type IRootFsDriver interface {
8383
DeployFstabScripts(IDiskPartition, []*deployapi.Disk) error
8484
GetLoginAccount(IDiskPartition, string, bool, bool) (string, error)
8585
DeployPublicKey(IDiskPartition, string, *deployapi.SSHKeys) error
86-
ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string) (string, error)
86+
ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error)
8787
DeployYunionroot(rootFs IDiskPartition, pubkeys *deployapi.SSHKeys, isInit bool, enableCloudInit bool) error
8888
EnableSerialConsole(IDiskPartition, *jsonutils.JSONDict) error
8989
DisableSerialConsole(IDiskPartition) error

pkg/hostman/guestfs/fsdriver/linux.go

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"yunion.io/x/onecloud/pkg/util/fstabutils"
4343
"yunion.io/x/onecloud/pkg/util/netutils2"
4444
"yunion.io/x/onecloud/pkg/util/procutils"
45+
"yunion.io/x/onecloud/pkg/util/pwquality"
4546
"yunion.io/x/onecloud/pkg/util/seclib2"
4647
"yunion.io/x/onecloud/pkg/util/sysutils"
4748
)
@@ -226,7 +227,24 @@ func (l *sLinuxRootFs) GetLoginAccount(rootFs IDiskPartition, sUser string, defa
226227
return selUsr, nil
227228
}
228229

229-
func (l *sLinuxRootFs) ChangeUserPasswd(rootFs IDiskPartition, account, gid, publicKey, password string) (string, error) {
230+
func (l *sLinuxRootFs) checkInputPasswd(rootFs IDiskPartition, config *pwquality.Config, account, gid, publicKey, password string) string {
231+
if config == nil {
232+
return password
233+
}
234+
235+
err := config.Validate(password, account)
236+
if err != nil && errors.Cause(err) == pwquality.ErrPasswordTooWeak {
237+
log.Infof("password %s too weak, try regenerate password", password)
238+
npassword := config.GeneratePassword(seclib2.RandomPassword2)
239+
if len(npassword) > 0 {
240+
log.Infof("regenerate password %s", npassword)
241+
password = npassword
242+
}
243+
}
244+
return password
245+
}
246+
247+
func (l *sLinuxRootFs) ChangeUserPasswd(rootFs IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
230248
var secret string
231249
var err error
232250
err = rootFs.Passwd(account, password, false)
@@ -1099,6 +1117,27 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics
10991117
return rootFs.FilePutContents(fn, cmds.String(), false, false)
11001118
}
11011119

1120+
func (r *sDebianLikeRootFs) ChangeUserPasswd(rootFs IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
1121+
if isRandomPassword {
1122+
var pwqualityConf *pwquality.Config
1123+
if rootFs.Exists("/etc/security/pwquality.conf", false) {
1124+
pwConfig, err := rootFs.FileGetContents("/etc/security/pwquality.conf", false)
1125+
if err == nil {
1126+
pwqualityConf = pwquality.ParseConfig(pwConfig)
1127+
}
1128+
}
1129+
if rootFs.Exists("/etc/pam.d/common-password", false) {
1130+
pamConfig, err := rootFs.FileGetContents("/etc/pam.d/common-password", false)
1131+
if err == nil {
1132+
pwqualityConf = pwquality.ParsePAMConfig(pamConfig, pwqualityConf)
1133+
}
1134+
}
1135+
password = r.checkInputPasswd(rootFs, pwqualityConf, account, gid, publicKey, password)
1136+
}
1137+
1138+
return r.sLinuxRootFs.ChangeUserPasswd(rootFs, account, gid, publicKey, password, isRandomPassword)
1139+
}
1140+
11021141
type SDebianRootFs struct {
11031142
*sDebianLikeRootFs
11041143
}
@@ -1394,6 +1433,26 @@ func (r *sRedhatLikeRootFs) Centos5DeployNetworkingScripts(rootFs IDiskPartition
13941433
return nil
13951434
}
13961435

1436+
func (r *sRedhatLikeRootFs) ChangeUserPasswd(rootFs IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
1437+
if isRandomPassword {
1438+
var pwqualityConf *pwquality.Config
1439+
if rootFs.Exists("/etc/security/pwquality.conf", false) {
1440+
pwConfig, err := rootFs.FileGetContents("/etc/security/pwquality.conf", false)
1441+
if err == nil {
1442+
pwqualityConf = pwquality.ParseConfig(pwConfig)
1443+
}
1444+
}
1445+
if rootFs.Exists("/etc/pam.d/system-auth", false) {
1446+
pamConfig, err := rootFs.FileGetContents("/etc/pam.d/system-auth", false)
1447+
if err == nil {
1448+
pwqualityConf = pwquality.ParsePAMConfig(pamConfig, pwqualityConf)
1449+
}
1450+
}
1451+
password = r.checkInputPasswd(rootFs, pwqualityConf, account, gid, publicKey, password)
1452+
}
1453+
return r.sLinuxRootFs.ChangeUserPasswd(rootFs, account, gid, publicKey, password, isRandomPassword)
1454+
}
1455+
13971456
func getMainNic(nics []*types.SServerNic) *types.SServerNic {
13981457
for i := range nics {
13991458
if nics[i].IsDefault {
@@ -2375,7 +2434,7 @@ func (d *SCoreOsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []*deplo
23752434
return nil
23762435
}
23772436

2378-
func (d *SCoreOsRootFs) ChangeUserPasswd(rootFs IDiskPartition, account, gid, publicKey, password string) (string, error) {
2437+
func (d *SCoreOsRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
23792438
keys := []string{}
23802439
if len(publicKey) > 0 {
23812440
keys = append(keys, publicKey)

pkg/hostman/guestfs/fsdriver/macos.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func (m *SMacOSRootFs) addScripts(lines []string) {
8686
m.scripts = append(m.scripts, "")
8787
}
8888

89-
func (m *SMacOSRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string) (string, error) {
89+
func (m *SMacOSRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
9090
lines := []string{
9191
fmt.Sprintf("dscl . -passwd /Users/%s %s", account, password),
9292
fmt.Sprintf("rm -fr /Users/%s/Library/Keychains/*", account),

pkg/hostman/guestfs/fsdriver/windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ func (w *SWindowsRootFs) CommitChanges(part IDiskPartition) error {
444444
return nil
445445
}
446446

447-
func (w *SWindowsRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string) (string, error) {
447+
func (w *SWindowsRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
448448
rinfo := w.GetReleaseInfo(part)
449449
confPath := part.GetLocalPath("/windows/system32/config", true)
450450
tool := winutils.NewWinRegTool(confPath)

pkg/hostman/guestfs/kvmpart/localfs.go

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ package kvmpart
1616

1717
import (
1818
"fmt"
19-
"io"
2019
"io/ioutil"
2120
"os"
21+
"os/exec"
2222
"path"
2323
"strings"
2424

@@ -139,40 +139,17 @@ func (f *SLocalGuestFS) Zerofiles(dir string, caseInsensitive bool) error {
139139
}
140140

141141
func (f *SLocalGuestFS) Passwd(account, password string, caseInsensitive bool) error {
142-
var proc = procutils.NewCommand("chroot", f.mountPath, "passwd", account)
143-
stdin, err := proc.StdinPipe()
144-
if err != nil {
145-
return err
146-
}
147-
defer stdin.Close()
142+
var proc = exec.Command("chroot", f.mountPath, "passwd", account)
148143

149-
outb, err := proc.StdoutPipe()
150-
if err != nil {
151-
return err
152-
}
153-
defer outb.Close()
144+
passwordInput := fmt.Sprintf("%s\n%s\n", password, password)
145+
proc.Stdin = strings.NewReader(passwordInput)
154146

155-
errb, err := proc.StderrPipe()
147+
out, err := proc.CombinedOutput()
156148
if err != nil {
157-
return err
158-
}
159-
defer errb.Close()
160-
161-
if err := proc.Start(); err != nil {
162-
return err
149+
return errors.Wrapf(err, "failed change passwd %s", out)
163150
}
164-
io.WriteString(stdin, fmt.Sprintf("%s\n", password))
165-
io.WriteString(stdin, fmt.Sprintf("%s\n", password))
166-
stdoutPut, err := ioutil.ReadAll(outb)
167-
if err != nil {
168-
return err
169-
}
170-
stderrOutPut, err := ioutil.ReadAll(errb)
171-
if err != nil {
172-
return err
173-
}
174-
log.Infof("Passwd %s %s", stdoutPut, stderrOutPut)
175-
return proc.Wait()
151+
log.Infof("Passwd %s", out)
152+
return nil
176153
}
177154

178155
func (f *SLocalGuestFS) Stat(usrDir string, caseInsensitive bool) os.FileInfo {

pkg/hostman/guestman/guestman.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,13 @@ func (m *SGuestManager) startDeploy(
986986
return nil, errors.Wrapf(err, "unmarshal to array of deployapi.DeployContent")
987987
}
988988
}
989+
990+
isRandomPassword := false
989991
password, _ := deployParams.Body.GetString("password")
990992
resetPassword := jsonutils.QueryBoolean(deployParams.Body, "reset_password", false)
991993
if resetPassword && len(password) == 0 {
992994
password = seclib.RandomPassword2(14)
995+
isRandomPassword = true
993996
}
994997
enableCloudInit := jsonutils.QueryBoolean(deployParams.Body, "enable_cloud_init", false)
995998
loginAccount, _ := deployParams.Body.GetString("login_account")
@@ -1007,7 +1010,7 @@ func (m *SGuestManager) startDeploy(
10071010
guestInfo, err := guest.DeployFs(ctx, deployParams.UserCred,
10081011
deployapi.NewDeployInfo(
10091012
publicKey, deployArray,
1010-
password, deployParams.IsInit, false,
1013+
password, isRandomPassword, deployParams.IsInit, false,
10111014
options.HostOptions.LinuxDefaultRootUser, options.HostOptions.WindowsDefaultAdminUser,
10121015
enableCloudInit, loginAccount, deployTelegraf, telegrafConfig,
10131016
guest.GetDesc().UserData,

0 commit comments

Comments
 (0)