Skip to content
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

Support I/O redirection in all ssh clients (ssh.exe, sftp.exe and scp.exe) #113

Merged
merged 14 commits into from
Apr 14, 2017
2 changes: 1 addition & 1 deletion contrib/win32/openssh/config.h.vs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@

/* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you
don't. */
#define HAVE_DECL_O_NONBLOCK 0
#define HAVE_DECL_O_NONBLOCK 1

/* Define to 1 if you have the declaration of `passwdexpired', and to 0 if you
don't. */
Expand Down
5 changes: 3 additions & 2 deletions contrib/win32/openssh/keygen.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
Expand Down Expand Up @@ -186,11 +186,12 @@
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-keygen.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
7 changes: 5 additions & 2 deletions contrib/win32/openssh/keygen.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
Expand All @@ -21,10 +21,13 @@
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>
5 changes: 3 additions & 2 deletions contrib/win32/openssh/scp.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
Expand All @@ -22,6 +22,7 @@
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)scp.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
Expand Down Expand Up @@ -191,4 +192,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
7 changes: 5 additions & 2 deletions contrib/win32/openssh/scp.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
Expand All @@ -21,10 +21,13 @@
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>
5 changes: 3 additions & 2 deletions contrib/win32/openssh/sftp.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
Expand Down Expand Up @@ -26,6 +26,7 @@
<ClCompile Include="$(OpenSSH-Src-Path)sftp-glob.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sftp.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
Expand Down Expand Up @@ -197,4 +198,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
7 changes: 5 additions & 2 deletions contrib/win32/openssh/sftp.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
Expand Down Expand Up @@ -33,10 +33,13 @@
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>
7 changes: 4 additions & 3 deletions contrib/win32/openssh/ssh.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
Expand Down Expand Up @@ -298,13 +298,14 @@
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
7 changes: 5 additions & 2 deletions contrib/win32/openssh/ssh.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
Expand Down Expand Up @@ -311,10 +311,13 @@
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>
1 change: 0 additions & 1 deletion contrib/win32/openssh/win32iocompat.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\utf.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32-utf8.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
Expand Down
1 change: 0 additions & 1 deletion contrib/win32/openssh/win32iocompat.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\utf.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32-utf8.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
Expand Down
67 changes: 17 additions & 50 deletions contrib/win32/win32compat/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ struct createFile_flags {
DWORD dwFlagsAndAttributes;
};

int termio_initiate_read(struct w32_io* pio);
int termio_initiate_write(struct w32_io* pio, DWORD num_bytes);
int syncio_initiate_read(struct w32_io* pio);
int syncio_initiate_write(struct w32_io* pio, DWORD num_bytes);
int syncio_close(struct w32_io* pio);

/* maps Win32 error to errno */
int
Expand Down Expand Up @@ -440,11 +441,10 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
}

if (fileio_is_io_available(pio, TRUE) == FALSE) {
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
if (-1 == termio_initiate_read(pio))
if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
if (-1 == syncio_initiate_read(pio))
return -1;
}
else {
} else {
if (-1 == fileio_ReadFileEx(pio, max)) {
if ((FILETYPE(pio) == FILE_TYPE_PIPE)
&& (errno == ERROR_BROKEN_PIPE)) {
Expand Down Expand Up @@ -571,46 +571,12 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
bytes_copied = min(max, pio->write_details.buf_size);
memcpy(pio->write_details.buf, buf, bytes_copied);

if (FILETYPE(pio) == FILE_TYPE_CHAR) {
if (termio_initiate_write(pio, bytes_copied) == 0) {
if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
if (syncio_initiate_write(pio, bytes_copied) == 0) {
pio->write_details.pending = TRUE;
pio->write_details.remaining = bytes_copied;
}
else
return -1;
} else if ( FILETYPE(pio) == FILE_TYPE_PIPE &&
GetNamedPipeInfo(WINHANDLE(pio), &pipe_flags, NULL, NULL, &pipe_instances) &&
pipe_flags == PIPE_CLIENT_END && pipe_instances == 1) {
/*
* TODO - Figure out a better solution to this problem
* IO handle corresponding to this object (pio->handle) may be referring
* to something that isn't opened in overlapped mode. While all handles
* opened by this POSIX wrapper are opened in overlapped mode, other handles
* that are inherited (ex. via std i/o) are typically not.
* Ex. When we do this in Powershell
* $o = ssh.exe user@target hostname
* Powershell creates anonymous pipes (that do not support overlapped i.o)
* Calling asynchronous I/O APIs (WriteFileEx) for example will not work in
* those cases (the callback is never called and it typically manifests as a
* hang to end user
*
* This conditional logic is put in place to specifically handle Powershell
* redirection scenarios. Thinking behind these conditions
* - should be a pipe handle. console I/O is handled in termio.c, impacting file i/o
* scenarios not found yet.
* - pipe should be the client end. This is to skip pipes created internally in POSIX
* wrapper (by pipe() calls) - The write ends on these pipes are on server
* - pipe_instances == 1. This is to skip pipe handles created as part of Connect(AF_UNIX)
* sockets (that typically are created for unlimited instances).
* For such I/O we do a synchronous write.
*/
/* DebugBreak() */;
if (WriteFile(WINHANDLE(pio), pio->write_details.buf, bytes_copied, &bytes_copied, NULL) == FALSE) {
errno = errno_from_Win32LastError();
debug3("write - WriteFile() ERROR:%d, io:%p", GetLastError(), pio);
} else
return -1;
}
return bytes_copied;
} else {
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
&pio->write_overlapped, &WriteCompletionRoutine)) {
Expand Down Expand Up @@ -753,8 +719,8 @@ fileio_on_select(struct w32_io* pio, BOOL rd)

if (!pio->read_details.pending && !fileio_is_io_available(pio, rd))
/* initiate read, record any error so read() will pick up */
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
if (termio_initiate_read(pio) != 0) {
if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
if (syncio_initiate_read(pio) != 0) {
pio->read_details.error = errno;
errno = 0;
return;
Expand All @@ -773,6 +739,9 @@ fileio_close(struct w32_io* pio)
{
debug4("fileclose - pio:%p", pio);

if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR)
return syncio_close(pio);

/* handle can be null on AF_UNIX sockets that are not yet connected */
if (WINHANDLE(pio) == 0 || WINHANDLE(pio) == INVALID_HANDLE_VALUE) {
free(pio);
Expand All @@ -782,15 +751,13 @@ fileio_close(struct w32_io* pio)
CancelIo(WINHANDLE(pio));
/* let queued APCs (if any) drain */
SleepEx(0, TRUE);
if (pio->type != STD_IO_FD) { /* STD handles are never explicitly closed */
CloseHandle(WINHANDLE(pio));

CloseHandle(WINHANDLE(pio));
/* free up non stdio */
if (!IS_STDIO(pio)) {
if (pio->read_details.buf)
free(pio->read_details.buf);

if (pio->write_details.buf)
free(pio->write_details.buf);

free(pio);
}
return 0;
Expand Down
25 changes: 23 additions & 2 deletions contrib/win32/win32compat/inc/fcntl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ int w32_open(const char *pathname, int flags, ...);
void* w32_fd_to_handle(int fd);
int w32_allocate_fd_for_handle(void* h, int is_sock);

#define O_ACCMODE 0x0003
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY
#define O_RDWR _O_RDWR
Expand All @@ -37,4 +36,26 @@ int w32_allocate_fd_for_handle(void* h, int is_sock);
#define O_NOINHERIT _O_NOINHERIT
#define O_SEQUENTIAL _O_SEQUENTIAL
#define O_RANDOM _O_RANDOM
#define O_U16TEXT _O_U16TEXT
#define O_U16TEXT _O_U16TEXT

/*
* open() POSIX specific modes and flags.
* Caution while making changes
* - cross check conflict with common macros in Windows headers
* - Ex. #define O_APPEND 0x8
*/
#define O_ACCMODE 0x0003
#define O_NONBLOCK 0x0004 /*io operations wont block*/
# define S_IXUSR 0000100 /* execute/search permission, */
# define S_IXGRP 0000010 /* execute/search permission, */
# define S_IXOTH 0000001 /* execute/search permission, */
# define _S_IWUSR 0000200 /* write permission, */
# define S_IWUSR _S_IWUSR /* write permission, owner */
# define S_IWGRP 0000020 /* write permission, group */
# define S_IWOTH 0000002 /* write permission, other */
# define S_IRUSR 0000400 /* read permission, owner */
# define S_IRGRP 0000040 /* read permission, group */
# define S_IROTH 0000004 /* read permission, other */
# define S_IRWXU 0000700 /* read, write, execute */
# define S_IRWXG 0000070 /* read, write, execute */
# define S_IRWXO 0000007 /* read, write, execute */
Loading