@f5devcentral/atg-shared-utilities
Advanced tools
Comparing version 0.4.7 to 0.4.8
@@ -15,2 +15,12 @@ # Changelog | ||
## [0.4.8] | ||
### Added | ||
### Fixed | ||
### Changed | ||
- Fix use of 'this' in secureVault | ||
### Removed | ||
## [0.4.7] 2022-09-29 | ||
@@ -17,0 +27,0 @@ ### Added |
{ | ||
"name": "@f5devcentral/atg-shared-utilities", | ||
"version": "0.4.7", | ||
"version": "0.4.8", | ||
"scripts": { | ||
@@ -5,0 +5,0 @@ "lint": "eslint .", |
@@ -32,65 +32,5 @@ /** | ||
const splitData = data.match(/.{1,500}/g); | ||
return this._encryptHelper(splitData, [], 0).then((r) => r.join(',')); | ||
return encryptHelper(splitData, [], 0).then((r) => r.join(',')); | ||
} | ||
static _encryptHelper(dataAra, encryptedDataAra, i) { | ||
const radiusObjectName = `f5-teem_delete_me_${crypto.randomBytes(6).toString('hex')}`; | ||
const postOptions = { | ||
method: 'POST', | ||
protocol: 'http:', | ||
host: 'localhost', | ||
port: 8100, | ||
path: '/tm/auth/radius-server' | ||
}; | ||
const postBody = { | ||
name: radiusObjectName, | ||
secret: dataAra[i], | ||
server: 'foo' | ||
}; | ||
const deleteOptions = { | ||
method: 'DELETE', | ||
protocol: 'http:', | ||
host: 'localhost', | ||
port: 8100, | ||
path: `/tm/auth/radius-server/${radiusObjectName}` | ||
}; | ||
return Promise.resolve() | ||
.then(() => request.send(postOptions, postBody)) | ||
.then(() => { | ||
const tmshCmd = `tmsh -a list auth radius-server ${radiusObjectName} secret`; | ||
return this._execBash(tmshCmd).then((result) => { | ||
let parsed = null; | ||
try { | ||
parsed = result.split('\n')[1].trim().split(' ', 2)[1]; | ||
} catch (error) { | ||
throw new Error(`Unable to parse secret from TMSH: ${result}`); | ||
} | ||
return parsed; | ||
}); | ||
}) | ||
.then((secret) => { | ||
encryptedDataAra.push(secret); | ||
if (typeof encryptedDataAra[i] !== 'string') { | ||
const message = 'Encryption failed! Failed to retrieve secret'; | ||
throw new Error(message); | ||
} | ||
}) | ||
.then(() => request.send(deleteOptions)) | ||
.then(() => { | ||
i += 1; | ||
if (i < dataAra.length) { | ||
return this._encryptHelper(dataAra, encryptedDataAra, i); | ||
} | ||
return encryptedDataAra; | ||
}) | ||
.catch((e) => { | ||
// best effort to delete radius server | ||
request.send(deleteOptions).catch(() => {}); | ||
throw e; | ||
}); | ||
} | ||
/** | ||
@@ -103,55 +43,114 @@ * Decrypts data encrypted by this module | ||
static decrypt(data) { | ||
return this._decryptHelper(data.split(','), [], 0); | ||
return decryptHelper(data.split(','), [], 0); | ||
} | ||
} | ||
static _decryptHelper(encryptedDataAra, dataAra, i) { | ||
const secret = encryptedDataAra[i].replace(/\$/g, '\\$'); | ||
const php = [ | ||
'coapi_login("admin");', | ||
'$query_result = coapi_query("master_key");', | ||
'$row = coapi_fetch($query_result);', | ||
'$master_key = $row["master_key"];', | ||
`$plain = f5_decrypt_string("${secret}", $master_key);`, | ||
'echo $plain;' | ||
].join(''); | ||
/** | ||
* Return a promise to execute a bash command on a BIG-IP using | ||
* child-process.exec. | ||
* @public | ||
* @param {string} command - bash command to execute | ||
* @returns {Promise} - resolves to a string containing the command output | ||
*/ | ||
function execBash(command) { | ||
return new Promise((resolve, reject) => { | ||
childProcess.exec(command, (error, stdout) => { | ||
if (error !== null) { | ||
reject(error); | ||
} else { | ||
resolve(stdout); | ||
} | ||
}); | ||
}); | ||
} | ||
const cmd = `/usr/bin/php -r '${php}'`; | ||
return this._execBash(cmd) | ||
.then((result) => { | ||
i += 1; | ||
dataAra.push(result); | ||
if (i < encryptedDataAra.length) { | ||
return this._decryptHelper(encryptedDataAra, dataAra, i); | ||
} | ||
return dataAra.join(''); | ||
}) | ||
.catch((error) => { | ||
if (error.message.includes('Command failed')) { | ||
error.message = 'Command failed'; | ||
} | ||
const message = `Error decrypting data: ${error}`; | ||
throw new Error(message); | ||
}); | ||
} | ||
function encryptHelper(dataAra, encryptedDataAra, i) { | ||
const radiusObjectName = `f5-teem_delete_me_${crypto.randomBytes(6).toString('hex')}`; | ||
/** | ||
* Return a promise to execute a bash command on a BIG-IP using | ||
* child-process.exec. | ||
* @public | ||
* @param {string} command - bash command to execute | ||
* @returns {Promise} - resolves to a string containing the command output | ||
*/ | ||
static _execBash(command) { | ||
return new Promise((resolve, reject) => { | ||
childProcess.exec(command, (error, stdout) => { | ||
if (error !== null) { | ||
reject(error); | ||
} else { | ||
resolve(stdout); | ||
const postOptions = { | ||
method: 'POST', | ||
protocol: 'http:', | ||
host: 'localhost', | ||
port: 8100, | ||
path: '/tm/auth/radius-server' | ||
}; | ||
const postBody = { | ||
name: radiusObjectName, | ||
secret: dataAra[i], | ||
server: 'foo' | ||
}; | ||
const deleteOptions = { | ||
method: 'DELETE', | ||
protocol: 'http:', | ||
host: 'localhost', | ||
port: 8100, | ||
path: `/tm/auth/radius-server/${radiusObjectName}` | ||
}; | ||
return Promise.resolve() | ||
.then(() => request.send(postOptions, postBody)) | ||
.then(() => { | ||
const tmshCmd = `tmsh -a list auth radius-server ${radiusObjectName} secret`; | ||
return execBash(tmshCmd).then((result) => { | ||
let parsed = null; | ||
try { | ||
parsed = result.split('\n')[1].trim().split(' ', 2)[1]; | ||
} catch (error) { | ||
throw new Error(`Unable to parse secret from TMSH: ${result}`); | ||
} | ||
return parsed; | ||
}); | ||
}) | ||
.then((secret) => { | ||
encryptedDataAra.push(secret); | ||
if (typeof encryptedDataAra[i] !== 'string') { | ||
const message = 'Encryption failed! Failed to retrieve secret'; | ||
throw new Error(message); | ||
} | ||
}) | ||
.then(() => request.send(deleteOptions)) | ||
.then(() => { | ||
i += 1; | ||
if (i < dataAra.length) { | ||
return encryptHelper(dataAra, encryptedDataAra, i); | ||
} | ||
return encryptedDataAra; | ||
}) | ||
.catch((e) => { | ||
// best effort to delete radius server | ||
request.send(deleteOptions).catch(() => {}); | ||
throw e; | ||
}); | ||
} | ||
} | ||
function decryptHelper(encryptedDataAra, dataAra, i) { | ||
const secret = encryptedDataAra[i].replace(/\$/g, '\\$'); | ||
const php = [ | ||
'coapi_login("admin");', | ||
'$query_result = coapi_query("master_key");', | ||
'$row = coapi_fetch($query_result);', | ||
'$master_key = $row["master_key"];', | ||
`$plain = f5_decrypt_string("${secret}", $master_key);`, | ||
'echo $plain;' | ||
].join(''); | ||
const cmd = `/usr/bin/php -r '${php}'`; | ||
return execBash(cmd) | ||
.then((result) => { | ||
i += 1; | ||
dataAra.push(result); | ||
if (i < encryptedDataAra.length) { | ||
return decryptHelper(encryptedDataAra, dataAra, i); | ||
} | ||
return dataAra.join(''); | ||
}) | ||
.catch((error) => { | ||
if (error.message.includes('Command failed')) { | ||
error.message = 'Command failed'; | ||
} | ||
const message = `Error decrypting data: ${error}`; throw new Error(message); | ||
}); | ||
} | ||
module.exports = SecureVault; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
114140
2340