From 4dbee0d15a5f4eaea07f169ca1ca6aabc7e373d1 Mon Sep 17 00:00:00 2001 From: bagajjal Date: Mon, 22 May 2017 22:18:41 -0700 Subject: [PATCH] Onboard sshkeyscan (#143) PowerShell/Win32-OpenSSH#124 PowerShell/Win32-OpenSSH#728 --- contrib/win32/openssh/Win32-OpenSSH.sln | 19 +- contrib/win32/openssh/libssh.vcxproj | 1 + contrib/win32/openssh/libssh.vcxproj.filters | 369 ++++-------------- contrib/win32/openssh/ssh-keyscan.vcxproj | 205 ++++++++++ .../win32/openssh/ssh-keyscan.vcxproj.filters | 30 ++ contrib/win32/openssh/sshd.vcxproj | 9 +- contrib/win32/openssh/sshd.vcxproj.filters | 3 - contrib/win32/openssh/unittest-kex.vcxproj | 1 - contrib/win32/win32compat/socketio.c | 123 +++--- contrib/win32/win32compat/w32fd.c | 39 +- contrib/win32/win32compat/w32fd.h | 5 +- regress/pesterTests/KeyUtils.Tests.ps1 | 27 ++ ssh-keyscan.c | 10 +- 13 files changed, 470 insertions(+), 371 deletions(-) create mode 100644 contrib/win32/openssh/ssh-keyscan.vcxproj create mode 100644 contrib/win32/openssh/ssh-keyscan.vcxproj.filters diff --git a/contrib/win32/openssh/Win32-OpenSSH.sln b/contrib/win32/openssh/Win32-OpenSSH.sln index e70453bf6..6fca70b12 100644 --- a/contrib/win32/openssh/Win32-OpenSSH.sln +++ b/contrib/win32/openssh/Win32-OpenSSH.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh", "ssh.vcxproj", "{74E69D5E-A1EF-46EA-9173-19A412774104}" ProjectSection(ProjectDependencies) = postProject @@ -149,6 +149,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-match", "unittest- {0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh-keyscan", "ssh-keyscan.vcxproj", "{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}" + ProjectSection(ProjectDependencies) = postProject + {05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7} + {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} + {DD483F7D-C553-4740-BC1A-903805AD0174} = {DD483F7D-C553-4740-BC1A-903805AD0174} + {0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -317,6 +325,14 @@ Global {484A8CDE-B949-4BDA-B447-74685C8E032F}.Release|x64.Build.0 = Release|x64 {484A8CDE-B949-4BDA-B447-74685C8E032F}.Release|x86.ActiveCfg = Release|Win32 {484A8CDE-B949-4BDA-B447-74685C8E032F}.Release|x86.Build.0 = Release|Win32 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x64.ActiveCfg = Debug|x64 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x64.Build.0 = Debug|x64 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x86.ActiveCfg = Debug|Win32 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x86.Build.0 = Debug|Win32 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x64.ActiveCfg = Release|x64 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x64.Build.0 = Release|x64 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x86.ActiveCfg = Release|Win32 + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -342,5 +358,6 @@ Global {890C6129-286F-4CD8-8252-FB8D3B4E6E1B} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {FC568FF0-60F2-4B2E-AF62-FD392EDBA1B9} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {484A8CDE-B949-4BDA-B447-74685C8E032F} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E} EndGlobalSection EndGlobal diff --git a/contrib/win32/openssh/libssh.vcxproj b/contrib/win32/openssh/libssh.vcxproj index ede66a5bc..101921759 100644 --- a/contrib/win32/openssh/libssh.vcxproj +++ b/contrib/win32/openssh/libssh.vcxproj @@ -284,6 +284,7 @@ true + diff --git a/contrib/win32/openssh/libssh.vcxproj.filters b/contrib/win32/openssh/libssh.vcxproj.filters index b4bc53b88..d5dd5dd58 100644 --- a/contrib/win32/openssh/libssh.vcxproj.filters +++ b/contrib/win32/openssh/libssh.vcxproj.filters @@ -1,291 +1,92 @@  - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - + + \ No newline at end of file diff --git a/contrib/win32/openssh/ssh-keyscan.vcxproj b/contrib/win32/openssh/ssh-keyscan.vcxproj new file mode 100644 index 000000000..dcdff7fbe --- /dev/null +++ b/contrib/win32/openssh/ssh-keyscan.vcxproj @@ -0,0 +1,205 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {7D0A75FC-F366-4B60-B72F-B37C3EA07CCA} + Win32Proj + sshkeyscan + 8.1 + ssh-keyscan + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + + NotUsing + Level1 + Disabled + _WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + $(SolutionDir);$(OpenSSL-Win32-Debug-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreadedDebug + ProgramDatabase + + + Console + true + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories) + wmainCRTStartup + + + targetos.manifest + + + + + NotUsing + Level1 + Disabled + _WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + $(SolutionDir);$(OpenSSL-x64-Debug-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreadedDebug + ProgramDatabase + + + Console + true + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Debug-Path)lib;%(AdditionalLibraryDirectories) + wmainCRTStartup + + + targetos.manifest + + + + + Level1 + NotUsing + MaxSpeed + true + true + _WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + $(SolutionDir);$(OpenSSL-Win32-Release-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreaded + + + Console + true + true + true + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) + wmainCRTStartup + true + + + targetos.manifest + + + + + Level1 + NotUsing + Disabled + true + true + _WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + $(SolutionDir);$(OpenSSL-x64-Release-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreaded + false + + + Console + true + true + true + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) + wmainCRTStartup + true + + + targetos.manifest + + + + + + + + + + + + + \ No newline at end of file diff --git a/contrib/win32/openssh/ssh-keyscan.vcxproj.filters b/contrib/win32/openssh/ssh-keyscan.vcxproj.filters new file mode 100644 index 000000000..1e2adadc6 --- /dev/null +++ b/contrib/win32/openssh/ssh-keyscan.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/contrib/win32/openssh/sshd.vcxproj b/contrib/win32/openssh/sshd.vcxproj index d6e0f6f1d..201381006 100644 --- a/contrib/win32/openssh/sshd.vcxproj +++ b/contrib/win32/openssh/sshd.vcxproj @@ -110,7 +110,7 @@ Console true - Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories) MultiplyDefinedSymbolOnly wmainCRTStartup @@ -134,7 +134,7 @@ Console true - Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Debug-Path)lib;%(AdditionalLibraryDirectories) MultiplyDefinedSymbolOnly wmainCRTStartup @@ -161,7 +161,7 @@ true true true - Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) MultiplyDefinedSymbolOnly wmainCRTStartup @@ -190,7 +190,7 @@ true true true - Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) MultiplyDefinedSymbolOnly wmainCRTStartup @@ -227,7 +227,6 @@ - diff --git a/contrib/win32/openssh/sshd.vcxproj.filters b/contrib/win32/openssh/sshd.vcxproj.filters index 017b0522e..e3254ed82 100644 --- a/contrib/win32/openssh/sshd.vcxproj.filters +++ b/contrib/win32/openssh/sshd.vcxproj.filters @@ -90,9 +90,6 @@ Source Files - - Source Files - Source Files diff --git a/contrib/win32/openssh/unittest-kex.vcxproj b/contrib/win32/openssh/unittest-kex.vcxproj index c457b0a27..fa3ef685e 100644 --- a/contrib/win32/openssh/unittest-kex.vcxproj +++ b/contrib/win32/openssh/unittest-kex.vcxproj @@ -198,7 +198,6 @@ - diff --git a/contrib/win32/win32compat/socketio.c b/contrib/win32/win32compat/socketio.c index 5e9d6621f..969d06218 100644 --- a/contrib/win32/win32compat/socketio.c +++ b/contrib/win32/win32compat/socketio.c @@ -112,7 +112,7 @@ socketio_acceptEx(struct w32_io* pio) if (getsockname(pio->sock, (struct sockaddr*)&addr, &addrlen) == SOCKET_ERROR) { errno = errno_from_WSALastError(); - debug("acceptEx - getsockname() ERROR:%d, io:%p", errno, pio); + debug("acceptEx - getsockname() ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } @@ -120,7 +120,7 @@ socketio_acceptEx(struct w32_io* pio) context->accept_socket = socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP); if (context->accept_socket == INVALID_SOCKET) { errno = errno_from_WSALastError(); - debug3("acceptEx - socket() ERROR:%d, io:%p", errno, pio); + debug3("acceptEx - socket() ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } @@ -139,7 +139,7 @@ socketio_acceptEx(struct w32_io* pio) /* if overlapped io is in progress, we are good */ if (WSAGetLastError() != ERROR_IO_PENDING) { errno = errno_from_WSALastError(); - debug3("acceptEx - AcceptEx() ERROR:%d, io:%p", errno, pio); + debug3("acceptEx - AcceptEx() ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } } @@ -208,7 +208,7 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed) pio->read_details.pending = TRUE; } else { errno = errno_from_WSALastError(); - debug3("WSARecv - WSARecv() ERROR: io:%p %d", pio, errno); + debug3("WSARecv - WSARecv() ERROR: io:%p %d", pio, WSAGetLastError()); return -1; } } @@ -231,8 +231,8 @@ socketio_socket(int domain, int type, int protocol) pio->sock = socket(domain, type, protocol); if (pio->sock == INVALID_SOCKET) { errno = errno_from_WSALastError(); + debug3("socket - socket() ERROR:%d, io:%p", WSAGetLastError(), pio); free(pio); - debug3("socket - socket() ERROR:%d, io:%p", errno, pio); return NULL; } @@ -240,13 +240,13 @@ socketio_socket(int domain, int type, int protocol) return pio; } -#define SET_ERRNO_ON_ERROR(expr) do { \ - int ret = (expr); \ - if (ret == SOCKET_ERROR) { \ - errno = errno_from_WSALastError(); \ - debug3("%s - ERROR:%d", __FUNCTION__, errno); \ - } \ - return ret; \ +#define SET_ERRNO_ON_ERROR(expr) do { \ + int ret = (expr); \ + if (ret == SOCKET_ERROR) { \ + errno = errno_from_WSALastError(); \ + debug3("%s - ERROR:%d", __FUNCTION__, WSAGetLastError()); \ + } \ + return ret; \ } while (0) /* implements setsockopt() */ @@ -292,7 +292,7 @@ socketio_listen(struct w32_io* pio, int backlog) if (SOCKET_ERROR == listen(pio->sock, backlog)) { errno = errno_from_WSALastError(); - debug3("listen - listen() ERROR:%d io:%p", errno, pio); + debug3("listen - listen() ERROR:%d io:%p", WSAGetLastError(), pio); return -1; } @@ -316,7 +316,7 @@ socketio_listen(struct w32_io* pio, int backlog) &dwBytes, NULL, NULL)) { free(context); errno = errno_from_WSALastError(); - debug3("listen - Ioctl1 ERROR:%d, io:%p", errno, pio); + debug3("listen - Ioctl1 ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } @@ -327,7 +327,7 @@ socketio_listen(struct w32_io* pio, int backlog) &dwBytes, NULL, NULL)) { free(context); errno = errno_from_WSALastError(); - debug3("listen - Ioctl2 ERROR:%d, io:%p", errno, pio); + debug3("listen - Ioctl2 ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } @@ -359,7 +359,8 @@ int socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { BOOL completed = FALSE; - debug5("recv - io:%p", pio); + debug5("recv - io:%p state:%d", pio, pio->internal.state); + if ((buf == NULL) || (len == 0)) { errno = EINVAL; debug3("recv - ERROR: invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio); @@ -396,7 +397,7 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) num_bytes_copied); pio->read_details.remaining -= num_bytes_copied; pio->read_details.completed += num_bytes_copied; - debug4("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p", + debug5("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p", num_bytes_copied, pio->read_details.remaining, pio); return num_bytes_copied; } @@ -505,8 +506,9 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { int ret = 0; WSABUF wsabuf; + + debug5("send - io:%p state:%d", pio, pio->internal.state); - debug4("send - io:%p", pio); if ((buf == NULL) || (len == 0)) { errno = EINVAL; debug3("send - ERROR invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio); @@ -536,7 +538,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) if (pio->write_details.error) { errno = errno_from_WSAError(pio->write_details.error); - debug3("ERROR:%d, io:%p", errno, pio); + debug3("ERROR:%d, io:%p", pio->write_details.error, pio); return -1; } @@ -597,7 +599,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) return wsabuf.len; } else { errno = errno_from_WSALastError(); - debug3("send - WSASend() ERROR:%d, io:%p", errno, pio); + debug3("send - WSASend() ERROR:%d, io:%p", WSAGetLastError(), pio); return -1; } } @@ -618,7 +620,7 @@ socketio_close(struct w32_io* pio) closesocket(pio->sock); /* wait for pending io to abort */ SleepEx(0, TRUE); - if (((pio->internal.state == SOCK_CONNECTED) || (pio->internal.state == SOCK_ACCEPTED)) && + if ((pio->internal.state == SOCK_READY) && (pio->read_details.pending || pio->write_details.pending)) { debug4("close - IO is still pending on closed socket. read:%d, write:%d, io:%p", pio->read_details.pending, pio->write_details.pending, pio); @@ -686,14 +688,14 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) if (pio->read_details.error) { errno = errno_from_WSAError(pio->read_details.error); - debug3("accept - ERROR: async io completed with error: %d, io:%p", errno, pio); + debug3("accept - ERROR: async io completed with error: %d, io:%p", pio->read_details.error, pio); goto on_error; } if (0 != setsockopt(context->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) { errno = errno_from_WSALastError(); - debug3("accept - ERROR: setsockopt failed:%d, io:%p", errno, pio); + debug3("accept - ERROR: setsockopt failed:%d, io:%p", WSAGetLastError(), pio); goto on_error; } @@ -706,7 +708,7 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) memset(accept_io, 0, sizeof(struct w32_io)); accept_io->sock = context->accept_socket; - accept_io->internal.state = SOCK_ACCEPTED; + accept_io->internal.state = SOCK_READY; context->accept_socket = INVALID_SOCKET; debug4("accept io:%p", accept_io); @@ -795,7 +797,7 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) CloseHandle(pio->write_overlapped.hEvent); pio->write_overlapped.hEvent = 0; errno = errno_from_WSALastError(); - debug3("connectex - ERROR ConnectEx() :%d, io:%p", errno, pio); + debug3("connectex - ERROR ConnectEx() :%d, io:%p", WSAGetLastError(), pio); return -1; } } @@ -837,25 +839,35 @@ socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen) int socketio_finish_connect(struct w32_io* pio) { + DWORD wsa_error = 0; debug5("finish_connect, io:%p", pio); + if (pio->write_details.error) { - errno = errno_from_WSAError(pio->write_details.error); - debug3("finish_connect - ERROR: async io completed with error: %d, io:%p", errno, pio); - return -1; + wsa_error = pio->write_details.error; + debug3("finish_connect - ERROR: async io completed with error: %d, io:%p", wsa_error, pio); + goto done; } if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) { - errno = errno_from_WSALastError(); - debug3("finish_connect - ERROR: setsockopt failed:%d, io:%p", errno, pio); - return -1; + wsa_error = WSAGetLastError(); + debug3("finish_connect - ERROR: setsockopt failed:%d, io:%p", wsa_error, pio); + goto done; } - /* Reset any state used during connect */ - /* close event handle */ +done: CloseHandle(pio->write_overlapped.hEvent); - ZeroMemory(&pio->write_details, sizeof(pio->write_details)); - pio->internal.state = SOCK_CONNECTED; - return 0; + pio->write_overlapped.hEvent = 0; + pio->write_details.pending = FALSE; + + if (wsa_error) { + pio->read_details.error = wsa_error; + pio->write_details.error = wsa_error; + errno = errno_from_WSAError(wsa_error); + } else /* reset write_detail that were previously used for async connect */ + ZeroMemory(&pio->write_details, sizeof(pio->write_details)); + + pio->internal.state = SOCK_READY; + return (wsa_error? -1 : 0); } /* checks if a given io is ready/available */ @@ -870,7 +882,7 @@ socketio_is_io_available(struct w32_io* pio, BOOL rd) OVERLAPPED *overlapped = sock_listening ? &pio->read_overlapped : &pio->write_overlapped; BOOL pending = sock_listening ? pio->read_details.pending : pio->write_details.pending; - if (pending) + if (pending) { /* if there is an error to be picked up */ if (sock_listening) { if (pio->read_details.error) @@ -879,18 +891,19 @@ socketio_is_io_available(struct w32_io* pio, BOOL rd) if (pio->write_details.error) return TRUE; } + } - if (WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags)) - return TRUE; - else if (WSAGetLastError() != WSA_IO_INCOMPLETE) { - if (sock_listening) - pio->read_details.error = WSAGetLastError(); - else - pio->write_details.error = WSAGetLastError(); - return TRUE; - } + if (WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags)) + return TRUE; + else if (WSAGetLastError() != WSA_IO_INCOMPLETE) { + if (sock_listening) + pio->read_details.error = WSAGetLastError(); + else + pio->write_details.error = WSAGetLastError(); + return TRUE; + } - return FALSE; + return FALSE; } else if (rd) { if (pio->read_details.remaining || pio->read_details.error) return TRUE; @@ -922,15 +935,15 @@ socketio_on_select(struct w32_io* pio, BOOL rd) SetEvent(pio->read_overlapped.hEvent); return; } - } else { + } else if(sock_state == SOCK_READY) { /* connected socket - WSARecv if needed */ - if ((!pio->read_details.pending) && (!socketio_is_io_available(pio, rd))) - if (socketio_WSARecv(pio, NULL) != 0) { - /* set error, recv() will pick it */ - pio->read_details.error = errno; - errno = 0; - return; - } + if ((!pio->read_details.pending) && (!socketio_is_io_available(pio, rd)) && (socketio_WSARecv(pio, NULL) != 0)) + { + /* set error, recv() will pick it */ + pio->read_details.error = errno; + errno = 0; + return; + } } } diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index 3921fd44e..984ecabc2 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -607,12 +607,10 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep } /* TODO - see if this needs to be supported */ - /* if (exceptfds) { - errno = EOPNOTSUPP; - debug3("select - ERROR: exceptfds not supported"); - DebugBreak(); - return -1; - } */ + if (exceptfds) { + for (i = 0; i < fds; i++) + FD_CLR(i, exceptfds); + } if (readfds) { for (i = 0; i < fds; i++) @@ -691,7 +689,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep } } - /* timeout specified and both fields are 0 - polling mode*/ /* proceed with further wait if not in polling mode*/ if ((timeout == NULL) || (timeout_ms != 0)) @@ -738,26 +735,31 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep /* clear out fds that are not ready yet */ if (readfds) for (i = 0; i < fds; i++) - if (FD_ISSET(i, readfds) && (!FD_ISSET(i, &read_ready_fds))) - FD_CLR(i, readfds); + if (FD_ISSET(i, readfds)) { + if (FD_ISSET(i, &read_ready_fds)) { + /* for connect() initiated sockets finish WSA connect process*/ + if ((fd_table.w32_ios[i]->type == SOCK_FD) && + ((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING))) + if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) { + /* async connect failed, error will be picked up by recv or send */ + errno = 0; + } + } else + FD_CLR(i, readfds); + } if (writefds) for (i = 0; i < fds; i++) if (FD_ISSET(i, writefds)) { if (FD_ISSET(i, &write_ready_fds)) { - /* for connect() completed sockets finish WSA connect process*/ + /* for connect() initiated sockets finish WSA connect process*/ if ((fd_table.w32_ios[i]->type == SOCK_FD) && ((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING))) if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) { - /* finalizeing connect failed - recored error */ - /* error gets picked up later recv and/or send*/ - fd_table.w32_ios[i]->read_details.error = errno; - fd_table.w32_ios[i]->write_details.error = errno; - fd_table.w32_ios[i]->internal.state = SOCK_CONNECTED; + /* async connect failed, error will be picked up by recv or send */ errno = 0; } - } - else + } else FD_CLR(i, writefds); } @@ -847,6 +849,9 @@ w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) pio->type = is_sock ? SOCK_FD : NONSOCK_FD; pio->handle = h; + + /* TODO - get socket state and confirm that its connected */ + pio->internal.state = SOCK_READY; fd_table_set(pio, min_index); return min_index; } diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h index 22f235927..356f89c81 100644 --- a/contrib/win32/win32compat/w32fd.h +++ b/contrib/win32/win32compat/w32fd.h @@ -60,9 +60,8 @@ enum w32_io_type { enum w32_io_sock_state { SOCK_INITIALIZED = 0, SOCK_LISTENING = 1, /*listen called on socket*/ - SOCK_ACCEPTED = 2, /*socket returned from accept()*/ - SOCK_CONNECTING = 3, /*connect called on socket, connect is in progress*/ - SOCK_CONNECTED = 4 /*connect completed on socket*/ + SOCK_CONNECTING = 2, /*connect called on socket, connect is in progress*/ + SOCK_READY = 3 /*recv and send can be done*/ }; /* diff --git a/regress/pesterTests/KeyUtils.Tests.ps1 b/regress/pesterTests/KeyUtils.Tests.ps1 index c26a247d6..9744c9b11 100644 --- a/regress/pesterTests/KeyUtils.Tests.ps1 +++ b/regress/pesterTests/KeyUtils.Tests.ps1 @@ -165,4 +165,31 @@ Describe "E2E scenarios for ssh key management" -Tags "Scenario" { } } + + Context "$tC - ssh-keyscan test cases" { + BeforeAll {$tI=1} + AfterAll{$tC++} + + It "$tC.$tI - ssh-keyscan with default arguments" { + iex "ssh-keyscan -p 22 github.com 2>&1 > out.txt" + 'out.txt' | Should Contain 'github.com ssh-rsa.*' + } + + It "$tC.$tI - ssh-keyscan with -p" { + iex "ssh-keyscan -p 22 github.com 2>&1 > out.txt" + 'out.txt' | Should Contain 'github.com ssh-rsa.*' + } + + It "$tC.$tI - ssh-keyscan with -f" { + Set-Content -Path tmp.txt -Value "github.com" + iex "ssh-keyscan -f tmp.txt 2>&1 > out.txt" + 'out.txt' | Should Contain 'github.com ssh-rsa.*' + } + + It "$tC.$tI - ssh-keyscan with -f -t" { + Set-Content -Path tmp.txt -Value "github.com" + iex "ssh-keyscan -f tmp.txt -t rsa,dsa 2>&1 > out.txt" + 'out.txt' | Should Contain 'github.com ssh-rsa.*' + } + } } diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 7b650d719..d320e4eea 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -66,7 +66,12 @@ int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; int hash_hosts = 0; /* Hash hostname on output */ +#ifdef WINDOWS +#define MAXMAXFD 32 +#else #define MAXMAXFD 256 +#endif // WINDOWS + /* The number of seconds after which to give up on a TCP connection */ int timeout = 5; @@ -390,7 +395,7 @@ confree(int s) { if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) fatal("confree: attempt to free bad fdno %d", s); - close(s); + free(fdcon[s].c_namebase); free(fdcon[s].c_output_name); if (fdcon[s].c_status == CS_KEYS) @@ -401,7 +406,8 @@ confree(int s) ssh_packet_close(fdcon[s].c_ssh); free(fdcon[s].c_ssh); fdcon[s].c_ssh = NULL; - } + } else + close(s); TAILQ_REMOVE(&tq, &fdcon[s], c_link); FD_CLR(s, read_wait); ncon--;