ssh: fix sudo failing with "password required" (v6 / 1.1.0)
The connector asked for a sudo password on every privileged call and failed whenever nobody answered it, which is every unattended run. - Always probe `sudo -n` first, even for aliases set to sudo="prompt". `_sudo_prefix` used to elicit unconditionally, so a host granting this user NOPASSWD still opened an Agent Inbox prompt; with no human there it hit the client's 300s ELICITATION_DEADLINE, got back `cancel`, and surfaced as "sudo password required (user declined or timed out)". sudo refuses before running anything when it wants a password, so the probe is side-effect free. - Strip a leading `sudo` from `command` and turn it into sudo=true. Agents write `exec(command="sudo systemctl restart x")`: with sudo=false that ran a tty-less sudo, with sudo=true it nested `sudo -S ... sudo ...` whose inner prompt had no tty either. Handles -u/-n/-S/-E/-H/-i/-k/-p/--; an unknown flag leaves the command alone. sudo_user now implies sudo=true. - Run privileged commands as `sh -c '<command>'`, so `&&`, pipes and redirections are elevated too instead of only the first word. - Add SSH_MCP_SUDO_PASSWORD (optional, secret) for unattended runs. It is consulted only after `sudo -n` proved a password is needed, so on a NOPASSWD host it never lands in the command's own stdin. - Actionable errors for every sudo failure mode, and a `hint` on a nested sudo we could not peel off. General review of the same server: - Drain stdout and stderr together and make timeout_sec a real wall-clock deadline. Both streams share one SSH channel window, so reading stdout to EOF first stalled once a chatty stderr filled it. Command stdin is now closed after the optional password. - Queue messages that arrive while awaiting an elicitation reply instead of discarding them, so a concurrent tools/call is not lost. - Record the client's `elicitation` capability at initialize and fail fast when it is absent rather than blocking on a prompt nobody can answer. - Tolerate null/string integer arguments (depth, max_results, context_lines, timeout_sec). - Realign the version across both manifests: fragment.json said 5/1.0.4 while connector.json said 2/1.0.1, so the feed was permanently ahead of the installed version and offered an update forever. Also lands the pending docs work: CONNECTOR_MANIFEST_GUIDE.md as the single source of truth, docs/connector.manifest_guide.md retired to a pointer, CLAUDE.md audited against the repo, compile.py docstring fixed, and an opencode.json config.
This commit is contained in:
@@ -619,14 +619,14 @@
|
||||
"type": "none"
|
||||
},
|
||||
"folder": "ssh",
|
||||
"version": 5,
|
||||
"version_string": "1.0.4",
|
||||
"version_release_date": "2026-07-21",
|
||||
"version": 6,
|
||||
"version_string": "1.1.0",
|
||||
"version_release_date": "2026-09-03",
|
||||
"files": [
|
||||
{
|
||||
"path": "connector.json",
|
||||
"sha256": "13ffbfaafab3092f5cc9e273a253f06ba50a5b89334ddd22bf1359dbd5b8feb7",
|
||||
"size": 3986
|
||||
"sha256": "a8bbc923bedf484f3d3bdd24e77aeaac81209e42b17f96b4abd15ed0c8c3dbe8",
|
||||
"size": 4494
|
||||
},
|
||||
{
|
||||
"path": "icon_lg.svg",
|
||||
@@ -645,8 +645,8 @@
|
||||
},
|
||||
{
|
||||
"path": "ssh_mcp_server.py",
|
||||
"sha256": "68509094a35578ffaaf357e13b55e1bfcf397f16a3b993719c4c3b97ab2dc798",
|
||||
"size": 50193
|
||||
"sha256": "ff3fb49dfd41eba6bd1cbfe5b314007876ce382a3a55fb28b96a03fa01fe292f",
|
||||
"size": 60367
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user