mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-16 22:50:10 +03:00
F #5422: first steps serveradmin login
Signed-off-by: Jorge Lobo <jlobo@opennebula.io>
This commit is contained in:
parent
49be6b5b59
commit
2332a1c164
@ -41,8 +41,10 @@ class OpenNebula::ServerCipherAuth
|
||||
if !srv_passwd.empty?
|
||||
# truncate token to 32-bytes for Ruby >= 2.4
|
||||
@key = Digest::SHA256.hexdigest(@srv_passwd)[0..31]
|
||||
else
|
||||
@iv = @key[0..15]
|
||||
else
|
||||
@key = ""
|
||||
@iv = ""
|
||||
end
|
||||
|
||||
@cipher = OpenSSL::Cipher.new(CIPHER)
|
||||
@ -112,6 +114,7 @@ class OpenNebula::ServerCipherAuth
|
||||
begin
|
||||
# truncate token to 32-bytes for Ruby >= 2.4
|
||||
@key = srv_pass[0..31]
|
||||
@iv = srv_pass[0..15]
|
||||
|
||||
token_array = decrypt(signed_text).split(':')
|
||||
|
||||
@ -133,7 +136,7 @@ class OpenNebula::ServerCipherAuth
|
||||
def encrypt(data)
|
||||
@cipher.encrypt
|
||||
@cipher.key = @key
|
||||
|
||||
@cipher.iv = @iv
|
||||
rc = @cipher.update(data)
|
||||
rc << @cipher.final
|
||||
|
||||
@ -143,7 +146,7 @@ class OpenNebula::ServerCipherAuth
|
||||
def decrypt(data)
|
||||
@cipher.decrypt
|
||||
@cipher.key = @key
|
||||
|
||||
@cipher.iv = @iv
|
||||
rc = @cipher.update(Base64::decode64(data))
|
||||
rc << @cipher.final
|
||||
|
||||
|
@ -23,7 +23,8 @@ const {
|
||||
defaultMethodZones,
|
||||
defaultMethodUserInfo,
|
||||
default2FAOpennebulaVar,
|
||||
defaultNamespace
|
||||
defaultNamespace,
|
||||
defaultServerAdminID
|
||||
} = require('server/utils/constants/defaults')
|
||||
const { getConfig } = require('server/utils/yml')
|
||||
const {
|
||||
@ -32,7 +33,7 @@ const {
|
||||
accepted
|
||||
} = require('server/utils/constants/http-codes')
|
||||
const { createToken } = require('server/utils/jwt')
|
||||
const { httpResponse } = require('server/utils/server')
|
||||
const { httpResponse, encrypt } = require('server/utils/server')
|
||||
const {
|
||||
responseOpennebula,
|
||||
checkOpennebulaCommand,
|
||||
@ -46,12 +47,15 @@ const appConfig = getConfig()
|
||||
|
||||
const namespace = appConfig.namespace || defaultNamespace
|
||||
const minimumExpirationTime = appConfig.minimun_opennebula_expiration || defaultOpennebulaMinimumExpiration
|
||||
const serverAdmin = appConfig.server_admin || defaultServerAdminID
|
||||
|
||||
const { POST } = httpMethod
|
||||
|
||||
const getOpennebulaMethod = checkOpennebulaCommand(defaultMethodLogin, POST)
|
||||
|
||||
let user = ''
|
||||
let key = ''
|
||||
let iv = ''
|
||||
let pass = ''
|
||||
let type = ''
|
||||
let tfatoken = ''
|
||||
@ -67,10 +71,22 @@ let relativeTime = ''
|
||||
|
||||
const dataSourceWithExpirateDate = () => Map(req).toObject()
|
||||
|
||||
const getKey = () => key
|
||||
const getIV = () => iv
|
||||
const getUser = () => user
|
||||
const getPass = () => pass
|
||||
const getRelativeTime = () => relativeTime
|
||||
|
||||
const setKey = newKey => {
|
||||
key = newKey
|
||||
return key
|
||||
}
|
||||
|
||||
const setIV = newIV => {
|
||||
iv = newIV
|
||||
return iv
|
||||
}
|
||||
|
||||
const setUser = newUser => {
|
||||
user = newUser
|
||||
return user
|
||||
@ -143,6 +159,10 @@ const validate2faAuthentication = informationUser => {
|
||||
informationUser.TEMPLATE.SUNSTONE &&
|
||||
informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
|
||||
) {
|
||||
/*********************************************************
|
||||
* Validate 2FA
|
||||
*********************************************************/
|
||||
|
||||
if (tfatoken.length <= 0) {
|
||||
updaterResponse(httpResponse(accepted))
|
||||
} else {
|
||||
@ -154,7 +174,10 @@ const validate2faAuthentication = informationUser => {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// without 2FA login
|
||||
/*********************************************************
|
||||
* Without 2FA
|
||||
*********************************************************/
|
||||
|
||||
rtn = true
|
||||
}
|
||||
return rtn
|
||||
@ -223,17 +246,21 @@ const setZones = () => {
|
||||
}
|
||||
|
||||
const login = userData => {
|
||||
let rtn = true
|
||||
let rtn = false
|
||||
if (userData) {
|
||||
const findTextError = `[${namespace + defaultMethodUserInfo}]`
|
||||
if (userData.indexOf && userData.indexOf(findTextError) >= 0) {
|
||||
updaterResponse(httpResponse(unauthorized))
|
||||
} else {
|
||||
rtn = true
|
||||
}
|
||||
if (userData.USER) {
|
||||
setZones()
|
||||
if (validate2faAuthentication(userData.USER)) {
|
||||
rtn = false
|
||||
checkOpennebulaToken(userData.USER)
|
||||
setDates()
|
||||
getServerAdmin()
|
||||
// checkOpennebulaToken(userData.USER) // aca seria el call de la funcion serveradmin
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -242,6 +269,62 @@ const login = userData => {
|
||||
}
|
||||
}
|
||||
|
||||
const createTokenServerAdmin = (serverAdmin = '', username = '') => {
|
||||
let rtn
|
||||
const key = getKey()
|
||||
const iv = getIV()
|
||||
if (serverAdmin && username && key && iv) {
|
||||
rtn = encrypt(
|
||||
`${serverAdmin}:${username}:${parseInt(nowWithMinutes.toSeconds())}`,
|
||||
key,
|
||||
iv
|
||||
)
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
|
||||
const wrapUserWithServerAdmin = (serverAdminData = {}) => {
|
||||
const relativeTime = getRelativeTime()
|
||||
const user = getUser()
|
||||
let userPassword = ''
|
||||
if (
|
||||
relativeTime &&
|
||||
serverAdminData &&
|
||||
serverAdminData.USER &&
|
||||
serverAdminData.USER.NAME &&
|
||||
(userPassword = serverAdminData.USER.PASSWORD) &&
|
||||
user
|
||||
) {
|
||||
/*********************************************************
|
||||
* equals what is placed in:
|
||||
* src/authm_mad/remotes/server_cipher/server_cipher_auth.rb:44
|
||||
*********************************************************/
|
||||
|
||||
setKey(userPassword.substring(0, 32))
|
||||
setIV(userPassword.substring(0, 16))
|
||||
const tokenWithServerAdmin = createTokenServerAdmin(serverAdminData.USER.NAME, user)
|
||||
if (tokenWithServerAdmin) {
|
||||
console.log('FINAL --> ', `${serverAdminData.USER.NAME}:${user}:${tokenWithServerAdmin}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getServerAdmin = () => {
|
||||
const oneConnect = connectOpennebula()
|
||||
oneConnect(
|
||||
defaultMethodUserInfo,
|
||||
[parseInt(serverAdmin, 10), false],
|
||||
(err, value) => {
|
||||
responseOpennebula(
|
||||
updaterResponse,
|
||||
err,
|
||||
value,
|
||||
wrapUserWithServerAdmin,
|
||||
next)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const checkOpennebulaToken = userData => {
|
||||
setDates()
|
||||
if (userData && userData.LOGIN_TOKEN) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
const appName = 'fireedge'
|
||||
const baseUrl = `${appName ? `/${appName}/` : '/'}`
|
||||
const baseUrlWebsockets = 'websockets'
|
||||
const apps = {
|
||||
flow: {
|
||||
name: 'flow',
|
||||
@ -30,6 +31,8 @@ const default2FAOpennebulaVar = 'TWO_FACTOR_AUTH_SECRET'
|
||||
const defaultIp = 'localhost'
|
||||
const protocol = 'http'
|
||||
const defaults = {
|
||||
defaultServerAdminID: 1,
|
||||
defaultTypeCrypto: 'aes-256-cbc',
|
||||
defaultEmptyFunction: () => undefined,
|
||||
defaultErrorTemplate: 'ERROR_FIREEDGE="%1$s"',
|
||||
defaultOpennebulaExpiration: 180,
|
||||
@ -41,11 +44,11 @@ const defaults = {
|
||||
},
|
||||
defaultFilesWebsockets: {
|
||||
hooks: {
|
||||
path: `${baseUrl}websockets/hooks`,
|
||||
path: `${baseUrl}${baseUrlWebsockets}hooks`,
|
||||
methods: ['GET', 'POST']
|
||||
},
|
||||
provision: {
|
||||
path: `${baseUrl}websockets/provision`,
|
||||
path: `${baseUrl}${baseUrlWebsockets}provision`,
|
||||
methods: ['GET', 'POST']
|
||||
}
|
||||
},
|
||||
|
@ -43,7 +43,13 @@ const fillResourceforHookConection = (username = '', action = '', parameters = '
|
||||
let match
|
||||
// parameters[0] is the resource ID
|
||||
if (username && action && (match = action.match(regexInfoAction)) && match[1] && parameters[0] >= 0) {
|
||||
if (global.users[username] && !global.users[username].resourcesHooks) {
|
||||
if (global && !global.users) {
|
||||
global.users = {}
|
||||
}
|
||||
if (!global.users[username]) {
|
||||
global.users[username] = {}
|
||||
}
|
||||
if (!global.users[username].resourcesHooks) {
|
||||
global.users[username].resourcesHooks = {}
|
||||
}
|
||||
global.users[username].resourcesHooks[match[1]] = parameters[0]
|
||||
|
@ -15,6 +15,8 @@
|
||||
const { env } = require('process')
|
||||
const { Map } = require('immutable')
|
||||
const { global } = require('window-or-global')
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
const { createCipheriv, createCipher, createDecipheriv, createDecipher } = require('crypto')
|
||||
const { existsSync, readFileSync, createWriteStream } = require('fs-extra')
|
||||
const { internalServerError } = require('./constants/http-codes')
|
||||
const { messageTerminal } = require('server/utils/general')
|
||||
@ -30,7 +32,8 @@ const {
|
||||
defaultKeyFilename,
|
||||
defaultWebpackMode,
|
||||
defaultOpennebulaZones,
|
||||
defaultEtcPath
|
||||
defaultEtcPath,
|
||||
defaultTypeCrypto
|
||||
} = require('./constants/defaults')
|
||||
|
||||
let cert = ''
|
||||
@ -117,6 +120,46 @@ const middlewareValidateAuthWebsocket = (server = {}, next = () => undefined) =>
|
||||
}
|
||||
}
|
||||
|
||||
const encrypt = (data = '', key = '', iv = '') => {
|
||||
let rtn
|
||||
if (data && key) {
|
||||
try {
|
||||
const cipher = iv ? createCipheriv(defaultTypeCrypto, key, iv) : createCipher(defaultTypeCrypto, key)
|
||||
let encryptData = cipher.update(data, 'ascii', 'base64')
|
||||
encryptData += cipher.final('base64')
|
||||
rtn = encryptData
|
||||
} catch (err) {
|
||||
const errorData = (err && err.message) || ''
|
||||
messageTerminal({
|
||||
color: 'red',
|
||||
message: 'Error: %s',
|
||||
type: errorData
|
||||
})
|
||||
}
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
|
||||
const decrypt = (data = '', key = '', iv = '') => {
|
||||
let rtn
|
||||
if (data && key) {
|
||||
try {
|
||||
const cipher = iv ? createDecipheriv(defaultTypeCrypto, key, iv) : createDecipher(defaultTypeCrypto, key)
|
||||
let decryptData = cipher.update(data, 'base64', 'ascii')
|
||||
decryptData += cipher.final('ascii')
|
||||
rtn = decryptData
|
||||
} catch (err) {
|
||||
const errorData = (err && err.message) || ''
|
||||
messageTerminal({
|
||||
color: 'red',
|
||||
message: 'Error: %s',
|
||||
type: errorData
|
||||
})
|
||||
}
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
|
||||
const existsFile = (path = '', success = () => undefined, error = () => undefined) => {
|
||||
let rtn = false
|
||||
let file
|
||||
@ -262,6 +305,8 @@ const parsePostData = (postData = {}) => {
|
||||
return rtn
|
||||
}
|
||||
module.exports = {
|
||||
encrypt,
|
||||
decrypt,
|
||||
getDataZone,
|
||||
existsFile,
|
||||
createFile,
|
||||
|
Loading…
x
Reference in New Issue
Block a user