From 4280e5d6a00e1fe29ecda682bd0241729b770c8e Mon Sep 17 00:00:00 2001 From: Bertrand Martin Date: Sun, 25 Oct 2026 21:54:00 +0100 Subject: [PATCH 1/3] Document that the Windows launcher alters values with cmd.exe metacharacters (#219) The ipmicli.cmd shim runs through cmd.exe, which expands %NAME%, drops ^ and runs what follows an unquoted &, |, < or > before the CLI sees its arguments, from PowerShell as well. Until the launcher is replaced, the cli.md password section, the installation page and the installer's closing message tell Windows users to give such a password at the prompt or with -pf, and such a path or name through java -jar. Co-Authored-By: Claude Fable 5.1 --- src/site/markdown/cli.md | 8 ++++++++ src/site/markdown/installation.md | 4 +++- src/site/resources/get.ps1 | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/site/markdown/cli.md b/src/site/markdown/cli.md index aa930ffa..7d8e3954 100644 --- a/src/site/markdown/cli.md +++ b/src/site/markdown/cli.md @@ -182,6 +182,14 @@ character of a `-p` or `-u` value that this code page lacks (Cyrillic or CJK on European system, for instance) reaches the CLI as `?`, and the BMC refuses the login. Put such a password in a UTF-8 file and pass it with `-pf`. +The Windows launcher is a batch file, so `cmd.exe` parses the command line before the CLI sees +it, from PowerShell as well: `%NAME%` is replaced by the variable, `^` is dropped, and `&`, `|`, +`<` and `>` end the arguments and run what follows as a command (`-p 'a&ver'` logs in with `a`, +then runs `ver`). A `-p`, `-u`, `--name` or `-pf` value that contains one of these characters +(`C:\R&D\pw.txt`) therefore does not reach the CLI as typed. Give such a password at the prompt +or in a file with `-pf`, and such a path or name through `java -jar`, which receives every value +unchanged. + Secrets are never printed: not in the usage errors, not with `--verbose`, not in the failure messages. The CLI wipes its copies of the password and of the key when it ends, but a `-p` or `-k` value stays in memory as text that the CLI cannot wipe (the JVM keeps its command line in the diff --git a/src/site/markdown/installation.md b/src/site/markdown/installation.md index 7efb05ad..f737cdde 100644 --- a/src/site/markdown/installation.md +++ b/src/site/markdown/installation.md @@ -81,7 +81,9 @@ installer runs in Windows PowerShell 5.1 and PowerShell 7. Neither installer nee The launcher finds a Java runtime, 8 or later, each time it runs: `IPMICLI_JAVA_HOME`, then `JAVA_HOME`, then `java` on the `PATH` (on Linux and macOS, then `/usr/libexec/java_home`, sdkman and `/usr/lib/jvm`). Installing or upgrading Java needs no reinstallation. Without a suitable -runtime, it exits with code 127 and points to [Adoptium](https://adoptium.net). +runtime, it exits with code 127 and points to [Adoptium](https://adoptium.net). The Windows +launcher is a batch file: a value that contains `%`, `^`, `&`, `|`, `<` or `>` does not reach +`ipmicli` as typed (see [Passwords and BMC key](cli.html#passwords-and-bmc-key)). ```shell-session $ ipmicli --version diff --git a/src/site/resources/get.ps1 b/src/site/resources/get.ps1 index 09b94566..38341aad 100644 --- a/src/site/resources/get.ps1 +++ b/src/site/resources/get.ps1 @@ -146,6 +146,8 @@ $shim | Set-Content -Path $shimPath -Encoding ASCII Write-Host "Installed the IPMI Java Client jar to $jarPath" Write-Host "Installed the ipmicli launcher to $shimPath" +Write-Host 'The launcher is a batch file: a value with % ^ & | < or > does not reach ipmicli as typed.' +Write-Host 'Give such a password at the prompt or in a file (-pf).' # --- PATH registration ----------------------------------------------------------- From ae5fdb3988b6460110823d18be312b4be155d35f Mon Sep 17 00:00:00 2001 From: Bertrand Martin Date: Sun, 25 Oct 2026 22:01:04 +0100 Subject: [PATCH 2/3] Qualify the launcher caveat by quoting (#219 review) Only a %NAME% reference expands everywhere; ^ & | < > are altered outside double quotes, which PowerShell adds only around a value with a space. Co-Authored-By: Claude Fable 5.1 --- src/site/markdown/cli.md | 14 ++++++++------ src/site/markdown/installation.md | 5 +++-- src/site/resources/get.ps1 | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/site/markdown/cli.md b/src/site/markdown/cli.md index 7d8e3954..13d669bc 100644 --- a/src/site/markdown/cli.md +++ b/src/site/markdown/cli.md @@ -183,12 +183,14 @@ European system, for instance) reaches the CLI as `?`, and the BMC refuses the l password in a UTF-8 file and pass it with `-pf`. The Windows launcher is a batch file, so `cmd.exe` parses the command line before the CLI sees -it, from PowerShell as well: `%NAME%` is replaced by the variable, `^` is dropped, and `&`, `|`, -`<` and `>` end the arguments and run what follows as a command (`-p 'a&ver'` logs in with `a`, -then runs `ver`). A `-p`, `-u`, `--name` or `-pf` value that contains one of these characters -(`C:\R&D\pw.txt`) therefore does not reach the CLI as typed. Give such a password at the prompt -or in a file with `-pf`, and such a path or name through `java -jar`, which receives every value -unchanged. +it, from PowerShell as well. A `%NAME%` reference is replaced by the variable wherever it is; +outside double quotes, `^` is dropped and `&`, `|`, `<` and `>` end the arguments and run what +follows as a command (`-p 'a&ver'` logs in with `a`, then runs `ver`). PowerShell puts double +quotes only around a value that contains a space, so a `-p`, `-u`, `--name` or `-pf` value with +one of these characters and no space (`C:\R&D\pw.txt`) does not reach the CLI as typed; from +`cmd.exe`, a value in double quotes is safe except for `%NAME%`. Give such a password at the +prompt or in a file with `-pf`, and such a path or name through `java -jar`, which receives every +value unchanged. Secrets are never printed: not in the usage errors, not with `--verbose`, not in the failure messages. The CLI wipes its copies of the password and of the key when it ends, but a `-p` or diff --git a/src/site/markdown/installation.md b/src/site/markdown/installation.md index f737cdde..80336c36 100644 --- a/src/site/markdown/installation.md +++ b/src/site/markdown/installation.md @@ -82,8 +82,9 @@ The launcher finds a Java runtime, 8 or later, each time it runs: `IPMICLI_JAVA_ `JAVA_HOME`, then `java` on the `PATH` (on Linux and macOS, then `/usr/libexec/java_home`, sdkman and `/usr/lib/jvm`). Installing or upgrading Java needs no reinstallation. Without a suitable runtime, it exits with code 127 and points to [Adoptium](https://adoptium.net). The Windows -launcher is a batch file: a value that contains `%`, `^`, `&`, `|`, `<` or `>` does not reach -`ipmicli` as typed (see [Passwords and BMC key](cli.html#passwords-and-bmc-key)). +launcher is a batch file: a `%NAME%` reference, and `^`, `&`, `|`, `<` or `>` outside double +quotes, do not reach `ipmicli` as typed (see +[Passwords and BMC key](cli.html#passwords-and-bmc-key)). ```shell-session $ ipmicli --version diff --git a/src/site/resources/get.ps1 b/src/site/resources/get.ps1 index 38341aad..77903b1b 100644 --- a/src/site/resources/get.ps1 +++ b/src/site/resources/get.ps1 @@ -146,7 +146,8 @@ $shim | Set-Content -Path $shimPath -Encoding ASCII Write-Host "Installed the IPMI Java Client jar to $jarPath" Write-Host "Installed the ipmicli launcher to $shimPath" -Write-Host 'The launcher is a batch file: a value with % ^ & | < or > does not reach ipmicli as typed.' +Write-Host 'The launcher is a batch file: a %NAME% reference, and ^ & | < > outside double quotes' +Write-Host '(PowerShell quotes only a value with a space), do not reach ipmicli as typed.' Write-Host 'Give such a password at the prompt or in a file (-pf).' # --- PATH registration ----------------------------------------------------------- From 7a15e3271250d58c17a560f0a16a7c4a6363e425 Mon Sep 17 00:00:00 2001 From: Bertrand Martin Date: Sun, 25 Oct 2026 22:10:55 +0100 Subject: [PATCH 3/3] Say that < and > redirect, and scope the java -jar workaround to PowerShell (#219 review) Co-Authored-By: Claude Fable 5.1 --- src/site/markdown/cli.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/site/markdown/cli.md b/src/site/markdown/cli.md index 13d669bc..1855d170 100644 --- a/src/site/markdown/cli.md +++ b/src/site/markdown/cli.md @@ -184,13 +184,15 @@ password in a UTF-8 file and pass it with `-pf`. The Windows launcher is a batch file, so `cmd.exe` parses the command line before the CLI sees it, from PowerShell as well. A `%NAME%` reference is replaced by the variable wherever it is; -outside double quotes, `^` is dropped and `&`, `|`, `<` and `>` end the arguments and run what -follows as a command (`-p 'a&ver'` logs in with `a`, then runs `ver`). PowerShell puts double -quotes only around a value that contains a space, so a `-p`, `-u`, `--name` or `-pf` value with -one of these characters and no space (`C:\R&D\pw.txt`) does not reach the CLI as typed; from -`cmd.exe`, a value in double quotes is safe except for `%NAME%`. Give such a password at the -prompt or in a file with `-pf`, and such a path or name through `java -jar`, which receives every -value unchanged. +outside double quotes, `^` is dropped, `&` and `|` end the arguments and run what follows as a +command (`-p 'a&ver'` logs in with `a`, then runs `ver`), and `<` and `>` end them and redirect +the input or output of the CLI to the file that follows (`-p 'a>out.txt'` logs in with `a` and +writes the output to `out.txt`). PowerShell puts double quotes only around a value that contains +a space, so a `-p`, `-u`, `--name` or `-pf` value with one of these characters and no space +(`C:\R&D\pw.txt`) does not reach the CLI as typed; from `cmd.exe`, a value in double quotes is +safe except for `%NAME%`. Give such a password at the prompt or in a file with `-pf`, and such a +path or name through `java -jar` from PowerShell, where Java receives every value unchanged +(from `cmd.exe`, `java -jar` goes through the same parsing as the launcher). Secrets are never printed: not in the usage errors, not with `--verbose`, not in the failure messages. The CLI wipes its copies of the password and of the key when it ends, but a `-p` or