Skip to content

Commit

Permalink
Support I/O redirection in all ssh clients (ssh.exe, sftp.exe and scp…
Browse files Browse the repository at this point in the history
  • Loading branch information
manojampalam authored Apr 14, 2017
1 parent b924b42 commit c3c5c1f
Show file tree
Hide file tree
Showing 23 changed files with 404 additions and 298 deletions.
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

0 comments on commit c3c5c1f

Please sign in to comment.