Skip to content

Commit

Permalink
Zowe Suite 1.16.0
Browse files Browse the repository at this point in the history
  • Loading branch information
zowe-robot authored Sep 28, 2020
2 parents cccdacf + cfd27c7 commit e21c360
Show file tree
Hide file tree
Showing 10 changed files with 391 additions and 102 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
All notable changes to the Zlux Server Framework package will be documented in this file.
This repo is part of the app-server Zowe Component, and the change logs here may appear on Zowe.org in that section.

## 1.16.0

- [D] Feature: Expose GET /server/environment endpoint with minimal data when RBAC is off, to share only environment details that are required to do dependency checks and more accurate server-to-server communication (#237)
- Add support for PKCS#12 certificates and certificate authorities
- Enhancement: Added JSON plugin environment checks for App server and Agent components that verify if plugin requirements, specified in
the plugin definition, for OS, CPU, endpoints are satisfied.

## 1.15.0

- Bugfix: Fixed desktop prompting for session renewal and failure due to sso-auth plugin incorrectly stating that session refresh is possible when using Zowe SSO. In reality, the SSO tokens are non-renewable with expiration after several hours, leading to a prompt to re-authenticate to continue using the Desktop. This bugfix should now allow for that behavior.
Expand Down
15 changes: 12 additions & 3 deletions lib/assets/i18n/log/messages_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@
"ZWED0293I":"Handling scan plugin request from worker=%d",
"ZWED0294I":"Successfully loaded %d recognizers for '%s' into config",
"ZWED0295I":"Successfully loaded %d actions for '%s' into config",

"ZWED0296I": "(%s) is a supported platform for %s to install (%s).",
"ZWED0297I": "(%s) is a supported architecture for %s to install (%s).",
"ZWED0298I": "(%s) is a supported endpoint for %s to install (%s).",

"ZWED0003W":"%s: Session security call %s failed for auth handler %s. Plugin response: %s",
"ZWED0004W":"Tomcat for ID=%s not starting, no services succeeded loading",
"ZWED0005W":"",
Expand Down Expand Up @@ -292,7 +295,10 @@
"ZWED0170W":"Plugin (%s) loading failed. Message: \"%s\"",
"ZWED0171W":"Rejected undefined referrer for url=%s, ip=%s",
"ZWED0172W":"Rejected bad referrer=%s for url=%s, ip=%s",

"ZWED0173W":"Unable to decode P12 certificate (different password than keystore?). Attempting to use empty string as password. Decode error: %s.",
"ZWED0174W":"%s could not verify (%s) as a supported platform to install (%s). Proceeding anyway...",
"ZWED0175W":"%s could not verify (%s) as a supported architecture to install (%s). Proceeding anyway...",

"ZWED0001E":"RESERVED: Error: %s",
"ZWED0002E":"Could not stop language manager for types=%s",
"ZWED0003E":"Loopback configuration not valid,%s\nLoopback calls will fail!",
Expand Down Expand Up @@ -358,5 +364,8 @@
"ZWED0149E":"SAF keyring reference missing userId \"%s\", keyringName \"%s\", or label \"%s\"",
"ZWED0150E":"Cannot load SAF keyring due to missing keyring_js library",
"ZWED0151E":"RESERVED: Env var %s not found",
"ZWED0152E":"Unable to locate server config instance location and INSTANCE_DIR environment variable does not exist."
"ZWED0152E":"Unable to locate server config instance location and INSTANCE_DIR environment variable does not exist.",
"ZWED0153E":"RESERVED: (%s) is not a supported platform for %s. Skipping (%s)... Supported: %s",
"ZWED0154E":"RESERVED: (%s) is not a supported architecture for %s. Skipping (%s)... Supported: %s",
"ZWED0155E":"RESERVED: (%s) is not a supported endpoint for %s. Skipping (%s)... Supported: %s"
}
2 changes: 1 addition & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ Server.prototype = {
});
}
}, installLogger));
this.pluginLoader.loadPlugins();
yield this.pluginLoader.loadPlugins();
yield this.authManager.loadAuthenticators(this.userConfig, Object.assign({},this.webServer.getTlsOptions()));
this.authManager.validateAuthPluginList();
this.processManager.addCleanupFunction(function() {
Expand Down
325 changes: 264 additions & 61 deletions lib/plugin-loader.js

Large diffs are not rendered by default.

36 changes: 34 additions & 2 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const ipaddr = require('ipaddr.js');
const dns = require('dns');
const dnsLookup = Promise.promisify(dns.lookup);
const mergeUtils = require('../utils/mergeUtils');
const forge = require('node-forge');

const loggers = {
bootstrapLogger: global.COM_RS_COMMON_LOGGER.makeComponentLogger("_zsf.bootstrap"),
Expand Down Expand Up @@ -147,11 +148,42 @@ module.exports.getOrInit = function(obj, key, dflt) {
return value;
};

module.exports.readFilesToArray = function(fileList) {
module.exports.readFilesToArray = function(fileList, type) {
var contentArray = [];
fileList.forEach(function(filePath) {
try {
contentArray.push(fs.readFileSync(filePath));
let extension = filePath.split('.').pop();
let content = fs.readFileSync(filePath);
if(extension == 'p12' || extension == 'pfx'){
let p12Der = forge.util.decode64(content.toString('base64'));
let p12Asn1 = forge.asn1.fromDer(p12Der);
let p12;
try {
p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, process.env.KEYSTORE_PASSWORD || "");
} catch (e1) {
loggers.bootstrapLogger.warn("ZWED0173W", e1.message);
p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, "");
}
const certData = p12.getBags({bagType: forge.pki.oids.certBag})[forge.pki.oids.certBag];
const keyData = p12.getBags({bagType: forge.pki.oids.pkcs8ShroudedKeyBag})[forge.pki.oids.pkcs8ShroudedKeyBag];
if(certData != undefined && type != 1 && type != 3){ //CRLs not currently supported by node forge
for(let i = 0; i < certData.length; i++){
let certObj = certData[i];
contentArray.push(Buffer.from(forge.pki.certificateToPem(certObj.cert), 'utf8'));
}
}
if(keyData != undefined && type == 1){
for(let i = 0; i < keyData.length; i++){
const rsaPrivateKey = forge.pki.privateKeyToAsn1(keyData[i].key);
const privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
let privateKeyPem = forge.pki.privateKeyInfoToPem(privateKeyInfo);
var buf = Buffer.from(privateKeyPem, 'utf8');
contentArray.push(buf);
}
}
} else {
contentArray.push(content);
}
} catch (e) {
loggers.bootstrapLogger.warn("ZWED0052W", filePath, e.message); //loggers.bootstrapLogger.warn('Error when reading file='+filePath+'. Error='+e.message);
}
Expand Down
90 changes: 61 additions & 29 deletions lib/webapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,25 +245,52 @@ const release = os.release();
const cpus = os.cpus();
const hostname = os.hostname();

function getUserEnv(){
function getUserEnv(rbac){
var date = new Date();
return new Promise(function(resolve, reject){
resolve({
"timestamp": date.toUTCString(),
"args": process.argv,
"nodeArgs": process.execArgv,
"platform": process.platform,
"arch": arch,
"osRelease": release,
"cpus": cpus,
"freeMemory": os.freemem(),
"hostname": hostname,
"userEnvironment": process.env,
"PID": process.pid,
"PPID": process.ppid,
"nodeVersion": process.version,
"nodeRelease": process.release,
})
if (rbac) {
resolve({
"timestamp": date.toUTCString(),
"args": process.argv,
"nodeArgs": process.execArgv,
"platform": process.platform,
"arch": arch,
"osRelease": release,
"cpus": cpus,
"freeMemory": os.freemem(),
"hostname": hostname,
"userEnvironment": process.env,
"PID": process.pid,
"PPID": process.ppid,
"nodeVersion": process.version,
"nodeRelease": process.release,
})
} else { //shorter list for security. limit exposure.
resolve({
//needed for sync check
"timestamp": date.toUTCString(),
//needed to do dependency checks
"platform": process.platform,
"arch": arch,
//needed for any cross-server communication requirements
"userEnvironment": {
"EXTERNAL_COMPONENTS": process.env.EXTERNAL_COMPONENTS,
"LAUNCH_COMPONENT_GROUPS": process.env.LAUNCH_COMPONENT_GROUPS,
"ZWED_node_mediationLayer_enabled": process.env.ZWED_node_mediationLayer_enabled,

//expected to be identical
"ZOWE_EXPLORER_HOST": process.env.ZOWE_EXPLORER_HOST,
"ZWED_node_mediationLayer_server_hostname": process.env.ZWED_node_mediationLayer_server_hostname,

//may diverge from above
"ZWE_EXTERNAL_HOSTS": process.env.ZWE_EXTERNAL_HOSTS,

//expected to be identical
"ZWED_node_mediationLayer_server_gatewayPort": process.env.ZWED_node_mediationLayer_server_gatewayPort,
"GATEWAY_PORT": process.env.GATEWAY_PORT
}
})
}
});
}

Expand Down Expand Up @@ -412,7 +439,9 @@ const staticHandlers = {
loader.once('refreshFinish', (event) => {
respondToGetPlugins(req, res, webapp, type, webapp.plugins);
});
loader.installPlugins(defs);
loader.installPlugins(defs).then( () => {
return;
});
}
});
}
Expand Down Expand Up @@ -461,8 +490,18 @@ const staticHandlers = {
});
const dataserviceAuth = options.serverConfig["dataserviceAuthentication"];
const rbac = (dataserviceAuth == undefined) ? false : dataserviceAuth.rbac === true;
//endpoints that handle rbac decision-making within
router.get('/environment', function(req, res){
getUserEnv(rbac).then(result => {
res.status(200).json(result);
});
}).all('/environment', function (req, res) {
return res.status(405).json({error: 'ZWED0130E - Only GET method supported'});
});

//per-endpoint rbac behavior follows
if(!rbac){
router.use('/*', (req, res) => {
router.all('/*', (req, res) => {
return res.status(506).send("Set dataserviceAuthentication.rbac to true in server configuration");
})
return router;
Expand Down Expand Up @@ -654,13 +693,6 @@ const staticHandlers = {
}).all('/logLevels/name/:componentName/level/:level', function (req, res) {
return res.status(405).json({error: 'ZWED0129E - Only POST method supported'});
});
router.get('/environment', function(req, res){
getUserEnv().then(result => {
res.status(200).json(result);
});
}).all('/environment', function (req, res) {
return res.status(405).json({error: 'ZWED0130E - Only GET method supported'});
});
return router;
}
},
Expand Down Expand Up @@ -1366,6 +1398,7 @@ WebApp.prototype = {

installRootServices() {
const serviceHandleMap = {};
const rootServicesMiddleware = commonMiddleware.injectServiceHandles(serviceHandleMap, true);
for (const proxiedRootService of this.options.rootServices || []) {
const name = proxiedRootService.name || proxiedRootService.url.replace("/", "");
installLog.info(`ZWED0055I`, proxiedRootService.url); //installLog.info(`installing root service proxy at ${proxiedRootService.url}`);
Expand All @@ -1385,13 +1418,12 @@ WebApp.prototype = {
const _router = this.makeProxy(proxiedRootService.url, false,
getAgentProxyOptions(this.options, this.options.serverConfig.agent));
middlewareArray.push(_router);
this.expressApp.use(proxiedRootService.url, this.auth.middleware, middlewareArray);
this.expressApp.use(proxiedRootService.url, rootServicesMiddleware, this.auth.middleware, middlewareArray);
}
serviceHandleMap[name] = new WebServiceHandle(proxiedRootService.url,
this.wsEnvironment);
}
this.expressApp.use(commonMiddleware.injectServiceHandles(serviceHandleMap,
true));
this.expressApp.use(rootServicesMiddleware);

this._installRootService('/auth', 'post', this.auth.doLogin,
{needJson: true, needAuth: false, isPseudoSso: true});
Expand Down
2 changes: 1 addition & 1 deletion lib/webserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ function loadPem(locations, type, keyrings) {
}
const files = locationsByType['file'];
if (files) {
content = util.readFilesToArray(files).concat(content);
content = util.readFilesToArray(files, type).concat(content);
}
return {content, keyrings};
}
Expand Down
11 changes: 8 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"js-yaml": "~3.13.1",
"mkdirp": "~0.5.1",
"ncp": "~2.0.0",
"node-forge": "^0.10.0",
"normalize-url": "~4.3.0",
"require-from-string": "~2.0.2",
"rimraf": "~2.6.3",
Expand Down
4 changes: 2 additions & 2 deletions utils/install-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ function copyRecognizers(appDir, appId, appVers) {
let instanceDir = JSON.parse(fs.readFileSync(userInput.zluxConfig)).instanceDir;
configLocation = path.join(instanceDir, "/ZLUX/pluginStorage/org.zowe.zlux.ng2desktop/");
} catch (e) {
logger.error('ZWED0152E'); //logger.error('Unable to locate server config instance location and INSTANCE_DIR environment variable does not exist.')
logger.severe('ZWED0152E'); //logger.error('Unable to locate server config instance location and INSTANCE_DIR environment variable does not exist.')
}
}

Expand Down Expand Up @@ -229,7 +229,7 @@ function copyActions(appDir, appId, appVers) {
let instanceDir = JSON.parse(fs.readFileSync(userInput.zluxConfig)).instanceDir;
configLocation = path.join(instanceDir, "/ZLUX/pluginStorage/org.zowe.zlux.ng2desktop/");
} catch (e) {
logger.error('ZWED0152E'); //logger.error("Unable to locate server config instance location and INSTANCE_DIR environment variable does not exist.")"
logger.severe('ZWED0152E'); //logger.error("Unable to locate server config instance location and INSTANCE_DIR environment variable does not exist.")"
}
}

Expand Down

0 comments on commit e21c360

Please sign in to comment.