zowe / zowe-cli

Zowe CLI
Eclipse Public License 2.0
116 stars 86 forks source link

ClI commands fail with bad CredMgr, daemon does not #1629

Open gejohnston opened 1 year ago

gejohnston commented 1 year ago

Describe the bug

When you have a bad credential manager, CLI commands are expected to fail. The CLI fails, but the daemon does not.

Expected and actual results

Establish a configuration like this:

The CLI displays a error upon startup. It prompts for credentials, but then fails when the operation is performed because we have an invalid credential manager. Note that the error message text below has been changed from our GA version, but the operational logic was not changed. All of the error information was also logged to the imperative log. Running the command multiple times gives the same result.

> zowe zos-files list data-set "SYS1.PARMLIB*"
[2023/02/14 10:52:58.365] [ERROR] [CredentialManagerFactory.js:149] Failed to load the credential manager named "BogusCredentialManager"
[2023/02/14 10:52:58.386] [ERROR] [CredentialManagerFactory.js:151] The "CredentialManager" setting named "BogusCredentialManager" is not installed and loadable. We will fallback to the default CredentialManager named "@zowe/cli" until you reconfigure. You can edit the "CredentialManager" value in $ZOWE_CLI_HOME/settings/imperative.json to contain one of these values:
"CredentialManager": "@zowe/cli" (default)
"CredentialManager": "Kubernetes Secrets" (supplied in CLI plugin @zowe/secrets-for-kubernetes-for-zowe-cli
                                           and in ZE extension Zowe.secrets-for-kubernetes)

Enter the user name for your service (will be hidden):
Enter the password for your service (will be hidden):
Command Error:
An invalid credential manager was passed in to the factory function!

With daemon mode, the first command starts the daemon, encounters the BogusCredentialManager, logs a detailed error, displays a brief error, and does not perform the desired action. This is consistent with the plain CLI commands.

> zowex zos-files list data-set "SYS1.PARMLIB*"
Starting a background process to increase performance ...
Enter the user name for your service (will be hidden):
Enter the password for your service (will be hidden):
Command Error:
An invalid credential manager was passed in to the factory function!

Additional daemon commands never prompt, log no errors, display no errors, and successfully run the command against the mainframe. It remembers the user and password, even though they were never stored in the Windows Credential Manager. This is inconsistent with the plain CLI.

> zowex zos-files list data-set "SYS1.PARMLIB*"
SYS1.PARMLIB
SYS1.PARMLIB.ARCHIVE
SYS1.PARMLIB.OLD
SYS1.PARMLIBN

After all of these commands, BogusCredentialManager remains in settings/imperative.json and no Zowe/secure_config_props entry exists in Windows Credential Manager.

Because the daemon hides the fact that you have a bad credential manager, it could lure a user into thinking that the credentials have been securely stored, even though they have not been stored. The next time the daemon is started this cycle repeats. The CLI will prompt for credentials the first time and fail, then not prompt on future commands, but run successfully.

This could be a source of confusion and lead the user to open misleading issues against Zowe CLI.

Describe your environment

zowe config report-env


Zowe CLI version = 7.10.2 Node.js version = 16.17.0 Node Version Manager version = 1.1.9 O.S. platform = win32 O.S. architecture = x64

O.S. PATH = C:\Program Files\PowerShell\7;C:\Program Files\ConEmu\ConEmu\Scripts;C:\Program Files\ConEmu;C:\Program Files\ConEmu\ConEmu;.\;c:\pkgs\cmds\winScr;c:\pkgs\cmds\workScr;c:\pkgs\cmds\bin;C:\ourstuff\records\Broadcom\zowe\cmds;C:\Program Files\PowerShell\7;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\pkgs\java\jdk\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin;C:\Program Files\doxygen\bin;C:\pkgs\Ruby25-x64\bin;C:\ProgramData\chocolatey\bin;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\Box\Box Edit\;C:\Program Files (x86)\Symantec\VIP Access Client\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\dotnet\;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Program Files (x86)\GitExtensions\;C:\Program Files\PowerShell\7\;C:\pkgs\cargo\bin;C:\Users\ej608771\AppData\Local\Microsoft\WindowsApps;C:\pkgs\nvm;C:\pkgs\nodejs

ZOWE_CLI_HOME = undefined Default = C:\Users\ej608771.zowe ZOWE_APP_LOG_LEVEL = undefined ZOWE_IMPERATIVE_LOGLEVEL = undefined No other 'ZOWE' variables have been set.


NPM information:

NPM version = 8.15.0
Shell = C:\WINDOWS\system32\cmd.exe
Global prefix = C:\pkgs\nodejs
    The directory above contains the Zowe Node.js command script.
Global root node modules = C:\pkgs\nodejs\node_modules
Global config = C:\pkgs\nodejs\etc\npmrc
Local prefix = C:\ourstuff\repos\zowe-cli
Local root node modules = C:\ourstuff\repos\zowe-cli\node_modules
User config = C:\Users\ej608771\.npmrc

@broadcom:registry = "https://registry.npmjs.org/"
; @zowe:registry = "https://registry.npmjs.org/" ; overridden by project
registry = "https://registry.npmjs.org/"
"project" config from C:\ourstuff\repos\zowe-cli\.npmrc
@zowe:registry = "https://zowe.jfrog.io/zowe/api/npm/npm-local-release/"
node bin location = C:\pkgs\nodejs\node.exe
cwd = C:\ourstuff\repos\zowe-cli\zowex\target\debug
HOME = C:\Users\ej608771

Zowe CLI configuration information:

Zowe daemon mode = off
Zowe config type = V2 Team Config
Team config files in effect:
    C:\Users\ej608771\.zowe\zowe.config.json
Default profile names:
    base =     base_plain_pass
    zosmf =    ca32
    jclcheck = de20.jck
    tso =      ca11.tso_ca11
    mat =      mat_ca31
Available profile names:
    base_plain_pass
    base_secure_pass
    base_apiml_secure_token
    ca11
    ca11.tso_ca11
    ca31
    ca32
    ca32.jck
    ca32_apiml
    ca32_apiml.jck
    tso1
    de16
    de16.jck
    de20
    de20.jck
    mat_ca31
    mstrbrs
    sr01brs
    xe61

Installed plugins:

@broadcom/qwikref-for-zowe-cli
    Version = 1.0.1
    Package = C:\ourstuff\repos\plugins\qwikref-cli

@zowe/zos-ftp-for-zowe-cli
    Version = 2.1.0
    Package = @zowe/zos-ftp-for-zowe-cli@2.1.0

Additional context

github-actions[bot] commented 1 year ago

Thank you for creating a bug report. We will investigate the bug and evaluate its impact on the product. If you haven't already, please ensure you have provided steps to reproduce the bug and as much context as possible.

gejohnston commented 1 year ago

A theory on the cause of this behavior is that when a user is prompted for credentials, those properties are added to the the IHandlerParameters.arguments that are passed to a command handler. For each normal zowe command, you start a new process and have a clean slate.

With the daemon, our process stays around. It is possible that the IHandlerParameters are not cleared out after a command is processed, so the next command already has the properties for user and password available. If so, it would explain why the daemon does not prompt again (it already has values for user and password). It also explains why no "bad cred mgr" errors are reported (since the command already has user and password, there is no reason to load the secure credential store).

None of this theory has been confirmed in the code. It simply explains the behavior that has been observed, so it is a good place to start troubleshooting the problem.