From 0840af06bf535fa690564bcffa9606e7b7dd4f16 Mon Sep 17 00:00:00 2001 From: Yanbing Date: Sat, 29 Sep 2018 14:28:21 -0700 Subject: [PATCH] Add support of posix_spawnp (#344) Added support of posix_spawnp. 1. fix of issue https://github.com/PowerShell/Win32-OpenSSH/issues/1185 2. add End2End tests --- contrib/win32/win32compat/spawn.c | 7 ------- contrib/win32/win32compat/w32fd.c | 16 +++++++++++----- readpass.c | 4 ++-- regress/pesterTests/CommonUtils.psm1 | 2 +- regress/pesterTests/SSH.Tests.ps1 | 12 ++++++++++++ regress/pesterTests/SSHDConfig.tests.ps1 | 1 - sshconnect.c | 4 ++-- 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/contrib/win32/win32compat/spawn.c b/contrib/win32/win32compat/spawn.c index f00628a85..38a3b3ef5 100644 --- a/contrib/win32/win32compat/spawn.c +++ b/contrib/win32/win32compat/spawn.c @@ -7,13 +7,6 @@ #include "inc\spawn.h" #include "inc\unistd.h" -int -posix_spawnp(pid_t *pidp, const char *file, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) -{ - errno = ENOTSUP; - return -1; -} - int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions) { diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index dc612a71c..2c787611e 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -1018,7 +1018,7 @@ int fork() */ static int -spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDLE err, unsigned long flags, HANDLE* as_user) +spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDLE err, unsigned long flags, HANDLE* as_user, BOOLEAN prepend_module_path) { PROCESS_INFORMATION pi; STARTUPINFOW si; @@ -1036,7 +1036,7 @@ spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDL } t = cmd; - if (!is_absolute_path(t)) + if (!is_absolute_path(t) && prepend_module_path) add_module_path = 1; /* compute total cmdline len*/ @@ -1246,7 +1246,7 @@ fd_decode_state(char* enc_buf) } int -posix_spawn_internal(pid_t *pidp, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[], HANDLE user_token) +posix_spawn_internal(pid_t *pidp, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[], HANDLE user_token, BOOLEAN prepend_module_path) { int i, ret = -1; int sc_flags = 0; @@ -1282,7 +1282,7 @@ posix_spawn_internal(pid_t *pidp, const char *path, const posix_spawn_file_actio if (_putenv_s(POSIX_FD_STATE, fd_info) != 0) goto cleanup; - i = spawn_child_internal(argv[0], argv + 1, stdio_handles[STDIN_FILENO], stdio_handles[STDOUT_FILENO], stdio_handles[STDERR_FILENO], sc_flags, user_token); + i = spawn_child_internal(argv[0], argv + 1, stdio_handles[STDIN_FILENO], stdio_handles[STDOUT_FILENO], stdio_handles[STDERR_FILENO], sc_flags, user_token, prepend_module_path); if (i == -1) goto cleanup; if (pidp) @@ -1315,5 +1315,11 @@ cleanup: int posix_spawn(pid_t *pidp, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { - return posix_spawn_internal(pidp, path, file_actions, attrp, argv, envp, NULL); + return posix_spawn_internal(pidp, path, file_actions, attrp, argv, envp, NULL, TRUE); +} + +int +posix_spawnp(pid_t *pidp, const char *file, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) +{ + return posix_spawn_internal(pidp, file, file_actions, attrp, argv, envp, NULL, FALSE); } diff --git a/readpass.c b/readpass.c index f5c99dcf1..a5a49c87b 100644 --- a/readpass.c +++ b/readpass.c @@ -81,9 +81,9 @@ ssh_askpass(char *askpass, const char *msg) char* spawn_argv[2]; spawn_argv[0] = askpass; spawn_argv[1] = NULL; - if (posix_spawn(&pid, spawn_argv[0], &actions, NULL, spawn_argv, NULL) != 0) { + if (posix_spawnp(&pid, spawn_argv[0], &actions, NULL, spawn_argv, NULL) != 0) { posix_spawn_file_actions_destroy(&actions); - error("ssh_askpass: posix_spawn: %s", strerror(errno)); + error("ssh_askpass: posix_spawnp: %s", strerror(errno)); signal(SIGCHLD, osigchld); return NULL; } diff --git a/regress/pesterTests/CommonUtils.psm1 b/regress/pesterTests/CommonUtils.psm1 index 08911b3d5..94e29c694 100644 --- a/regress/pesterTests/CommonUtils.psm1 +++ b/regress/pesterTests/CommonUtils.psm1 @@ -97,7 +97,7 @@ function Add-PasswordSetting $platform = Get-Platform if ($platform -eq [PlatformType]::Windows) { if (-not($env:DISPLAY)) {$env:DISPLAY = 1} - $env:SSH_ASKPASS="$($env:ComSpec) /c echo $pass" + $env:SSH_ASKPASS="cmd.exe /c echo $pass" } } diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index d2b0ee605..5fc7d1b99 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -296,6 +296,18 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { iex "cmd /c `"ssh -o UserKnownHostsFile=`"$kh`" -o StrictHostKeyChecking=no test_target hostname 2>&1`"" @(Get-Content $kh).Count | Should Be 1 } + + It "ProxyCommand with file name only" { + & cmd /c "ssh -o ProxyCommand=`"cmd.exe /c echo Invalid proxy 1>&2`" abc 2>$stderrFile" + $stderrFile | Should Contain "Invalid proxy" + $stderrFile | Should Contain "Connection closed by remote host" + } + + It "ProxyCommand with absolute path to the file" { + & cmd /c "ssh -o ProxyCommand=`"$($env:ComSpec) /c echo Invalid proxy 1>&2`" abc 2>$stderrFile" + $stderrFile | Should Contain "Invalid proxy" + $stderrFile | Should Contain "Connection closed by remote host" + } } } diff --git a/regress/pesterTests/SSHDConfig.tests.ps1 b/regress/pesterTests/SSHDConfig.tests.ps1 index 30acda081..8fe38be35 100644 --- a/regress/pesterTests/SSHDConfig.tests.ps1 +++ b/regress/pesterTests/SSHDConfig.tests.ps1 @@ -333,6 +333,5 @@ Describe "Tests of sshd_config" -Tags "CI" { Stop-SSHDTestDaemon Remove-UserFromLocalGroup -UserName $matchuser -GroupName $allowGroup1 } -#> } } diff --git a/sshconnect.c b/sshconnect.c index 2887b923d..63d44a611 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -236,8 +236,8 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port, posix_spawn_file_actions_adddup2(&actions, pin[0], STDIN_FILENO) != 0 || posix_spawn_file_actions_adddup2(&actions, pout[1], STDOUT_FILENO) != 0) fatal("posix_spawn initialization failed"); - else if (posix_spawn(&pid, spawn_argv[0], &actions, NULL, spawn_argv, NULL) != 0) - fatal("posix_spawn: %s", strerror(errno)); + else if (posix_spawnp(&pid, spawn_argv[0], &actions, NULL, spawn_argv, NULL) != 0) + fatal("posix_spawnp: %s", strerror(errno)); posix_spawn_file_actions_destroy(&actions); }