Honor configured shell for remote exec
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s

This commit is contained in:
DuProcess
2026-07-17 19:26:08 -04:00
parent 7c915a9fd7
commit b8b56c0f32
2 changed files with 42 additions and 3 deletions
+13 -3
View File
@@ -3271,15 +3271,25 @@ async fn run_exec_stream_service(
continue;
}
};
let output = TokioCommand::new("sh")
.arg("-lc")
let shell = {
state
.lock()
.expect("server state poisoned")
.config
.shell
.clone()
};
let output = TokioCommand::new(&shell)
.arg("-c")
.arg(&request.command)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.await
.with_context(|| format!("run command {:?}", request.command))?;
.with_context(|| {
format!("run command {:?} with shell {shell}", request.command)
})?;
for chunk in output.stdout.chunks(CHUNK_SIZE) {
send_exec_response_to_client(
&state,
+29
View File
@@ -1355,6 +1355,22 @@ fn native_exec_command_smoke() {
let dir = tempfile::tempdir().unwrap();
let port = free_udp_port();
let config = write_server_config(&dir, port);
let shell_log = dir.path().join("exec-shell.log");
let shell = dir.path().join("exec-shell");
fs::write(
&shell,
format!(
"#!/bin/sh\nprintf '%s\\n' \"$*\" >> '{}'\nexec /bin/sh \"$@\"\n",
shell_log.display()
),
)
.unwrap();
fs::set_permissions(&shell, fs::Permissions::from_mode(0o700)).unwrap();
let raw = fs::read_to_string(&config).unwrap().replace(
"shell = \"/bin/sh\"",
&format!("shell = {:?}", shell.display().to_string()),
);
fs::write(&config, raw).unwrap();
write_native_client_auth(&dir, &config);
let mut server = start_server(&dir, &config);
let client_bin = env!("CARGO_BIN_EXE_dosh-client");
@@ -1380,6 +1396,19 @@ fn native_exec_command_smoke() {
);
assert_eq!(String::from_utf8_lossy(&output.stdout), "out");
assert_eq!(String::from_utf8_lossy(&output.stderr), "err");
let shell_invocations = fs::read_to_string(shell_log).unwrap();
assert!(
shell_invocations
.lines()
.any(|line| line.starts_with("-c ")),
"configured shell was not used for exec: {shell_invocations:?}"
);
assert!(
!shell_invocations
.lines()
.any(|line| line.starts_with("-lc ")),
"exec must not start a login shell: {shell_invocations:?}"
);
}
#[test]