fix(compute): add null check before hashing admin password
Change-Id: If45bf4a0bb8a3cdc6d11a5db818609e58f2983ef Signed-off-by: Hüseyin Altun <huseyin.altun@tubitak.gov.tr>
This commit is contained in:
committed by
Hüseyin Altun
parent
60743e8853
commit
4c2a8c70fb
@@ -83,6 +83,7 @@
|
||||
"react-fast-compare": "^3.0.1",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"sha512-crypt-ts": "^0.1.26",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
feat: Hash instance passwords for cloud-init
|
||||
@@ -24,6 +24,7 @@ import { isEmpty, isFinite } from 'lodash';
|
||||
import {
|
||||
getUserData,
|
||||
canCreateIronicByEndpoint,
|
||||
hashPasswordForCloudInit,
|
||||
} from 'resources/nova/instance';
|
||||
import { ironicOriginEndpoint } from 'client/client/constants';
|
||||
import Notify from 'components/Notify';
|
||||
@@ -332,6 +333,9 @@ export class CreateIronic extends StepAction {
|
||||
getUserData(server.adminPass, userData, username || 'root')
|
||||
);
|
||||
}
|
||||
if (server.adminPass) {
|
||||
server.adminPass = hashPasswordForCloudInit(server.adminPass);
|
||||
}
|
||||
return {
|
||||
server,
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ import globalServerStore from 'stores/nova/instance';
|
||||
import globalProjectStore from 'stores/keystone/project';
|
||||
import classnames from 'classnames';
|
||||
import { isEmpty, isFinite, isString } from 'lodash';
|
||||
import { getUserData } from 'resources/nova/instance';
|
||||
import { getUserData, hashPasswordForCloudInit } from 'resources/nova/instance';
|
||||
import { getAllDataDisks } from 'resources/cinder/snapshot';
|
||||
import { getGiBValue } from 'utils/index';
|
||||
import Notify from 'components/Notify';
|
||||
@@ -748,6 +748,9 @@ export class StepCreate extends StepAction {
|
||||
getUserData(server.adminPass, userData, username || 'root')
|
||||
);
|
||||
}
|
||||
if (server.adminPass) {
|
||||
server.adminPass = hashPasswordForCloudInit(server.adminPass);
|
||||
}
|
||||
const body = {
|
||||
server,
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ import PopActionEvent from 'src/components/Popover/PopActionEvent';
|
||||
import lockSvg from 'asset/image/lock.svg';
|
||||
import unlockSvg from 'asset/image/unlock.svg';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { sha512 } from 'sha512-crypt-ts';
|
||||
|
||||
const lockIcon = (
|
||||
<Tooltip
|
||||
@@ -217,7 +218,7 @@ const passwordAndUserData =
|
||||
'Content-Disposition: attachment; filename="passwd-script.txt" \n' +
|
||||
'\n' +
|
||||
'#!/bin/sh\n' +
|
||||
"echo 'USER_NAME:USER_PASSWORD' | chpasswd\n" +
|
||||
"echo 'USER_NAME:USER_PASSWORD' | chpasswd --encrypted \n" +
|
||||
'\n' +
|
||||
'--===============2309984059743762475==\n' +
|
||||
'Content-Type: text/x-shellscript; charset="us-ascii" \n' +
|
||||
@@ -250,7 +251,7 @@ const onlyPassword =
|
||||
'Content-Disposition: attachment; filename="passwd-script.txt" \n' +
|
||||
'\n' +
|
||||
'#!/bin/sh\n' +
|
||||
"echo 'USER_NAME:USER_PASSWORD' | chpasswd\n" +
|
||||
"echo 'USER_NAME:USER_PASSWORD' | chpasswd --encrypted \n" +
|
||||
'\n' +
|
||||
'--===============2309984059743762475==--';
|
||||
|
||||
@@ -264,18 +265,22 @@ const onlyUserData =
|
||||
'Content-Transfer-Encoding: 7bit\n' +
|
||||
'Content-Disposition: attachment; filename="init-shell.txt" \n' +
|
||||
'\n' +
|
||||
'USER_DATA\n' +
|
||||
'USER_DATA | chpasswd --encrypted\n' +
|
||||
'\n' +
|
||||
'--===============2309984059743762475==--';
|
||||
|
||||
export const getUserData = (password, userData, username = 'root') => {
|
||||
const hashedPassword = hashPasswordForCloudInit(password);
|
||||
|
||||
|
||||
|
||||
if (password && userData) {
|
||||
let str = passwordAndUserData.replace(/USER_PASSWORD/g, password);
|
||||
let str = passwordAndUserData.replace(/USER_PASSWORD/g, hashedPassword);
|
||||
str = str.replace(/USER_NAME/g, username);
|
||||
return str.replace(/USER_DATA/g, userData);
|
||||
}
|
||||
if (password) {
|
||||
const str = onlyPassword.replace(/USER_PASSWORD/g, password);
|
||||
const str = onlyPassword.replace(/USER_PASSWORD/g, hashedPassword);
|
||||
return str.replace(/USER_NAME/g, username);
|
||||
}
|
||||
return onlyUserData.replace(/USER_DATA/g, userData);
|
||||
@@ -583,3 +588,17 @@ export const isBootFromVolume = (item) => {
|
||||
}
|
||||
return !item.image;
|
||||
};
|
||||
|
||||
export const hashPasswordForCloudInit = (password) => {
|
||||
const hashedPassword = sha512.crypt(password, randomSalt());
|
||||
return hashedPassword;
|
||||
};
|
||||
const randomSalt = () => {
|
||||
const alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./';
|
||||
const length = 8 + Math.random() * 8;
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += alphabet[Math.floor(Math.random() * alphabet.length)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import client from 'client';
|
||||
import Base from 'stores/base';
|
||||
import { mapperRule } from 'resources/neutron/security-group-rule';
|
||||
import { RecycleBinStore } from '../skyline/recycle-server';
|
||||
import { hashPasswordForCloudInit } from 'src/resources/nova/instance';
|
||||
|
||||
export class ServerStore extends Base {
|
||||
@observable
|
||||
@@ -380,7 +381,7 @@ export class ServerStore extends Base {
|
||||
async changePassword({ id, password }) {
|
||||
const body = {
|
||||
changePassword: {
|
||||
adminPass: password,
|
||||
adminPass: hashPasswordForCloudInit(password),
|
||||
},
|
||||
};
|
||||
return this.operation({ body, id });
|
||||
|
||||
Reference in New Issue
Block a user