-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix of 1211 and 1082 #349
Fix of 1211 and 1082 #349
Conversation
bingbing8
commented
Oct 12, 2018
•
edited
Loading
edited
- fix of Unable to use scp with -oUserKnownHostsFile that has spaces Win32-OpenSSH#1211
- fix of Remote SSH commands require double escaping before hitting the DefaultShell Win32-OpenSSH#1082
- scp works when powershell and cmd as default shell
- have the escaping logic in posix_spawn only
- Add program dir as part of path in process context so scp and sftp in…
- only escape double quotes and backslash for common shells
1. fix of 1211 (scp works when powershell and cmd as default shell) 2. fix of 1082, 3. have the escaping logic in posix_spawn only4. Add program dir as part of path in process context so scp and sftp in…
contrib/win32/win32compat/misc.c
Outdated
* we want to launch scp and sftp executables from the same binary directory | ||
* that sshd is hosted in. This will facilitate hosting and evaluating | ||
* multiple versions of OpenSSH at the same time. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this function is not prepending the current binary location to command. are these comments obsolete ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- we added current binary location to PATH
- If we prepend the path, some shells, like powershell will require shell specific additional characters (& for powershell) to be able to run scp, sftp. powershell -c "&
<full path to scp
>"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will remove the comments
contrib/win32/win32compat/w32fd.c
Outdated
@@ -1052,7 +1053,9 @@ spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDL | |||
error("failed to duplicate %s", cmd); | |||
return ret; | |||
} | |||
|
|||
if (strstr(path, "system32\\cmd") || strstr(path, "ssh-shellhost")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if you do:
bash.exe -c c:\windows\system32\cmd.exe /c "echo hi"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this case is an issue when the path is user define cmd which contains both exe and arguments. in next version, I use the last parameter to define if it is user defined cmd. If so, we don't change anything.
contrib/win32/win32compat/w32fd.c
Outdated
memcpy(t, tmp, strlen(tmp)); | ||
t += strlen(tmp); | ||
} else { | ||
tmp += strlen(exe_extenstion); /* move the pointer to the end of ".exe" */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you end up with an input command like the following here:
c:\windows\system32\cmd /c ping.exe localhost
If so, this logic would incorrectly identify the nested binary as the parent executable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the existing known shells and ssh executable, the first parts always ends with .exe. I don't see other ways to identify the file path (the first part) in the string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about with proxyCommand or SSH_ASK_PASS ? Also fix spelling mistake in exe_extenstion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right.
error("failed to allocation memory"); | ||
return -1; | ||
} | ||
swprintf_s(path_new_value, path_new_len, L"%s%s%s", __wprogdir, path_value ? L";" : L"", path_value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the confirmed order of exe lookup (we figured that what's on msdn is wrong) ? Does this guarantee picking up exe from progdir in all scenarios?
Are we OK with adjusting PATH for user's remote sessions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the msdn is correct, but the search order is for the executable, which is the first part of the command. but scp, sftp are the arguments part of the command.
So far, looks like it picked up binaries from progdir in all the scenarios.
I don't see a problem with adjusting PATH for user's remote session.
2. don't touch user defined cmd: no prepending, no escaping, no additional quotes 3. fix line ending
@manojampalam , when you get time, please review the changes. Thanks! |
@manojampalam Please review. currently only escape non-user defined commands from common shells. for other shells, no escaping, no -c added if shell option is not specified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments inline...
contrib/win32/openssh/ssh.vcxproj
Outdated
@@ -496,6 +496,7 @@ | |||
<ClInclude Include="$(OpenSSH-Src-Path)uuencode.h" /> | |||
<ClInclude Include="$(OpenSSH-Src-Path)version.h" /> | |||
<ClInclude Include="$(OpenSSH-Src-Path)xmalloc.h" /> | |||
<ClInclude Include="$(OpenSSH-Src-Path)pal-doexec.c.h" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pal-doexec.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
contrib/win32/openssh/sshd.vcxproj
Outdated
@@ -1,473 +1,474 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix CRLF
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still shows up different
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
finally fixed it.
@@ -70,9 +70,9 @@ int is_absolute_path(const char *); | |||
int file_in_chroot_jail(HANDLE); | |||
PSID get_sid(const char*); | |||
int am_system(); | |||
char* build_session_commandline(const char *, const char *, const char *); | |||
char * build_command_string(const char * ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could get rid of this since this is internal to logic within w32_doexec.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added back and keep them in misc_internal.h. we need to call them from w32_doexec.c and unit tests
int is_conpty_supported(); | ||
int exec_command_with_pty(wchar_t*, STARTUPINFOW*, PROCESS_INFORMATION*, int); | ||
int exec_command_with_pty(int * pid, char* cmd, int in, int out, int err, unsigned int col, unsigned int row, int ttyfd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one too, you could get rid of this since this is internal to logic within w32_doexec.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I revert it back to misc.internal.h because the definition is in w32_pty.c and the caller is w32_doexe.c
contrib/win32/win32compat/w32fd.c
Outdated
t += strlen(path); | ||
|
||
|
||
/*For user defined cmd, no need to add quotes*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?? can you add some examples? What's a user defined command ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
contrib/win32/win32compat/w32fd.c
Outdated
t += strlen(__progdir); | ||
*t++ = '\\'; | ||
} | ||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not in favor of this. What issues are we hitting if we don't do this? If the module path has spaces in it, it is expected to be enclosed in quotes. This is a standard practice even on Unix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the log below this.
contrib/win32/win32compat/w32fd.c
Outdated
while (*t1) | ||
cmdline_len += (DWORD)strlen(*t1++) + 1 + 2; | ||
while (*t1) { | ||
if (!escape) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend pulling all the commandline building logic into a separate utility helper and writing an exhaustive set of unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
separate the utility helper out.
added unit tests.
|
||
memset(&si, 0, sizeof(STARTUPINFO)); | ||
si.cb = sizeof(STARTUPINFO); | ||
si.dwXSize = 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 5 ? Add comments if needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove these two lines. It was from the existing codes.
argc_original = argc; | ||
wargv_original = wargv; | ||
|
||
init_prog_paths(); | ||
/* change current directory to sshd.exe root */ | ||
_wchdir(__wprogdir); | ||
|
||
_wdupenv_s(&path_value, &len, L"PATH"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comments on why we are doing this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added.
2. Add registry key to indicate escaping is needed or not for shells other than ps, shellhost, cmd, cygwin, bash. Default is escape the arg string
…s createprocess failed. Remove the added quotes as failoever when arg is empty.
contrib/win32/openssh/sshd.vcxproj
Outdated
@@ -1,473 +1,474 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still shows up different
contrib/win32/win32compat/w32fd.c
Outdated
*t = '\0'; | ||
|
||
int ret = -1; | ||
cmdline = build_commandline_string(cmd, argv, prepend_module_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if build_commandline_string fails ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add check
@@ -1034,115 +1034,25 @@ int fork() | |||
verbose("fork is not supported"); | |||
return -1; | |||
} | |||
char * build_commandline_string(const char* cmd, char *const argv[], BOOLEAN prepend_module_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this move to misc_internal.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
contrib/win32/win32compat/w32fd.c
Outdated
else | ||
b = CreateProcessW(NULL, t, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi); | ||
*(cmdline_utf16 + wcslen(cmdline_utf16) - 1) = L'\0'; | ||
/*failover only when double quotes is potentially added necessary*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could simplify the below condition by putting this inside loop and getting rid of "num" and "t":
if ( !b && GetLastError() != ERROR_FILENOTFOUND && (argv == NULL || *argv == NULL) && cmd[0] != '"') {
cmdline_utf16++;
*(cmdline_utf16 + wcslen(cmdline_utf16) - 1) = L'\0';
}
break;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can get rid of num, but not t.
I need to free cmdline_utf16 at the end. the pointer can't change
debug3("pty commandline: %ls", pty_cmdline); | ||
|
||
if (!CreateProcessW(NULL, pty_cmdline, NULL, NULL, TRUE, 0, NULL, NULL, si, pi)) { | ||
if (CreateProcessW(NULL, pty_cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I may have missed this earlier but why can't we call posix_spawnp here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for pty, the si setting from session (col, row, and dwflag) are different from posix_spawnp. There is no args for col, row, and dwflag to posix_spawnp. One option is change the signature of posix_spawn_internal to take si info and pass them to spawn_child_internal. and then call posix_spawn_internal at here.
out = build_session_commandline("c:\\powershell", NULL, "sftp-server -arg"); | ||
ASSERT_STRING_EQ(out, "\"c:\\powershell\" -c \"sftp-server.exe -arg\""); | ||
char * | ||
build_commandline_string(const char* cmd, char *const argv[], BOOLEAN prepend_module_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can get rid of this by moving it to misc_internal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
@manojampalam, please review the updated code |