Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ jobs:
with:
manifest-file-path: ${{ github.workspace }}/manifest.json
default-target-path: .pax/binaryDependencies/
expected-count: 33
expected-count: 34

# this step is not doing a publish, we are just utilizing this actions to get the PUBLISH_TARGET_PATH,
# and it will be used in the next step: [Download 3] Download SMPE build log
Expand Down
5 changes: 5 additions & 0 deletions .pax/pre-packaging.sh
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,11 @@ echo "[$SCRIPT_NAME] move certificate_analyser $certificate_analyser"
mkdir -p "${ZOWE_ROOT_DIR}/bin/utils"
mv "${certificate_analyser}" "${ZOWE_ROOT_DIR}/bin/utils/certificate-analyser.jar"

zosmf_jwt_check=$(find "${ZOWE_ROOT_DIR}/files" -type f \( -name "zosmf-jwt-check*.jar" \) | head -n 1)
echo "[$SCRIPT_NAME] move zosmf_jwt_check $zosmf_jwt_check"
mkdir -p "${ZOWE_ROOT_DIR}/bin/utils"
mv "${zosmf_jwt_check}" "${ZOWE_ROOT_DIR}/bin/utils/zosmf-jwt-check.jar"


echo "[$SCRIPT_NAME] create dummy zowe.yaml for install"
cat <<EOT >>"${BASE_DIR}/zowe.yaml"
Expand Down
1 change: 1 addition & 0 deletions .pax/prepare-workspace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ mv *.pax.Z "${CONTENT_DIR}/files/"
mv *.pax "${CONTENT_DIR}/files/"
mv *.zip "${CONTENT_DIR}/files/"
mv certificate-analyser-* "${CONTENT_DIR}/files/"
mv zosmf-jwt-check-* "${CONTENT_DIR}/files/"
# PAX_BINARY_DEPENDENCIES should be empty now
if [ -n "$(ls -1)" ]; then
echo "[$SCRIPT_NAME] Error: binaryDependencies directory is not clean"
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
All notable changes to the Zowe Installer will be documented in this file.

## `3.5.0`

- Enhancement: Added command `zwe validate zosmf jwt` which checks whether a Zowe configured to use z/OSMF is able to use z/OSMF's JWT authentication method or not. This command runs every startup if the conditions are met, but can be disabled or turned into only a warning via YAML property `zowe.launchScript.startupChecks.zosmfjwt` being set to "warn" or "disabled". [#4727](https://github.com/zowe/zowe-install-packaging/pull/4727)
- Enhancement: Split `zwe components install` into subcommands with dry-run options to help you with each step of component installation. [#4582](https://github.com/zowe/zowe-install-packaging/pull/4582)
- Enhancement: Added command `zwe vadlidate certificate` which checks Zowe's keystore and truststore and reports action items to resolve any issues found. This is run automatically every Zowe setup but that can be changed via the parameter `zowe.launchScript.startupChecks.certificate`, which can be changed to "warn" to warn only, or "disabled" to bypass the check. [#4554](https://github.com/zowe/zowe-install-packaging/pull/4554)
- Enhancement: `zwe version` supports displaying Zowe version defined in the configuration. [#4322](https://github.com/zowe/zowe-install-packaging/pull/4322)
Expand Down
5 changes: 5 additions & 0 deletions bin/commands/.errors
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,8 @@ ZWEL0322E|322|%s is not a valid directory.
ZWEL0323E|323|Certificate validation failed. Fix errors listed before starting Zowe.
ZWEL0326E|326|An error occurred while processing Zowe YAML config %s:
ZWEL0327E|327|Failed to read %s - %s.
ZWEL0359E|359|z/OSMF host (zosmf.host) or port (zosmf.port) is not configured in the Zowe YAML. Cannot validate z/OSMF JWT support without a z/OSMF destination.
ZWEL0360E|360|Neither components.discovery.enabled nor components.apiml.enabled is set to true. The required APIML servers are not enabled for z/OSMF access.
ZWEL0361W||z/OSMF JWT check failed (rc=%s) but jwtAutoconfiguration is 'ltpa', so JWT support is not required for this Zowe configuration.
ZWEL0362E|362|z/OSMF JWT check failed (rc=%s). Zowe requires z/OSMF JWT support (jwtAutoconfiguration is 'jwt') but it is not working.

9 changes: 9 additions & 0 deletions bin/commands/internal/start/prepare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as node from '../../../../libs/node';
import * as zosmf from '../../../../libs/zosmf';
import * as zoslib from '../../../../libs/zos';
import * as validateBind from '../../../validate/port/bind/index';
import * as validateZosmfJwt from '../../../validate/zosmf/jwt/index';
import * as validateCertificate from '../../../validate/certificate/index';

//# This command prepares everything needed to start Zowe.
Expand Down Expand Up @@ -217,6 +218,14 @@ function globalValidate(enabledComponents:string[]): void {
privateErrors++;
common.printFormattedError('ZWELS', "zwe-internal-start-prepare,global_validate", "Zosmf validation failed");
}
const validateZosmfJwtAction = getStartupCheckMode('zosmfjwt');
if (validateZosmfJwtAction.doCheck) {
const jwtRc = validateZosmfJwt.execute(!validateZosmfJwtAction.warnOnly);
if (jwtRc !== 0) {
privateErrors++;
common.printFormattedError('ZWELS', "zwe-internal-start-prepare,global_validate", "Zosmf JWT validation failed");
}
}
} else if (enabledComponents.includes('gateway') && std.getenv('ZWE_components_gateway_apiml_security_auth_provider') == "zosmf") {
privateErrors++;
common.printError("Using z/OSMF as 'components.gateway.apiml.security.auth.provider' is not possible: discovery is disabled.");
Expand Down
4 changes: 4 additions & 0 deletions bin/commands/validate/zosmf/jwt/.errors
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ZWEL0359E|359|z/OSMF host (zosmf.host) or port (zosmf.port) is not configured in the Zowe YAML. Cannot validate z/OSMF JWT support without a z/OSMF destination.
ZWEL0360E|360|Neither components.discovery.enabled nor components.apiml.enabled is set to true. The required APIML servers are not enabled for z/OSMF access.
ZWEL0361W||z/OSMF JWT check failed (rc=%s) but jwtAutoconfiguration is 'ltpa', so JWT support is not required for this Zowe configuration.
ZWEL0362E|362|z/OSMF JWT check failed (rc=%s). Zowe requires z/OSMF JWT support (jwtAutoconfiguration is 'jwt') but it is not working.
3 changes: 3 additions & 0 deletions bin/commands/validate/zosmf/jwt/.examples
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zwe validate zosmf jwt -c /path/to/zowe.yaml
zwe validate zosmf jwt -c 'FILE(/customizations/zowe.yaml):FILE(/defaults/zowe.yaml)'
zwe validate zosmf jwt -c 'FILE(/path/to/zowe.yaml):PARMLIB(ZOWE.PARMLIB(YAML))'
17 changes: 17 additions & 0 deletions bin/commands/validate/zosmf/jwt/.help
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Checks whether z/OSMF JWT support is correctly configured and operational when Zowe is set
to use z/OSMF as the authentication provider with JWT autoconfiguration.

This command reads the Zowe YAML configuration to determine whether the check is applicable,
then invokes the zosmf-jwt-check.jar utility to probe z/OSMF for JWT support.

If Zowe is not configured to use z/OSMF as the authentication provider, the check succeeds
immediately with an informational message.

If jwtAutoconfiguration is 'ltpa' and the check fails, a warning is issued but the command
still exits successfully, because LTPA does not require z/OSMF JWT support.

If jwtAutoconfiguration is 'jwt' and the check fails, the command exits with an error and
provides detailed diagnostic information.

The behavior of this check during Zowe startup can be controlled via:
zowe.launchScript.startupChecks.zosmfjwt: exit | warn | disabled
16 changes: 16 additions & 0 deletions bin/commands/validate/zosmf/jwt/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v2.0 which
accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html

SPDX-License-Identifier: EPL-2.0

Copyright Contributors to the Zowe Project.
*/
import * as index from './index';
import * as configmgr from '../../../../libs/configmgr';

index.execute(false);

configmgr.cleanupTempDir();
18 changes: 18 additions & 0 deletions bin/commands/validate/zosmf/jwt/index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh

#######################################################################
# This program and the accompanying materials are made available
# under the terms of the Eclipse Public License v2.0 which
# accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright Contributors to the Zowe Project.
#######################################################################

if [ -z "${ZWE_PRIVATE_TMP_MERGED_YAML_DIR}" ]; then
# user-facing command, use tmpdir to not mess up workspace permissions
export ZWE_PRIVATE_TMP_MERGED_YAML_DIR=1
fi
_CEE_RUNOPTS="XPLINK(ON),HEAPPOOLS(OFF),HEAPPOOLS64(OFF)" ${ZWE_zowe_runtimeDirectory}/bin/utils/configmgr -script "${ZWE_zowe_runtimeDirectory}/bin/commands/validate/zosmf/jwt/cli.js"
159 changes: 159 additions & 0 deletions bin/commands/validate/zosmf/jwt/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v2.0 which
accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html

SPDX-License-Identifier: EPL-2.0

Copyright Contributors to the Zowe Project.
*/

import * as std from 'cm_std';
import * as common from '../../../../libs/common';
import * as config from '../../../../libs/config';
import * as java from '../../../../libs/java';
import * as shell from '../../../../libs/shell';

const COMMAND_NAME = 'zwe-validate-zosmf-jwt';

export function execute(quitOnError?: boolean): number {
common.requireZoweYaml();
const ZOWE_CONFIG = config.getZoweConfig();

// Verify that zosmf.host and zosmf.port are configured.
const zosmfHost = ZOWE_CONFIG.zOSMF?.host;
const zosmfPort = ZOWE_CONFIG.zOSMF?.port;
if (!zosmfHost || !zosmfPort) {
const msg = `ZWEL0359E: z/OSMF host (zosmf.host) or port (zosmf.port) is not configured in the Zowe YAML.` +
` Cannot validate z/OSMF JWT support without a z/OSMF destination.`;
if (quitOnError) {
common.printErrorAndExit(msg, undefined, 359);
} else {
common.printFormattedError(common.MSG_KEY, COMMAND_NAME, msg);
}
return 359;
}

// Verify that at least one of the required APIML servers is enabled.
const discoveryEnabled = ZOWE_CONFIG.components?.discovery?.enabled === true;
const apimlEnabled = ZOWE_CONFIG.components?.apiml?.enabled === true;
if (!discoveryEnabled && !apimlEnabled) {
const msg = `ZWEL0360E: Neither components.discovery.enabled nor components.apiml.enabled is set to true.` +
` The required APIML servers are not enabled for z/OSMF access.`;
if (quitOnError) {
common.printErrorAndExit(msg, undefined, 360);
} else {
common.printFormattedError(common.MSG_KEY, COMMAND_NAME, msg);
}
return 360;
}

// Check whether the gateway is configured to use z/OSMF as the authentication provider.
const authProvider = ZOWE_CONFIG.components?.gateway?.apiml?.security?.auth?.provider;
if (!authProvider || authProvider.toLowerCase() !== 'zosmf') {
common.printFormattedInfo(
common.MSG_KEY,
COMMAND_NAME,
`Zowe is not configured to use z/OSMF as the authentication provider` +
` (components.gateway.apiml.security.auth.provider=${authProvider || '<not set>'}).` +
` No z/OSMF JWT check is required.`
);
return 0;
}

// Determine the jwtAutoconfiguration value to understand what mode we are in.
const jwtAutoconfigRaw = ZOWE_CONFIG.components?.gateway?.apiml?.security?.auth?.zosmf?.jwtAutoconfiguration || '';
const jwtAutoconfig = jwtAutoconfigRaw.toLowerCase();

// Ensure java is available before invoking the jar.
java.requireJava();
const javaHome = std.getenv('JAVA_HOME');
const javaExec = `${javaHome}/bin/java`;

const runtimeDir = std.getenv('ZWE_zowe_runtimeDirectory');
const jarPath = `${runtimeDir}/bin/utils/zosmf-jwt-check.jar`;

// Collect truststore parameters from the Zowe YAML.
const verifyCertificates = ZOWE_CONFIG.zowe?.verifyCertificates || 'STRICT';
const truststoreType = ZOWE_CONFIG.zowe?.certificate?.truststore?.type || '';
const truststoreFile = ZOWE_CONFIG.zowe?.certificate?.truststore?.file || '';
const truststorePassword = ZOWE_CONFIG.zowe?.certificate?.truststore?.password || '';

common.printFormattedInfo(
common.MSG_KEY,
COMMAND_NAME,
`Running z/OSMF JWT check for ${zosmfHost}:${zosmfPort} (jwtAutoconfiguration=${jwtAutoconfigRaw || '<not set>'})`
);

const result = shell.execOutErrSync(
javaExec,
'-Djava.protocol.handler.pkgs=com.ibm.crypto.provider',
'-jar', jarPath,
'--zosmf-host', zosmfHost,
'--zosmf-port', String(zosmfPort),
'--verify-certificates', verifyCertificates,
'--truststore-type', truststoreType,
'--truststore-file', truststoreFile,
'--truststore-password', truststorePassword
);

if (result.rc !== 0) {
if (jwtAutoconfig === 'ltpa') {
// LTPA mode does not require z/OSMF JWT support - treat as a warning only.
common.printFormattedWarn(
common.MSG_KEY,
COMMAND_NAME,
`ZWEL0361W: z/OSMF JWT check failed (rc=${result.rc}) but jwtAutoconfiguration is 'ltpa',` +
` so JWT support is not required for this Zowe configuration.` +
` z/OSMF JWT support may not be available.`
);
if (result.out) {
common.printDebug(result.out);
}
if (result.err) {
common.printDebug(result.err);
}
return 0;
}

// JWT mode requires z/OSMF JWT support - this is an error.
const jarOutput = [result.out, result.err].filter(Boolean).join('\n');
const errorMsg =
`ZWEL0362E: z/OSMF JWT check failed (rc=${result.rc}).` +
` Zowe requires z/OSMF JWT support (jwtAutoconfiguration is '${jwtAutoconfigRaw}') but it is not working.\n` +
`\nJar output:\n${jarOutput}\n` +
`\nZowe YAML parameters that led to this result:` +
`\n zosmf.host=${zosmfHost}` +
`\n zosmf.port=${zosmfPort}` +
`\n zowe.verifyCertificates=${verifyCertificates}` +
`\n zowe.certificate.truststore.type=${truststoreType}` +
`\n zowe.certificate.truststore.file=${truststoreFile}` +
`\n zowe.certificate.truststore.password=<redacted>` +
`\n components.gateway.apiml.security.auth.provider=${authProvider}` +
`\n components.gateway.apiml.security.auth.zosmf.jwtAutoconfiguration=${jwtAutoconfigRaw || '<not set>'}` +
`\n\nTo resolve this issue:` +
`\n Verify that z/OSMF has been configured for JWT support by reviewing:` +
`\n https://www.ibm.com/docs/en/zos/3.2.0?topic=configurations-enabling-json-web-token-support` +
`\n Also check the z/OSMF joblog for further diagnostic information.` +
`\n\nIf you do not wish to use z/OSMF JWT support, you can instead change:` +
`\n components.gateway.apiml.security.auth.zosmf.jwtAutoconfiguration to 'ltpa'` +
`\n\nIf you believe this validate command is incorrect, you can set it to a warning or disable it:` +
`\n zowe.launchScript.startupChecks.zosmfjwt: warn (report as warning, continue startup)` +
`\n zowe.launchScript.startupChecks.zosmfjwt: disabled (skip this check entirely)`;

if (quitOnError) {
common.printErrorAndExit(errorMsg, undefined, 362);
} else {
common.printFormattedError(common.MSG_KEY, COMMAND_NAME, errorMsg);
}
return result.rc;
}

common.printFormattedInfo(
common.MSG_KEY,
COMMAND_NAME,
`z/OSMF JWT check passed. z/OSMF at ${zosmfHost}:${zosmfPort} supports JWT.`
);
return 0;
}
2 changes: 2 additions & 0 deletions files/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ zowe:
# zosmf: exit
# # Superuser startup check - defaults to zowe.launchScript.startupChecks.default, or "exit" if this is unset
# user: exit
# z/OSMF JWT support check - checks whether z/OSMF JWT support is usable when Zowe is configured to use it
# zosmfjwt: exit
# # Certificate (zowe.certificate) validation check - defaults to zowe.launchScript.startupChecks.default, or "exit" if this is unset
# certificate: exit

Expand Down
46 changes: 21 additions & 25 deletions manifest.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -61,53 +61,49 @@
"artifact": "*.pax"
},
"org.zowe.apiml.apiml-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "apiml-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "apiml-*.zip"
},
"org.zowe.apiml.api-catalog-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "api-catalog-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "api-catalog-*.zip"
},
"org.zowe.apiml.discovery-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "discovery-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "discovery-*.zip"
},
"org.zowe.apiml.gateway-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "gateway-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "gateway-*.zip"
},
"org.zowe.apiml.caching-service-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "caching-service-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "caching-service-*.zip"
},
"org.zowe.apiml.apiml-common-lib-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "apiml-common-lib-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "apiml-common-lib-*.zip"
},
"org.zowe.apiml.sdk.common-java-lib-package": {
"version": "^2.0.0-SNAPSHOT",
"artifact": "common-java-lib-*.zip",
"exclusions": ["*PR*.zip"]
},
"org.zowe.apiml.sdk.apiml-sample-extension-package": {
"version": "^3.0.3-SNAPSHOT",
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "apiml-sample-extension-*.zip"
},
"org.zowe.apiml.zaas-package": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "zaas-package-*.zip",
"exclusions": ["*PR*.zip"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "zaas-package-*.zip"
},
"org.zowe.apiml.sdk.certificate-analyser": {
"version": "^3.0.3-SNAPSHOT",
"artifact": "certificate-analyser-*.jar",
"exclusions": ["*PR*.jar"]
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "certificate-analyser-*.jar"
},
"org.zowe.apiml.sdk.zosmf-jwt-check": {
"version": "^3.5.13-PR-fixed-Preflight-SNAPSHOT",
"artifact": "zosmf-jwt-check-*.jar"
},
"org.zowe.getesm": {
"version": "^3.0.0-V3.X-STAGING",
Expand Down
5 changes: 5 additions & 0 deletions schemas/zowe-yaml-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,11 @@
"$ref": "/schemas/v2/server-common#startupCheck",
"default": "exit",
"description": "Checks if zowe.setup.security.users.zowe (ZWESVUSR) is configured as a superuser (UID 0). Such a setting is strongly discouraged."
},
"zosmfjwt": {
"$ref": "/schemas/v2/server-common#startupCheck",
"default": "exit",
"description": "Checks whether z/OSMF JWT support is correctly configured when Zowe is set to use z/OSMF as the authentication provider with JWT autoconfiguration. Can be set to 'exit', 'warn', or 'disabled'."
}
}
}
Expand Down
Loading