[client] Fix SSH proxy mangling shell quoting in forwarded commands#5669
[client] Fix SSH proxy mangling shell quoting in forwarded commands#5669
Conversation
📝 WalkthroughWalkthroughThe changes modify SSH command detection and execution logic to use raw command strings instead of parsed command arrays, preserving shell quoting and special characters throughout the proxy and server. A comprehensive integration test validates the correct handling of quoted and special-character command scenarios. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
29c1086 to
9d03878
Compare
9d03878 to
3692a2a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
client/ssh/proxy/proxy_test.go (1)
420-429: Tighten helper cleanup to close all opened resources.
setupProxySSHClientallocates proxy connection and pipe FDs but cleanup currently doesn’t close all of them (or the proxy instance). Closing them reduces cross-test leakage and flakiness.Suggested patch
cleanupFn := func() { _ = client.Close() _ = clientConn.Close() + _ = proxyConn.Close() cancel() os.Stdin = origStdin os.Stdout = origStdout + _ = stdinReader.Close() + _ = stdinWriter.Close() + _ = stdoutReader.Close() + _ = stdoutWriter.Close() + _ = proxyInstance.Close() _ = sshServer.Stop() mockDaemon.stop() jwksServer.Close() }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@client/ssh/proxy/proxy_test.go` around lines 420 - 429, The cleanupFn in setupProxySSHClient doesn't close all opened descriptors—ensure you close the proxy instance and any pipe FDs created by the helper in addition to existing closes; specifically, add calls to close the proxy (e.g., proxy.Close() or CloseProxy()), close the proxy connection (proxyConn.Close() if different from clientConn), and close any stdin/stdout pipe endpoints created (e.g., stdinPipeReader/Writer, stdoutPipeReader/Writer) using the same `_ = ...Close()` pattern so all resources allocated by setupProxySSHClient (client, clientConn, proxy, proxyConn, pipe FDs, sshServer, mockDaemon, jwksServer) are closed and cancel is called and stdio restored.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@client/ssh/proxy/proxy_test.go`:
- Around line 257-260: The test TestSSHProxy_CommandQuoting runs POSIX-only
/bin/sh payloads and should also skip on Windows CI; update the test (function
TestSSHProxy_CommandQuoting) to detect the OS using runtime.GOOS and call t.Skip
when runtime.GOOS == "windows", and add the runtime import to the test file's
imports so the build passes.
---
Nitpick comments:
In `@client/ssh/proxy/proxy_test.go`:
- Around line 420-429: The cleanupFn in setupProxySSHClient doesn't close all
opened descriptors—ensure you close the proxy instance and any pipe FDs created
by the helper in addition to existing closes; specifically, add calls to close
the proxy (e.g., proxy.Close() or CloseProxy()), close the proxy connection
(proxyConn.Close() if different from clientConn), and close any stdin/stdout
pipe endpoints created (e.g., stdinPipeReader/Writer, stdoutPipeReader/Writer)
using the same `_ = ...Close()` pattern so all resources allocated by
setupProxySSHClient (client, clientConn, proxy, proxyConn, pipe FDs, sshServer,
mockDaemon, jwksServer) are closed and cancel is called and stdio restored.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0bb0aaa7-57b3-462d-9a53-bdd51bf7f34c
📒 Files selected for processing (3)
client/ssh/proxy/proxy.goclient/ssh/proxy/proxy_test.goclient/ssh/server/session_handlers.go
|



Describe your changes
session.Command()(shlex split + join) instead ofsession.RawCommand()to forward commands to the backend, which loses shell quoting and breaks tools like Ansible that send commands with subshells:/bin/sh -c '( umask 77 && ... ) && sleep 0'hasCommandcheckIssue ticket number and link
Checklist
Documentation
Select exactly one:
Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
Summary by CodeRabbit
Bug Fixes
Tests