From 776483fb4ef535c7d50b20e37f0f4f077cdf658e Mon Sep 17 00:00:00 2001 From: Manoj Ampalam Date: Tue, 14 Mar 2017 12:36:27 -0700 Subject: [PATCH] Source snapshot from Powershell/openssh-portable:latestw_all --- appveyor.yml | 3 + auth-pam.c | 2 + authfd.c | 49 ----- authfd.h | 2 - channels.c | 48 ++++- clientloop.c | 27 ++- contrib/win32/openssh/appveyor.psm1 | 29 +-- contrib/win32/openssh/config.h.vs | 3 +- contrib/win32/openssh/config.vcxproj | 8 +- contrib/win32/openssh/keygen.vcxproj | 2 - contrib/win32/openssh/libssh.vcxproj | 1 - contrib/win32/openssh/libssh.vcxproj.filters | 3 - contrib/win32/openssh/scp.vcxproj | 2 - contrib/win32/openssh/sftp-server.vcxproj | 2 - contrib/win32/openssh/sftp.vcxproj | 2 - contrib/win32/openssh/ssh-add.vcxproj | 2 - contrib/win32/openssh/ssh-agent.vcxproj | 2 - contrib/win32/openssh/ssh-lsa.vcxproj | 2 - contrib/win32/openssh/ssh-shellhost.vcxproj | 2 - contrib/win32/openssh/ssh.vcxproj | 2 - contrib/win32/openssh/sshd.vcxproj | 2 - contrib/win32/openssh/unittest-bitmap.vcxproj | 14 +- .../win32/openssh/unittest-hostkeys.vcxproj | 16 +- contrib/win32/openssh/unittest-kex.vcxproj | 8 +- contrib/win32/openssh/unittest-match.vcxproj | 8 +- contrib/win32/openssh/unittest-sshbuf.vcxproj | 12 +- contrib/win32/openssh/unittest-sshkey.vcxproj | 16 +- contrib/win32/openssh/unittest-utf8.vcxproj | 8 +- .../openssh/unittest-win32compat.vcxproj | 8 +- contrib/win32/openssh/version.rc | Bin 4046 -> 4066 bytes contrib/win32/openssh/win32iocompat.vcxproj | 3 + .../openssh/win32iocompat.vcxproj.filters | 3 + contrib/win32/win32compat/ansiprsr.c | 57 +++--- contrib/win32/win32compat/console.c | 183 +++++++++++++----- contrib/win32/win32compat/console.h | 110 +++++------ contrib/win32/win32compat/fileio.c | 77 ++++++++ contrib/win32/win32compat/inc/stdio.h | 7 +- contrib/win32/win32compat/inc/sys/un.h | 10 +- contrib/win32/win32compat/misc.c | 75 ++++++- contrib/win32/win32compat/misc_internal.h | 3 +- contrib/win32/win32compat/shell-host.c | 104 +++++++--- contrib/win32/win32compat/ssh-agent/agent.h | 2 +- contrib/win32/win32compat/termio.c | 20 +- contrib/win32/win32compat/tncon.c | 136 ++++++------- contrib/win32/win32compat/tnnet.c | 21 +- contrib/win32/win32compat/tnnet.h | 6 +- contrib/win32/win32compat/w32fd.c | 41 +++- contrib/win32/win32compat/w32fd.h | 2 + contrib/win32/win32compat/win32-utf8.c | 54 ++++++ contrib/win32/win32compat/wmain_common.c | 6 +- contrib/win32/win32compat/wmain_sshd.c | 3 + digest-openssl.c | 4 +- hostfile.c | 19 +- kex.c | 19 +- log.c | 5 +- match.c | 19 +- packet.c | 8 +- readconf.c | 7 +- regress/test-exec.sh | 4 +- regress/unittests/utf8/tests.c | 65 ++++--- scp.c | 20 -- servconf.c | 4 +- session.c | 9 +- sftp.c | 127 +++--------- ssh-keygen.c | 42 ++-- ssh-keyscan.c | 14 +- ssh.c | 10 +- ssh_config.5 | 6 +- sshconnect.c | 4 +- sshconnect1.c | 8 +- sshd.c | 10 +- sshkey.c | 64 +++++- sshkey.h | 4 +- sshtty.c | 8 +- utf8.c | 12 +- 75 files changed, 1045 insertions(+), 655 deletions(-) create mode 100644 contrib/win32/win32compat/win32-utf8.c diff --git a/appveyor.yml b/appveyor.yml index 46186a6..1650a6f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,6 +16,7 @@ build_script: after_build: - ps: | + Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Install-OpenSSH - ps: Write-Verbose "Restart computer ..." - ps: Restart-Computer -Force @@ -37,8 +38,10 @@ test_script: after_test: - ps: | + Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Upload-OpenSSHTestResults on_finish: - ps: | + Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Publish-Artifact diff --git a/auth-pam.c b/auth-pam.c index 7d8b292..bc8e5e0 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -830,6 +830,8 @@ fake_password(const char *wire_password) fatal("%s: password length too long: %zu", __func__, l); ret = malloc(l + 1); + if (ret == NULL) + return NULL; for (i = 0; i < l; i++) ret[i] = junk[i % (sizeof(junk) - 1)]; ret[i] = '\0'; diff --git a/authfd.c b/authfd.c index 63614c9..2fd857d 100644 --- a/authfd.c +++ b/authfd.c @@ -94,54 +94,6 @@ ssh_get_authentication_socket(int *fdp) if (fdp != NULL) *fdp = -1; -#ifdef WINDOWS - /* Auth socket in Windows is a static-named pipe listener in ssh-agent */ - { - HKEY agent_root = 0; - DWORD agent_pid = 0, tmp_size = 4, pipe_server_pid = 0xff; - DWORD connection_attempts = 0; - HANDLE h; - RegOpenKeyExW(HKEY_LOCAL_MACHINE, SSH_AGENT_REG_ROOT, - 0, KEY_QUERY_VALUE, &agent_root); - if (agent_root) { - RegQueryValueEx(agent_root, "ProcessId", 0, - NULL, (LPBYTE)&agent_pid, &tmp_size); - RegCloseKey(agent_root); - } - - do { - h = CreateFileW(SSH_AGENT_PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if (h != INVALID_HANDLE_VALUE || GetLastError() != ERROR_PIPE_BUSY || - ++connection_attempts > 10) - break; - Sleep(100); - } while(1); - - if (h == INVALID_HANDLE_VALUE) { - debug("ssh_get_authentication_socket - CreateFileW failed error %d", - GetLastError()); - return SSH_ERR_AGENT_NOT_PRESENT; - } - - /* - * ensure that connected server pid matches published pid. - * this provides service side auth and prevents mitm - */ - if (!GetNamedPipeServerProcessId(h, &pipe_server_pid) || - (agent_pid != pipe_server_pid)) { - debug("agent pid mismatch"); - CloseHandle(h); - return SSH_ERR_AGENT_COMMUNICATION; - } - - /* alloc fd for pipe handle */ - if ((sock = w32_allocate_fd_for_handle(h, FALSE)) < 0) { - CloseHandle(h); - return SSH_ERR_SYSTEM_ERROR; - } - } -#else /* !WINDOWS */ authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); if (!authsocket) return SSH_ERR_AGENT_NOT_PRESENT; @@ -161,7 +113,6 @@ ssh_get_authentication_socket(int *fdp) errno = oerrno; return SSH_ERR_SYSTEM_ERROR; } -#endif /* !WINDOWS */ if (fdp != NULL) *fdp = sock; diff --git a/authfd.h b/authfd.h index 4681479..38cffaf 100644 --- a/authfd.h +++ b/authfd.h @@ -96,7 +96,5 @@ int ssh_agent_sign(int sock, struct sshkey *key, #define SSH_AGENT_AUTHENTICATE 200 #define PUBKEY_AUTH_REQUEST "pubkey" #define PASSWD_AUTH_REQUEST "password" -#define SSH_AGENT_REG_ROOT L"SOFTWARE\\SSH\\Agent" -#define SSH_AGENT_PIPE_NAME L"\\\\.\\pipe\\ssh-agent" #endif /* AUTHFD_H */ diff --git a/channels.c b/channels.c index ddd2b24..431e0ea 100644 --- a/channels.c +++ b/channels.c @@ -4375,6 +4375,33 @@ connect_local_xsocket(u_int dnr) return connect_local_xsocket_path(buf); } +#ifdef __APPLE__ +static int +is_path_to_xsocket(const char *display, char *path, size_t pathlen) +{ + struct stat sbuf; + + if (strlcpy(path, display, pathlen) >= pathlen) { + error("%s: display path too long", __func__); + return 0; + } + if (display[0] != '/') + return 0; + if (stat(path, &sbuf) == 0) { + return 1; + } else { + char *dot = strrchr(path, '.'); + if (dot != NULL) { + *dot = '\0'; + if (stat(path, &sbuf) == 0) { + return 1; + } + } + } + return 0; +} +#endif + int x11_connect_display(void) { @@ -4396,15 +4423,22 @@ x11_connect_display(void) * connection to the real X server. */ - /* Check if the display is from launchd. */ #ifdef __APPLE__ - if (strncmp(display, "/tmp/launch", 11) == 0) { - sock = connect_local_xsocket_path(display); - if (sock < 0) - return -1; + /* Check if display is a path to a socket (as set by launchd). */ + { + char path[PATH_MAX]; - /* OK, we now have a connection to the display. */ - return sock; + if (is_path_to_xsocket(display, path, sizeof(path))) { + debug("x11_connect_display: $DISPLAY is launchd"); + + /* Create a socket. */ + sock = connect_local_xsocket_path(path); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } } #endif /* diff --git a/clientloop.c b/clientloop.c index 5a21387..6f317e0 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.290 2017/01/29 21:35:23 dtucker Exp $ */ +/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -2394,6 +2394,26 @@ client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) hostkeys_update_ctx_free(ctx); } +/* + * Returns non-zero if the key is accepted by HostkeyAlgorithms. + * Made slightly less trivial by the multiple RSA signature algorithm names. + */ +static int +key_accepted_by_hostkeyalgs(const struct sshkey *key) +{ + const char *ktype = sshkey_ssh_name(key); + const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? + options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG; + + if (key == NULL || key->type == KEY_UNSPEC) + return 0; + if (key->type == KEY_RSA && + (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 || + match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1)) + return 1; + return match_pattern_list(ktype, hostkeyalgs, 0) == 1; +} + /* * Handle hostkeys-00@openssh.com global request to inform the client of all * the server's hostkeys. The keys are checked against the user's @@ -2440,10 +2460,7 @@ client_input_hostkeys(void) sshkey_type(key), fp); free(fp); - /* Check that the key is accepted in HostkeyAlgorithms */ - if (match_pattern_list(sshkey_ssh_name(key), - options.hostkeyalgorithms ? options.hostkeyalgorithms : - KEX_DEFAULT_PK_ALG, 0) != 1) { + if (!key_accepted_by_hostkeyalgs(key)) { debug3("%s: %s key not permitted by HostkeyAlgorithms", __func__, sshkey_ssh_name(key)); continue; diff --git a/contrib/win32/openssh/appveyor.psm1 b/contrib/win32/openssh/appveyor.psm1 index 8d6eb7e..331913e 100644 --- a/contrib/win32/openssh/appveyor.psm1 +++ b/contrib/win32/openssh/appveyor.psm1 @@ -497,16 +497,16 @@ function Deploy-OpenSSHTests else { $RealConfiguration = $Configuration - } - + } [System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot #copy all pester tests $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests" Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1, sshd_config -Force -ErrorAction Stop #copy all unit tests. - $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration" - Copy-Item -Path "$sourceDir\unittest-*" -Destination $OpenSSHTestDir -Force -ErrorAction Stop + $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration" + Copy-Item -Path "$sourceDir\*" -Destination "$OpenSSHTestDir\" -Container -Include unittest-* -Recurse -Force -ErrorAction Stop + #restart the service to use the test copy of sshd_config Restart-Service sshd } @@ -668,14 +668,18 @@ function Run-OpenSSHUnitTest { Remove-Item -Path $unitTestOutputFile -Force -ErrorAction SilentlyContinue } - - $unitTestFiles = Get-ChildItem -Path "$testRoot\unittest*.exe" -Exclude unittest-kex.exe,unittest-hostkeys.exe + $testFolders = Get-ChildItem unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe | + ForEach-Object{ Split-Path $_.FullName} | + Sort-Object -Unique $testfailed = $false - if ($unitTestFiles -ne $null) - { - $unitTestFiles | % { - Write-Output "Running OpenSSH unit $($_.FullName)..." - & $_.FullName >> $unitTestOutputFile + if ($testFolders -ne $null) + { + $testFolders | % { + Push-Location $_ + $unittestFile = "$(Split-Path $_ -Leaf).exe" + Write-Output "Running OpenSSH unit $unittestFile ..." + & .\$unittestFile >> $unitTestOutputFile + $errorCode = $LASTEXITCODE if ($errorCode -ne 0) { @@ -685,6 +689,7 @@ function Run-OpenSSHUnitTest Write-BuildMessage -Message $errorMessage -Category Error Set-BuildVariable TestPassed False } + Pop-Location } if(-not $testfailed) { @@ -747,7 +752,7 @@ function Upload-OpenSSHTestResults if($env:TestPassed -ieq 'True') { - Write-BuildMessage -Message "The checkin validation success!" + Write-BuildMessage -Message "The checkin validation success!" -Category Information } else { diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs index b4d4878..28592f7 100644 --- a/contrib/win32/openssh/config.h.vs +++ b/contrib/win32/openssh/config.h.vs @@ -1080,7 +1080,7 @@ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_UN_H */ +#define HAVE_SYS_UN_H 1 /* Define to 1 if you have the `tcgetpgrp' function. */ /* #undef HAVE_TCGETPGRP */ @@ -1641,7 +1641,6 @@ #undef HAVE_SYS_CDEFS_H #undef HAVE_SYS_SYSMACROS_H #undef HAVE_SYS_MMAN_H -#undef HAVE_SYS_UN_H #define _STRUCT_WINSIZE 1 #define HAVE_TCGETPGRP 1 diff --git a/contrib/win32/openssh/config.vcxproj b/contrib/win32/openssh/config.vcxproj index 45d6ca4..9bf9ee2 100644 --- a/contrib/win32/openssh/config.vcxproj +++ b/contrib/win32/openssh/config.vcxproj @@ -115,7 +115,7 @@ powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' - Setup config.h in openssh source path for visual studio + Generate crtheaders.h and config.h @@ -139,7 +139,7 @@ powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' - Setup config.h in openssh source path for visual studio + Generate crtheaders.h and config.h @@ -167,7 +167,7 @@ powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' - Setup config.h in openssh source path for visual studio + Generate crtheaders.h and config.h @@ -195,7 +195,7 @@ powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' - Setup config.h in openssh source path for visual studio + Generate crtheaders.h and config.h diff --git a/contrib/win32/openssh/keygen.vcxproj b/contrib/win32/openssh/keygen.vcxproj index 1f8171c..690ec33 100644 --- a/contrib/win32/openssh/keygen.vcxproj +++ b/contrib/win32/openssh/keygen.vcxproj @@ -157,7 +157,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No @@ -182,7 +181,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No diff --git a/contrib/win32/openssh/libssh.vcxproj b/contrib/win32/openssh/libssh.vcxproj index 1205b58..16fff96 100644 --- a/contrib/win32/openssh/libssh.vcxproj +++ b/contrib/win32/openssh/libssh.vcxproj @@ -283,7 +283,6 @@ - true diff --git a/contrib/win32/openssh/libssh.vcxproj.filters b/contrib/win32/openssh/libssh.vcxproj.filters index efb660e..1959987 100644 --- a/contrib/win32/openssh/libssh.vcxproj.filters +++ b/contrib/win32/openssh/libssh.vcxproj.filters @@ -282,9 +282,6 @@ Source Files - - Source Files - Source Files diff --git a/contrib/win32/openssh/scp.vcxproj b/contrib/win32/openssh/scp.vcxproj index 0ad73c8..7a92254 100644 --- a/contrib/win32/openssh/scp.vcxproj +++ b/contrib/win32/openssh/scp.vcxproj @@ -162,7 +162,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No @@ -187,7 +186,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No diff --git a/contrib/win32/openssh/sftp-server.vcxproj b/contrib/win32/openssh/sftp-server.vcxproj index 2574f3b..d08af44 100644 --- a/contrib/win32/openssh/sftp-server.vcxproj +++ b/contrib/win32/openssh/sftp-server.vcxproj @@ -166,7 +166,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No @@ -191,7 +190,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No diff --git a/contrib/win32/openssh/sftp.vcxproj b/contrib/win32/openssh/sftp.vcxproj index 3b7f9b3..b558033 100644 --- a/contrib/win32/openssh/sftp.vcxproj +++ b/contrib/win32/openssh/sftp.vcxproj @@ -168,7 +168,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No @@ -193,7 +192,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No diff --git a/contrib/win32/openssh/ssh-add.vcxproj b/contrib/win32/openssh/ssh-add.vcxproj index 462f004..8ed9e90 100644 --- a/contrib/win32/openssh/ssh-add.vcxproj +++ b/contrib/win32/openssh/ssh-add.vcxproj @@ -167,7 +167,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No @@ -192,7 +191,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) wmainCRTStartup true - No diff --git a/contrib/win32/openssh/ssh-agent.vcxproj b/contrib/win32/openssh/ssh-agent.vcxproj index d5f3b45..cc29c3a 100644 --- a/contrib/win32/openssh/ssh-agent.vcxproj +++ b/contrib/win32/openssh/ssh-agent.vcxproj @@ -164,7 +164,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) Netapi32.lib;Crypt32.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) true - No targetos.manifest @@ -191,7 +190,6 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) Netapi32.lib;Crypt32.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) true - No targetos.manifest diff --git a/contrib/win32/openssh/ssh-lsa.vcxproj b/contrib/win32/openssh/ssh-lsa.vcxproj index 713ffa6..899782a 100644 --- a/contrib/win32/openssh/ssh-lsa.vcxproj +++ b/contrib/win32/openssh/ssh-lsa.vcxproj @@ -159,7 +159,6 @@ $(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) ssh-lsa.def true - No @@ -184,7 +183,6 @@ $(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) ssh-lsa.def true - No diff --git a/contrib/win32/openssh/ssh-shellhost.vcxproj b/contrib/win32/openssh/ssh-shellhost.vcxproj index d431618..e5c1602 100644 --- a/contrib/win32/openssh/ssh-shellhost.vcxproj +++ b/contrib/win32/openssh/ssh-shellhost.vcxproj @@ -160,7 +160,6 @@ openbsd_compat.lib;kernel32.lib;user32.lib;%(AdditionalDependencies) $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) true - No @@ -184,7 +183,6 @@ true openbsd_compat.lib;kernel32.lib;user32.lib;%(AdditionalDependencies) true - No $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) diff --git a/contrib/win32/openssh/ssh.vcxproj b/contrib/win32/openssh/ssh.vcxproj index 9502e85..f3297a1 100644 --- a/contrib/win32/openssh/ssh.vcxproj +++ b/contrib/win32/openssh/ssh.vcxproj @@ -167,7 +167,6 @@ 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) wmainCRTStartup true - No targetos.manifest @@ -195,7 +194,6 @@ 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) wmainCRTStartup true - No targetos.manifest diff --git a/contrib/win32/openssh/sshd.vcxproj b/contrib/win32/openssh/sshd.vcxproj index 80e6ae4..1410453 100644 --- a/contrib/win32/openssh/sshd.vcxproj +++ b/contrib/win32/openssh/sshd.vcxproj @@ -166,7 +166,6 @@ MultiplyDefinedSymbolOnly wmainCRTStartup true - No targetos.manifest @@ -196,7 +195,6 @@ MultiplyDefinedSymbolOnly wmainCRTStartup true - No targetos.manifest diff --git a/contrib/win32/openssh/unittest-bitmap.vcxproj b/contrib/win32/openssh/unittest-bitmap.vcxproj index f99eac1..cc462ef 100644 --- a/contrib/win32/openssh/unittest-bitmap.vcxproj +++ b/contrib/win32/openssh/unittest-bitmap.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-bitmap $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-bitmap $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -160,7 +160,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -186,7 +186,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -199,13 +199,13 @@ - true + true - true + true - true + true diff --git a/contrib/win32/openssh/unittest-hostkeys.vcxproj b/contrib/win32/openssh/unittest-hostkeys.vcxproj index 247e56d..477e59a 100644 --- a/contrib/win32/openssh/unittest-hostkeys.vcxproj +++ b/contrib/win32/openssh/unittest-hostkeys.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-hostkeys $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-hostkeys $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -123,7 +123,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir)hostkeys\ @@ -149,7 +149,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir)hostkeys\ @@ -166,7 +166,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -177,7 +177,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) @@ -195,7 +195,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -206,7 +206,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) diff --git a/contrib/win32/openssh/unittest-kex.vcxproj b/contrib/win32/openssh/unittest-kex.vcxproj index d714584..a133038 100644 --- a/contrib/win32/openssh/unittest-kex.vcxproj +++ b/contrib/win32/openssh/unittest-kex.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-kex $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-kex $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -160,7 +160,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -186,7 +186,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) diff --git a/contrib/win32/openssh/unittest-match.vcxproj b/contrib/win32/openssh/unittest-match.vcxproj index c874918..7e0f421 100644 --- a/contrib/win32/openssh/unittest-match.vcxproj +++ b/contrib/win32/openssh/unittest-match.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-match $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-match $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -160,7 +160,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -186,7 +186,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) diff --git a/contrib/win32/openssh/unittest-sshbuf.vcxproj b/contrib/win32/openssh/unittest-sshbuf.vcxproj index c70c2cf..a63568c 100644 --- a/contrib/win32/openssh/unittest-sshbuf.vcxproj +++ b/contrib/win32/openssh/unittest-sshbuf.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-sshbuf $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-sshbuf $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -160,7 +160,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -186,7 +186,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -204,10 +204,10 @@ - true + true - true + true diff --git a/contrib/win32/openssh/unittest-sshkey.vcxproj b/contrib/win32/openssh/unittest-sshkey.vcxproj index 03eea3f..c3ac4b5 100644 --- a/contrib/win32/openssh/unittest-sshkey.vcxproj +++ b/contrib/win32/openssh/unittest-sshkey.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-sshkey $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-sshkey $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -123,7 +123,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir)sshkey\ @@ -149,7 +149,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir)sshkey\ @@ -166,7 +166,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -177,7 +177,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) @@ -195,7 +195,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -206,7 +206,7 @@ targetos.manifest - copy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) diff --git a/contrib/win32/openssh/unittest-utf8.vcxproj b/contrib/win32/openssh/unittest-utf8.vcxproj index 62aef0c..d6cb3b2 100644 --- a/contrib/win32/openssh/unittest-utf8.vcxproj +++ b/contrib/win32/openssh/unittest-utf8.vcxproj @@ -87,14 +87,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-utf8 $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-utf8 $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -160,7 +160,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -186,7 +186,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) diff --git a/contrib/win32/openssh/unittest-win32compat.vcxproj b/contrib/win32/openssh/unittest-win32compat.vcxproj index 4eaef80..a522687 100644 --- a/contrib/win32/openssh/unittest-win32compat.vcxproj +++ b/contrib/win32/openssh/unittest-win32compat.vcxproj @@ -94,14 +94,14 @@ false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-win32compat $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); false - $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\$(TargetName)\ $(Platform)\$(Configuration)\$(TargetName)\ unittest-win32compat $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -167,7 +167,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories) @@ -193,7 +193,7 @@ Console - No + true true true $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories) diff --git a/contrib/win32/openssh/version.rc b/contrib/win32/openssh/version.rc index 28e97ef7a795cdf62d313161195af165e35d58be..8b8517b6b3a6b313d9afcc0c4c4e658f2c5f45b3 100644 GIT binary patch delta 111 zcmX>n|44qrBo1an27}3yISfJc=A#^vOkjb9+|rX5aB)mF;NhDrz%8fh&rraS%8_To`76ABI8Sel9 delta 78 zcmaDPe@=eGBo0Q)$x}HD87()T + @@ -203,6 +204,8 @@ + + diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters index 07a88fa..77a05a3 100644 --- a/contrib/win32/openssh/win32iocompat.vcxproj.filters +++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters @@ -19,6 +19,7 @@ + @@ -138,6 +139,8 @@ inc + + diff --git a/contrib/win32/win32compat/ansiprsr.c b/contrib/win32/win32compat/ansiprsr.c index f2e99bc..e5344e8 100644 --- a/contrib/win32/win32compat/ansiprsr.c +++ b/contrib/win32/win32compat/ansiprsr.c @@ -48,14 +48,12 @@ extern int ScreenX; extern int ScreenY; extern int ScrollTop; extern int ScrollBottom; -extern BOOL bAnsiParsing; bool gbVTAppMode = false; /* private message for port printing to */ unsigned char VT_ST[] = { 0x1b, '/', '\0' }; static int AutoWrap = 1; BOOL bAtEOLN = FALSE; -static int term_mode = TERM_ANSI; /* * ParseANSI globals - these need to be here, because sometimes blocks are sent @@ -142,12 +140,24 @@ BufConvertToG2(char * pszBuffer, int length) void GoToNextLine() { - if (ConGetCursorY() >= (ConWindowSizeY() - 1)) { - ConScrollDown(ScrollTop, ScrollBottom); - ConMoveCursorPosition(-ConGetCursorX(), 0); - } - else - ConMoveCursorPosition(-ConGetCursorX(), 1); + int currentX = 0; + int currentY = 0; + + ConGetCursorPosition(¤tX, ¤tY); + + /* If the cursor is the last line of the visible window */ + if (is_cursor_at_lastline_of_visible_window()) { + if (currentY >= ConGetBufferHeight()) { + /* handle the max window buffer size */ + ConScrollDown(0, currentY); + ConMoveCursorPosition(-currentX, 0); + } else { + /* max window buffer is not breached */ + ConMoveVisibleWindow(1); + ConMoveCursorPosition(-currentX, 1); + } + } else /* If the cursor is NOT the last line of the visible window */ + ConMoveCursorPosition(-currentX, 1); bAtEOLN = FALSE; } @@ -155,8 +165,8 @@ GoToNextLine() unsigned char* ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char **respbuf, size_t *resplen) { - int CurrentX; - int CurrentY; + int currentX; + int currentY; int bufLen, cmpLen, i; if (!fcompletion) { @@ -164,8 +174,7 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char unsigned char * pszCurrent = pszBuffer + 1; unsigned char * pszNewCurrent = pszCurrent; - if (term_mode == TERM_ANSI && bAnsiParsing) - pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen); + pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen); /* Pointer didn't move inside Parse function */ if (pszCurrent == pszNewCurrent) { @@ -200,8 +209,8 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char case 8: pszBuffer++; if (!bAtEOLN) { - CurrentX = ConGetCursorX(); - if (CurrentX == 0) { + currentX = ConGetCursorX(); + if (currentX == 0) { ConMoveCursorPosition(ScreenX - 1, -1); ConWriteString(" ", 1); } else { @@ -263,10 +272,8 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char if (*pszCurrent == 27) { pszNewCurrent += ConWriteString((char *)pszCurrent, 1); return pszBuffer + 1; - } else { - if (term_mode == TERM_ANSI) - pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen); - } + } else + pszNewCurrent = ParseANSI(pszCurrent, pszBufferEnd, respbuf, resplen); if (pszNewCurrent > pszCurrent) pszBuffer = pszNewCurrent; @@ -278,12 +285,12 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char if (bAtEOLN) GoToNextLine(); unsigned char* pszCurrent = pszBuffer; - CurrentX = ConGetCursorX(); + currentX = ConGetCursorX(); int nCharCount = 0; while ((pszCurrent < pszBufferEnd) && (*pszCurrent != (unsigned char)27) && (*pszCurrent > (unsigned char)15) && (*pszCurrent != (unsigned char)255) - && (CurrentX++ < ScreenX)) { + && (currentX++ < ScreenX)) { if (*pszCurrent > 127) { unsigned char nLead = *pszCurrent; nCharCount++; @@ -305,7 +312,7 @@ ParseBuffer(unsigned char* pszBuffer, unsigned char* pszBufferEnd, unsigned char pszBuffer += ConWriteString((char *)pszBuffer, (int)(pszCurrent - pszBuffer)); - if ((CurrentX >= ScreenX) && AutoWrap && !(VTMode & MODE_CURSORAPP)) + if ((currentX >= ScreenX) && AutoWrap && !(VTMode & MODE_CURSORAPP)) bAtEOLN = TRUE; } break; @@ -561,10 +568,10 @@ ParseANSI(unsigned char * pszBuffer, unsigned char * pszBufferEnd, unsigned char if (iParam[0]) { int i; for (i = 0; i < iParam[0]; i++) - ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConWindowSizeY() - 2); + ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConVisibleWindowHeight() - 2); } else { - if (ConGetCursorY() <= ScrollTop + ConWindowSizeY() - 2) - ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConWindowSizeY() - 2); + if (ConGetCursorY() <= ScrollTop + ConVisibleWindowHeight() - 2) + ConScrollUp(ConGetCursorY() - 1, ScrollTop + ConVisibleWindowHeight() - 2); } fcompletion = 1; bAtEOLN = FALSE; @@ -600,7 +607,7 @@ ParseANSI(unsigned char * pszBuffer, unsigned char * pszBufferEnd, unsigned char for (i = 0; i < iParam[0]; i++) ConScrollUp(ConGetCursorY(), ScrollTop - ConGetCursorY()); } else { - if (ConGetCursorY() <= ScrollTop + ConWindowSizeY() - 2) + if (ConGetCursorY() <= ScrollTop + ConVisibleWindowHeight() - 2) ConScrollUp(ConGetCursorY(), ScrollTop - ConGetCursorY()); } fcompletion = 1; diff --git a/contrib/win32/win32compat/console.c b/contrib/win32/win32compat/console.c index eb6b717..7ec2eeb 100644 --- a/contrib/win32/win32compat/console.c +++ b/contrib/win32/win32compat/console.c @@ -52,13 +52,14 @@ int ScrollTop; int ScrollBottom; int LastCursorX; int LastCursorY; -BOOL bAnsiParsing = FALSE; +BOOL isAnsiParsingRequired = FALSE; char *pSavedScreen = NULL; static COORD ZeroCoord = { 0,0 }; COORD SavedScreenSize = { 0,0 }; COORD SavedScreenCursor = { 0, 0 }; SMALL_RECT SavedViewRect = { 0,0,0,0 }; CONSOLE_SCREEN_BUFFER_INFOEX SavedWindowState; +BOOL isConHostParserEnabled = TRUE; typedef struct _SCREEN_RECORD { PCHAR_INFO pScreenBuf; @@ -69,10 +70,11 @@ typedef struct _SCREEN_RECORD { PSCREEN_RECORD pSavedScreenRec = NULL; int in_raw_mode = 0; +char *consoleTitle = "Microsoft openSSH client"; -/* Used to Initialize the Console for output */ +/* Used to enter the raw mode */ int -ConInit(DWORD OutputHandle, BOOL fSmartInit) +ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit) { OSVERSIONINFO os; DWORD dwAttributes = 0; @@ -87,16 +89,18 @@ ConInit(DWORD OutputHandle, BOOL fSmartInit) hOutputConsole = GetStdHandle(OutputHandle); if (hOutputConsole == INVALID_HANDLE_VALUE) { dwRet = GetLastError(); - printf("GetStdHandle on OutputHandle failed with %d\n", dwRet); + error("GetStdHandle on OutputHandle failed with %d\n", dwRet); return dwRet; } if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &dwSavedAttributes)) { dwRet = GetLastError(); - printf("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet); + error("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet); return dwRet; } + SetConsoleTitle(consoleTitle); + dwAttributes = dwSavedAttributes; dwAttributes &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); @@ -104,53 +108,69 @@ ConInit(DWORD OutputHandle, BOOL fSmartInit) if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwAttributes)) { /* Windows NT */ dwRet = GetLastError(); - printf("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet); + error("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet); return dwRet; } if (!GetConsoleMode(hOutputConsole, &dwAttributes)) { dwRet = GetLastError(); - printf("GetConsoleMode on hOutputConsole failed with %d\n", dwRet); + error("GetConsoleMode on hOutputConsole failed with %d\n", dwRet); return dwRet; + } dwAttributes |= (DWORD)ENABLE_VIRTUAL_TERMINAL_PROCESSING; - if (!SetConsoleMode(hOutputConsole, dwAttributes)) /* Windows NT */ - bAnsiParsing = TRUE; + if (NULL != getenv("SSH_TERM_CONHOST_PARSER")) + isConHostParserEnabled = atoi(getenv("SSH_TERM_CONHOST_PARSER")); + + /* We use our custom ANSI parser when + * a) User sets the environment variable "SSH_TERM_CONHOST_PARSER" to 0 + * b) or when the console doesn't have the inbuilt capability to parse the ANSI/Xterm raw buffer. + */ + if (FALSE == isConHostParserEnabled || !SetConsoleMode(hOutputConsole, dwAttributes)) /* Windows NT */ + isAnsiParsingRequired = TRUE; + + GetConsoleScreenBufferInfo(hOutputConsole, &csbi); + + /* if we are passing rawbuffer to console then we need to move the cursor to top + * so that the clearscreen will not erase any lines. + */ + if (TRUE == isAnsiParsingRequired) { + SavedViewRect = csbi.srWindow; + debug("console doesn't support the ansi parsing"); + } else { + ConMoveCurosorTop(csbi); + debug("console supports the ansi parsing"); + } ConSetScreenX(); ConSetScreenY(); ScrollTop = 0; - ScrollBottom = ConWindowSizeY(); - - if (GetConsoleScreenBufferInfo(hOutputConsole, &csbi)) - SavedViewRect = csbi.srWindow; - + ScrollBottom = ConVisibleWindowHeight(); + in_raw_mode = 1; + return 0; } /* Used to Uninitialize the Console */ int -ConUnInit(void) +ConExitRawMode() { CONSOLE_SCREEN_BUFFER_INFO consoleInfo; in_raw_mode = 0; - if (hOutputConsole == NULL) + if (hOutputConsole == NULL || !GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) return 0; - - if (!GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) - return 0; - + SetConsoleMode(hOutputConsole, dwSavedAttributes); return 0; } -/* Used to Uninitialize the Console */ +/* Used to exit the raw mode */ int -ConUnInitWithRestore(void) +ConUnInitWithRestore() { DWORD dwWritten; COORD Coord; @@ -446,9 +466,9 @@ ConScreenSizeY() return (consoleInfo.srWindow.Bottom - consoleInfo.srWindow.Top + 1); } -/* returns visible size of screen window */ +/* returns width of visible window */ int -ConWindowSizeX() +ConVisibleWindowWidth() { CONSOLE_SCREEN_BUFFER_INFO consoleInfo; @@ -458,9 +478,9 @@ ConWindowSizeX() return (consoleInfo.srWindow.Right - consoleInfo.srWindow.Left + 1); } -/* returns visible size of screen window */ +/* returns height of visible window */ int -ConWindowSizeY() +ConVisibleWindowHeight() { CONSOLE_SCREEN_BUFFER_INFO consoleInfo; @@ -837,7 +857,7 @@ ConDisplayCursor(BOOL bVisible) } void -ConClearScreen(void) +ConClearScreen() { DWORD dwWritten; COORD Coord; @@ -850,7 +870,7 @@ ConClearScreen(void) Coord.X = 0; Coord.Y = 0; - DWORD dwNumChar = (consoleInfo.srWindow.Bottom + 1) * (consoleInfo.srWindow.Right + 1); + DWORD dwNumChar = (consoleInfo.dwSize.Y) * (consoleInfo.dwSize.X); FillConsoleOutputCharacter(hOutputConsole, ' ', dwNumChar, Coord, &dwWritten); FillConsoleOutputAttribute(hOutputConsole, consoleInfo.wAttributes, dwNumChar, Coord, &dwWritten); srcWindow = consoleInfo.srWindow; @@ -1055,11 +1075,25 @@ ConScrollUp(int topline, int botline) ); } +void +ConMoveVisibleWindow(int offset) +{ + CONSOLE_SCREEN_BUFFER_INFO consoleInfo; + SMALL_RECT visibleWindowRect; + + if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) { + memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect)); + visibleWindowRect.Top += offset; + visibleWindowRect.Bottom += offset; + + SetConsoleWindowInfo(hOutputConsole, TRUE, &visibleWindowRect); + } +} + void ConScrollDown(int topline, int botline) { - SMALL_RECT ScrollRect; - SMALL_RECT ClipRect; + SMALL_RECT ScrollRect; COORD destination; CHAR_INFO Fill; CONSOLE_SCREEN_BUFFER_INFO consoleInfo; @@ -1078,11 +1112,6 @@ ConScrollDown(int topline, int botline) ScrollRect.Left = 0; ScrollRect.Right = ConScreenSizeX() - 1; - ClipRect.Top = ScrollRect.Top; - ClipRect.Bottom = ScrollRect.Bottom; - ClipRect.Left = ScrollRect.Left; - ClipRect.Right = ScrollRect.Right; - destination.X = 0; destination.Y = ScrollRect.Top - 1; @@ -1152,6 +1181,17 @@ ConChangeCursor(CONSOLE_CURSOR_INFO *pCursorInfo) return SetConsoleCursorInfo(hOutputConsole, pCursorInfo); } +void +ConGetCursorPosition(int *x, int *y) +{ + CONSOLE_SCREEN_BUFFER_INFO consoleInfo; + + if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) { + *x = consoleInfo.dwCursorPosition.X; + *y = consoleInfo.dwCursorPosition.Y; + } +} + int ConGetCursorX() { @@ -1163,6 +1203,21 @@ ConGetCursorX() return consoleInfo.dwCursorPosition.X; } +int +is_cursor_at_lastline_of_visible_window() +{ + CONSOLE_SCREEN_BUFFER_INFO consoleInfo; + int return_val = 0; + + if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) { + int cursor_linenum_in_visible_window = consoleInfo.dwCursorPosition.Y - consoleInfo.srWindow.Top; + if (cursor_linenum_in_visible_window >= ConVisibleWindowHeight() - 1) + return_val = 1; + } + + return return_val; +} + int ConGetCursorY() { @@ -1175,14 +1230,14 @@ ConGetCursorY() } int -ConGetCursorInBufferY() +ConGetBufferHeight() { CONSOLE_SCREEN_BUFFER_INFO consoleInfo; if (!GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) return 0; - return (consoleInfo.dwCursorPosition.Y); + return (consoleInfo.dwSize.Y - 1); } void @@ -1390,28 +1445,53 @@ ConDeleteScreenHandle(SCREEN_HANDLE hScreen) /* Restores Previous Saved screen info and buffer */ BOOL -ConRestoreScreen(void) +ConRestoreScreen() { return ConRestoreScreenHandle(pSavedScreenRec); } /* Saves current screen info and buffer */ -BOOL -ConSaveScreen(void) +void +ConSaveScreen() { - pSavedScreenRec = (PSCREEN_RECORD)ConSaveScreenHandle(pSavedScreenRec); - return TRUE; + pSavedScreenRec = (PSCREEN_RECORD)ConSaveScreenHandle(pSavedScreenRec); } void -ConSaveViewRect(void) +ConSaveViewRect() { CONSOLE_SCREEN_BUFFER_INFO csbi; - if (!GetConsoleScreenBufferInfo(hOutputConsole, &csbi)) - return; + if (GetConsoleScreenBufferInfo(hOutputConsole, &csbi)) + SavedViewRect = csbi.srWindow; +} - SavedViewRect = csbi.srWindow; +void +ConRestoreViewRect() +{ + CONSOLE_SCREEN_BUFFER_INFO consoleInfo; + HWND hwnd = FindWindow(NULL, consoleTitle); + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(hwnd, &wp); + + if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo) && + ((consoleInfo.srWindow.Top != SavedViewRect.Top || + consoleInfo.srWindow.Bottom != SavedViewRect.Bottom))) { + if ((SavedViewRect.Right - SavedViewRect.Left > consoleInfo.dwSize.X) || + (wp.showCmd == SW_SHOWMAXIMIZED)) { + COORD coordScreen; + coordScreen.X = SavedViewRect.Right - SavedViewRect.Left; + coordScreen.Y = consoleInfo.dwSize.Y; + SetConsoleScreenBufferSize(hOutputConsole, coordScreen); + + ShowWindow(hwnd, SW_SHOWMAXIMIZED); + } else + ShowWindow(hwnd, SW_RESTORE); + + SetConsoleWindowInfo(hOutputConsole, TRUE, &SavedViewRect); + } } BOOL @@ -1460,7 +1540,7 @@ GetConsoleInputHandle() } void -ConSaveWindowsState(void) +ConSaveWindowsState() { CONSOLE_SCREEN_BUFFER_INFOEX csbiex; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); @@ -1470,3 +1550,12 @@ ConSaveWindowsState(void) SavedWindowState = csbiex; } + +void +ConMoveCurosorTop(CONSOLE_SCREEN_BUFFER_INFO csbi) +{ + int offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top; + ConMoveVisibleWindow(offset); + + ConSaveViewRect(); +} diff --git a/contrib/win32/win32compat/console.h b/contrib/win32/win32compat/console.h index f06143e..c98386d 100644 --- a/contrib/win32/win32compat/console.h +++ b/contrib/win32/win32compat/console.h @@ -42,38 +42,38 @@ #define __PRAGMA_CONSOLE_h #define ANSI_ATTR_RESET 0 -#define ANSI_BRIGHT 1 -#define ANSI_DIM 2 +#define ANSI_BRIGHT 1 +#define ANSI_DIM 2 #define ANSI_UNDERSCORE 4 -#define ANSI_BLINK 5 +#define ANSI_BLINK 5 #define ANSI_REVERSE 7 -#define ANSI_HIDDEN 8 -#define ANSI_NOUNDERSCORE 24 +#define ANSI_HIDDEN 8 +#define ANSI_NOUNDERSCORE 24 #define ANSI_NOREVERSE 27 -#define ANSI_FOREGROUND_BLACK 30 +#define ANSI_FOREGROUND_BLACK 30 #define ANSI_FOREGROUND_RED 31 -#define ANSI_FOREGROUND_GREEN 32 -#define ANSI_FOREGROUND_YELLOW 33 -#define ANSI_FOREGROUND_BLUE 34 -#define ANSI_FOREGROUND_MAGENTA 35 -#define ANSI_FOREGROUND_CYAN 36 -#define ANSI_FOREGROUND_WHITE 37 -#define ANSI_DEFAULT_FOREGROUND 39 -#define ANSI_BACKGROUND_BLACK 40 +#define ANSI_FOREGROUND_GREEN 32 +#define ANSI_FOREGROUND_YELLOW 33 +#define ANSI_FOREGROUND_BLUE 34 +#define ANSI_FOREGROUND_MAGENTA 35 +#define ANSI_FOREGROUND_CYAN 36 +#define ANSI_FOREGROUND_WHITE 37 +#define ANSI_DEFAULT_FOREGROUND 39 +#define ANSI_BACKGROUND_BLACK 40 #define ANSI_BACKGROUND_RED 41 -#define ANSI_BACKGROUND_GREEN 42 -#define ANSI_BACKGROUND_YELLOW 43 -#define ANSI_BACKGROUND_BLUE 44 -#define ANSI_BACKGROUND_MAGENTA 45 -#define ANSI_BACKGROUND_CYAN 46 -#define ANSI_BACKGROUND_WHITE 47 -#define ANSI_DEFAULT_BACKGROUND 49 -#define ANSI_BACKGROUND_BRIGHT 128 +#define ANSI_BACKGROUND_GREEN 42 +#define ANSI_BACKGROUND_YELLOW 43 +#define ANSI_BACKGROUND_BLUE 44 +#define ANSI_BACKGROUND_MAGENTA 45 +#define ANSI_BACKGROUND_CYAN 46 +#define ANSI_BACKGROUND_WHITE 47 +#define ANSI_DEFAULT_BACKGROUND 49 +#define ANSI_BACKGROUND_BRIGHT 128 -#define TAB_LENGTH 4 -#define TAB_CHAR '\t' -#define TAB_SPACE " " +#define TAB_LENGTH 4 +#define TAB_CHAR '\t' +#define TAB_SPACE " " #define true TRUE #define false FALSE @@ -81,30 +81,30 @@ typedef void * SCREEN_HANDLE; -int ConInit( DWORD OutputHandle, BOOL fSmartInit); -int ConUnInitWithRestore( void ); -int ConUnInit( void ); +int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit); +int ConUnInitWithRestore(); +int ConExitRawMode(); BOOL ConIsRedirected(HANDLE hInput); HANDLE GetConsoleOutputHandle(); HANDLE GetConsoleInputHandle(); -BOOL ConSetScreenRect( int xSize, int ySize ); -BOOL ConSetScreenSize( int X, int Y ); -BOOL ConRestoreScreen( void ); -BOOL ConSaveScreen( void ); -void ConSetAttribute( int *iParam, int iParamCount ); -int ConScreenSizeX(); -int ConSetScreenX(); +BOOL ConSetScreenRect(int xSize, int ySize); +BOOL ConSetScreenSize(int X, int Y); +BOOL ConRestoreScreen(); +void ConSaveScreen(); +void ConSetAttribute(int *iParam, int iParamCount); +int ConScreenSizeX(); +int ConSetScreenX(); int ConScreenSizeY(); -int ConWindowSizeX(); -int ConWindowSizeY(); +int ConVisibleWindowWidth(); +int ConVisibleWindowHeight(); int ConSetScreenY(); void ConFillToEndOfLine(); int ConWriteString(char* pszString, int cbString); -BOOL ConWriteChar( CHAR ch ); -int ConWriteConsole( char *pData, int NumChars ); +BOOL ConWriteChar(CHAR ch); +int ConWriteConsole(char *pData, int NumChars); PCHAR ConDisplayData(char* pData, int NumLines); PCHAR ConWriteLine(char* pData); -int Con_printf( const char *Format, ... ); +int Con_printf(const char *Format, ...); void ConClearScrollRegion(); void ConClearScreen(); void ConClearEOScreen(); @@ -115,25 +115,27 @@ void ConClearNFromCursorRight(int n); void ConClearNFromCursorLeft(int n); void ConScrollUpEntireBuffer(); void ConScrollDownEntireBuffer(); -void ConScrollUp(int topline,int botline); -void ConScrollDown(int topline,int botline); +void ConScrollUp(int topline,int botline); +void ConScrollDown(int topline,int botline); void ConClearBOLine(); -BOOL ConChangeCursor( CONSOLE_CURSOR_INFO *pCursorInfo ); +BOOL ConChangeCursor(CONSOLE_CURSOR_INFO *pCursorInfo); void ConSetCursorPosition(int x, int y); int ConGetCursorX(); int ConGetCursorY(); -int ConGetCursorInBufferY(void); -BOOL ConDisplayCursor( BOOL bVisible ); +int ConGetBufferHeight(); +BOOL ConDisplayCursor(BOOL bVisible); void ConMoveCursorPosition(int x, int y); void ConGetRelativeCursorPosition(int *x, int *y); -BOOL ConRestoreScreenHandle( SCREEN_HANDLE hScreen ); -BOOL ConRestoreScreenColors( void ); -SCREEN_HANDLE ConSaveScreenHandle( SCREEN_HANDLE); -void ConDeleteScreenHandle( SCREEN_HANDLE hScreen ); -void ConSaveViewRect( void ); -void ConRestoreViewRect( void ); +BOOL ConRestoreScreenHandle(SCREEN_HANDLE hScreen); +BOOL ConRestoreScreenColors(); +SCREEN_HANDLE ConSaveScreenHandle(SCREEN_HANDLE); +void ConDeleteScreenHandle(SCREEN_HANDLE hScreen); +void ConSaveViewRect(); +void ConRestoreViewRect(); void ConDeleteChars(int n); -void ConSaveWindowsState(void); - - +void ConSaveWindowsState(); +void ConMoveVisibleWindow(int offset); +int is_cursor_at_lastline_of_visible_window(); +void ConGetCursorPosition(int *x, int *y); +void ConMoveCurosorTop(CONSOLE_SCREEN_BUFFER_INFO csbi); #endif diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index 06745d1..5fb40c8 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -37,6 +37,7 @@ #include "w32fd.h" #include "inc\utf.h" +#include "inc\fcntl.h" #include "misc_internal.h" /* internal read buffer size */ @@ -74,6 +75,76 @@ errno_from_Win32Error(int win32_error) } } +struct w32_io* +fileio_afunix_socket() +{ + struct w32_io* ret = (struct w32_io*)malloc(sizeof(struct w32_io)); + if (ret == NULL) { + errno = ENOMEM; + return NULL; + } + + memset(ret, 0, sizeof(struct w32_io)); + return ret; +} + +int +fileio_connect(struct w32_io* pio, char* name) +{ + wchar_t* name_w = NULL; + wchar_t pipe_name[PATH_MAX]; + HANDLE h = INVALID_HANDLE_VALUE; + int ret = 0; + + if (pio->handle != 0 && pio->handle != INVALID_HANDLE_VALUE) { + debug("fileio_connect called in unexpected state, pio = %p", pio); + errno = EOTHER; + ret = -1; + goto cleanup; + } + + if ((name_w = utf8_to_utf16(name)) == NULL) { + errno = ENOMEM; + return -1; + } + _snwprintf(pipe_name, PATH_MAX, L"\\\\.\\pipe\\%ls", name_w); + h = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + + /* TODO - support nonblocking connect */ + /* wait until we have a server pipe instance to connect */ + while (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) { + debug2("waiting for agent connection, retrying after 1 sec"); + if ((ret = wait_for_any_event(NULL, 0, 1000) != 0) != 0) + goto cleanup; + } + + if (h == INVALID_HANDLE_VALUE) { + debug("unable to connect to pipe %ls, error: %d", name_w, GetLastError()); + errno = errno_from_Win32LastError(); + ret = -1; + goto cleanup; + } + + if (SetHandleInformation(h, HANDLE_FLAG_INHERIT, + pio->fd_flags & FD_CLOEXEC ? 0 : HANDLE_FLAG_INHERIT) == FALSE) { + errno = errno_from_Win32LastError(); + debug("SetHandleInformation failed, error = %d, pio = %p", GetLastError(), pio); + ret = -1; + goto cleanup; + } + + pio->handle = h; + h = NULL; + +cleanup: + if (name_w) + free(name_w); + if (h != INVALID_HANDLE_VALUE) + CloseHandle(h); + return ret; +} + /* used to name named pipes used to implement pipe() */ static int pipe_counter = 0; @@ -663,6 +734,12 @@ fileio_close(struct w32_io* pio) { debug2("fileclose - pio:%p", 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); + return 0; + } + CancelIo(WINHANDLE(pio)); /* let queued APCs (if any) drain */ SleepEx(0, TRUE); diff --git a/contrib/win32/win32compat/inc/stdio.h b/contrib/win32/win32compat/inc/stdio.h index 83aa05b..269ece8 100644 --- a/contrib/win32/win32compat/inc/stdio.h +++ b/contrib/win32/win32compat/inc/stdio.h @@ -5,6 +5,12 @@ FILE* w32_fopen_utf8(const char *, const char *); #define fopen w32_fopen_utf8 +char* w32_fgets(char *str, int n, FILE *stream); +#define fgets w32_fgets + +int w32_setvbuf(FILE *stream,char *buffer, int mode, size_t size); +#define setvbuf w32_setvbuf + /* stdio.h additional definitions */ #define popen _popen #define pclose _pclose @@ -14,4 +20,3 @@ FILE* w32_fdopen(int fd, const char *mode); int w32_rename(const char *old_name, const char *new_name); #define rename w32_rename - diff --git a/contrib/win32/win32compat/inc/sys/un.h b/contrib/win32/win32compat/inc/sys/un.h index fff9d78..42f09b8 100644 --- a/contrib/win32/win32compat/inc/sys/un.h +++ b/contrib/win32/win32compat/inc/sys/un.h @@ -1,7 +1,7 @@ -#ifndef COMPAT_UN_H -#define COMPAT_UN_H 1 +#pragma once +struct sockaddr_un { + short sun_family; /* AF_UNIX */ + char sun_path[108]; /* path name (gag) */ +}; -/* Compatibility header to avoid lots of #ifdef _WIN32's in includes.h */ - -#endif diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index 9e87efa..014fa31 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -276,6 +276,75 @@ w32_fopen_utf8(const char *path, const char *mode) return f; } +/* fgets to support Unicode input */ +char* + w32_fgets(char *str, int n, FILE *stream) { + HANDLE h = (HANDLE)_get_osfhandle(_fileno(stream)); + wchar_t* str_w = NULL; + char *ret = NULL, *str_tmp = NULL; + + if (h != NULL && h != INVALID_HANDLE_VALUE + && GetFileType(h) == FILE_TYPE_CHAR) { + /* + * read only n/4 wide chars from console + * each UTF-16 char may bloat upto 4 utf-8 chars when converted to utf-8 + * so we can fit in str[n] provided as input + */ + if ((str_w = malloc((n/4) * sizeof(wchar_t))) == NULL) { + errno = ENOMEM; + goto cleanup; + } + /* prepare for Unicode input */ + _setmode(_fileno(stream), O_U16TEXT); + if (fgetws(str_w, n/4, stream) == NULL) + goto cleanup; + if ((str_tmp = utf16_to_utf8(str_w)) == NULL) { + errno = ENOMEM; + goto cleanup; + } + if (strlen(str_tmp) > n - 1) { + /* shouldn't happen. but handling in case */ + errno = EINVAL; + goto cleanup; + } + memcpy(str, str_tmp, strlen(str_tmp) + 1); + ret = str; + } + else + ret = fgets(str, n, stream); +cleanup: + if (str_w) + free(str_w); + if (str_tmp) + free(str_tmp); + return ret; +} + +/* Account for differences between Unix's and Windows versions of setvbuf */ +int +w32_setvbuf(FILE *stream, char *buffer, int mode, size_t size) { + + /* BUG: setvbuf on console stream interferes with Unicode I/O */ + HANDLE h = (HANDLE)_get_osfhandle(_fileno(stream)); + + if (h != NULL && h != INVALID_HANDLE_VALUE + && GetFileType(h) == FILE_TYPE_CHAR) + return 0; + + /* BUG: setvbuf on file stream is interfering with w32_fopen */ + /* short circuit for now*/ + return 0; + + /* + * if size is 0, set no buffering. + * Windows does not differentiate __IOLBF and _IOFBF + */ + if (size == 0) + return setvbuf(stream, NULL, _IONBF, 0); + else + return setvbuf(stream, buffer, mode, size); +} + char * w32_programdir() { @@ -319,10 +388,12 @@ w32_ioctl(int d, int request, ...) errno = EINVAL; return -1; } - wsize->ws_col = c_info.dwSize.X - 5; - wsize->ws_row = c_info.dwSize.Y; + + wsize->ws_col = c_info.dwSize.X; + wsize->ws_row = c_info.srWindow.Bottom - c_info.srWindow.Top + 1; wsize->ws_xpixel = 640; wsize->ws_ypixel = 480; + return 0; } default: diff --git a/contrib/win32/win32compat/misc_internal.h b/contrib/win32/win32compat/misc_internal.h index d17278a..6150de0 100644 --- a/contrib/win32/win32compat/misc_internal.h +++ b/contrib/win32/win32compat/misc_internal.h @@ -1,3 +1,4 @@ +#pragma once #define PATH_MAX MAX_PATH /* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */ @@ -9,4 +10,4 @@ void w32posix_done(); char* w32_programdir(); void convertToBackslash(char *str); -void convertToForwardslash(char *str); \ No newline at end of file +void convertToForwardslash(char *str); diff --git a/contrib/win32/win32compat/shell-host.c b/contrib/win32/win32compat/shell-host.c index de8ae2f..a6e5b46 100644 --- a/contrib/win32/win32compat/shell-host.c +++ b/contrib/win32/win32compat/shell-host.c @@ -121,6 +121,9 @@ struct key_translation keys[] = { { "\x1b[24~", VK_F12, 0 } }; +static SHORT lastX = 0; +static SHORT lastY = 0; + consoleEvent* head = NULL; consoleEvent* tail = NULL; @@ -182,6 +185,17 @@ STARTUPINFO inputSi; goto cleanup; \ } while(0) +int +ConSRWidth() +{ + CONSOLE_SCREEN_BUFFER_INFOEX consoleBufferInfo; + ZeroMemory(&consoleBufferInfo, sizeof(consoleBufferInfo)); + consoleBufferInfo.cbSize = sizeof(consoleBufferInfo); + + GetConsoleScreenBufferInfoEx(child_out, &consoleBufferInfo); + return consoleBufferInfo.srWindow.Right; +} + /* * This function will handle the console keystrokes. */ @@ -426,7 +440,7 @@ SendBuffer(HANDLE hInput, CHAR_INFO *buffer, DWORD bufferSize) } void -CalculateAndSetCursor(HANDLE hInput, UINT aboveTopLine, UINT viewPortHeight, UINT x, UINT y) +CalculateAndSetCursor(HANDLE hInput, UINT x, UINT y) { SendSetCursor(pipe_out, x + 1, y + 1); @@ -548,14 +562,13 @@ ProcessEvent(void *p) case EVENT_CONSOLE_CARET: { COORD co; + co.X = LOWORD(idChild); + co.Y = HIWORD(idChild); - if (idObject == CONSOLE_CARET_SELECTION) { - co.X = HIWORD(idChild); - co.Y = LOWORD(idChild); - } else { - co.X = HIWORD(idChild); - co.Y = LOWORD(idChild); - } + lastX = co.X; + lastY = co.Y; + + SendSetCursor(pipe_out, lastX + 1, lastY + 1); break; } @@ -568,6 +581,8 @@ ProcessEvent(void *p) readRect.Bottom = HIWORD(idChild); readRect.Right = LOWORD(idChild); + readRect.Right = max(readRect.Right, ConSRWidth()); + /* Detect a "cls" (Windows) */ if (!bStartup && (readRect.Top == consoleInfo.srWindow.Top || readRect.Top == nextConsoleInfo.srWindow.Top)) { @@ -632,7 +647,7 @@ ProcessEvent(void *p) SendLF(pipe_out); /* Set cursor location based on the reported location from the message */ - CalculateAndSetCursor(pipe_out, ViewPortY, viewPortHeight, readRect.Left, readRect.Top); + CalculateAndSetCursor(pipe_out, readRect.Left, readRect.Top); /* Send the entire block */ SendBuffer(pipe_out, pBuffer, bufferSize); @@ -649,12 +664,37 @@ ProcessEvent(void *p) wAttributes = HIWORD(idChild); wX = LOWORD(idObject); wY = HIWORD(idObject); - + + SMALL_RECT readRect; + readRect.Top = wY; + readRect.Bottom = wY; + readRect.Left = wX; + readRect.Right = ConSRWidth(); + /* Set cursor location based on the reported location from the message */ - CalculateAndSetCursor(pipe_out, ViewPortY, viewPortHeight, wX, wY); + CalculateAndSetCursor(pipe_out, wX, wY); + + COORD coordBufSize; + coordBufSize.Y = readRect.Bottom - readRect.Top + 1; + coordBufSize.X = readRect.Right - readRect.Left + 1; + /* The top left destination cell of the temporary buffer is row 0, col 0 */ + COORD coordBufCoord; + coordBufCoord.X = 0; + coordBufCoord.Y = 0; + int pBufferSize = coordBufSize.X * coordBufSize.Y; /* Send the one character. Note that a CR doesn't end up here */ - SendCharacter(pipe_out, wAttributes, chUpdate); + CHAR_INFO *pBuffer = (PCHAR_INFO)malloc(sizeof(CHAR_INFO) * pBufferSize); + + /* Copy the block from the screen buffer to the temp. buffer */ + if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) { + DWORD dwError = GetLastError(); + free(pBuffer); + return dwError; + } + + SendBuffer(pipe_out, pBuffer, pBufferSize); + free(pBuffer); break; } @@ -699,18 +739,24 @@ ProcessEvent(void *p) } } - ZeroMemory(&consoleInfo, sizeof(consoleInfo)); - consoleInfo.cbSize = sizeof(consoleInfo); - GetConsoleScreenBufferInfoEx(child_out, &consoleInfo); - return ERROR_SUCCESS; } DWORD WINAPI ProcessEventQueue(LPVOID p) { - static SHORT lastX = 0; - static SHORT lastY = 0; + if (child_in != INVALID_HANDLE_VALUE && child_in != NULL && + child_out != INVALID_HANDLE_VALUE && child_out != NULL) { + DWORD dwInputMode; + DWORD dwOutputMode; + + if (GetConsoleMode(child_in, &dwInputMode) && GetConsoleMode(child_out, &dwOutputMode)) + if (((dwOutputMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == ENABLE_VIRTUAL_TERMINAL_PROCESSING) && + ((dwInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT)) + bAnsi = TRUE; + else + bAnsi = FALSE; + } while (1) { while (head) { @@ -738,14 +784,6 @@ ProcessEventQueue(LPVOID p) DWORD dwInputMode; DWORD dwOutputMode; - if (GetConsoleMode(child_in, &dwInputMode) && GetConsoleMode(child_out, &dwOutputMode)) { - if (((dwOutputMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == ENABLE_VIRTUAL_TERMINAL_PROCESSING) && - ((dwInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT)) - bAnsi = TRUE; - else - bAnsi = FALSE; - } - ZeroMemory(&consoleInfo, sizeof(consoleInfo)); consoleInfo.cbSize = sizeof(consoleInfo); @@ -953,7 +991,7 @@ start_with_pty(wchar_t *command) /* * Windows PTY sends cursor positions in absolute coordinates starting from <0,0> * We send a clear screen upfront to simplify client - */ + */ SendClearScreen(pipe_out); ZeroMemory(&inputSi, sizeof(STARTUPINFO)); GetStartupInfo(&inputSi); @@ -963,7 +1001,7 @@ start_with_pty(wchar_t *command) hostThreadId = GetCurrentThreadId(); hostProcessId = GetCurrentProcessId(); InitializeCriticalSection(&criticalSection); - hEventHook = __SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_LAYOUT, NULL, + hEventHook = __SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_END_APPLICATION, NULL, ConsoleEventProc, 0, 0, WINEVENT_OUTOFCONTEXT); memset(&si, 0, sizeof(STARTUPINFO)); memset(&pi, 0, sizeof(PROCESS_INFORMATION)); @@ -1205,8 +1243,14 @@ wmain(int ac, wchar_t **av) char *cmd_b64_utf8, *cmd_utf8; if ((cmd_b64_utf8 = utf16_to_utf8(cmd_b64)) == NULL || /* strlen(b64) should be sufficient for decoded length */ - (cmd_utf8 = malloc(strlen(cmd_b64_utf8))) == NULL || - b64_pton(cmd_b64_utf8, cmd_utf8, strlen(cmd_b64_utf8)) == -1 || + (cmd_utf8 = malloc(strlen(cmd_b64_utf8))) == NULL) { + printf("ssh-shellhost - out of memory"); + return -1; + } + + memset(cmd_utf8, 0, strlen(cmd_b64_utf8)); + + if (b64_pton(cmd_b64_utf8, cmd_utf8, strlen(cmd_b64_utf8)) == -1 || (cmd = utf8_to_utf16(cmd_utf8)) == NULL) { printf("ssh-shellhost encountered an internal error while decoding base64 cmdline"); return -1; diff --git a/contrib/win32/win32compat/ssh-agent/agent.h b/contrib/win32/win32compat/ssh-agent/agent.h index 36686ff..e919cfc 100644 --- a/contrib/win32/win32compat/ssh-agent/agent.h +++ b/contrib/win32/win32compat/ssh-agent/agent.h @@ -37,7 +37,7 @@ struct agent_connection { }; void agent_connection_on_io(struct agent_connection*, DWORD, OVERLAPPED*); -void agent_connection_on_error(struct agent_connection* , DWORD ); +void agent_connection_on_error(struct agent_connection* , DWORD); void agent_connection_disconnect(struct agent_connection*); void agent_start(BOOL, BOOL, HANDLE); diff --git a/contrib/win32/win32compat/termio.c b/contrib/win32/win32compat/termio.c index 967b20e..d637ade 100644 --- a/contrib/win32/win32compat/termio.c +++ b/contrib/win32/win32compat/termio.c @@ -39,6 +39,7 @@ #include "w32fd.h" #include "tncon.h" #include "inc\utf.h" +#include "tnnet.h" #define TERM_IO_BUF_SIZE 2048 @@ -136,6 +137,7 @@ WriteAPCProc(_In_ ULONG_PTR dwParam) pio->write_overlapped.hEvent = 0; } + /* Write worker thread */ static DWORD WINAPI WriteThread(_In_ LPVOID lpParameter) @@ -145,27 +147,27 @@ WriteThread(_In_ LPVOID lpParameter) size_t resplen = 0; DWORD dwSavedAttributes = ENABLE_PROCESSED_INPUT; debug3("TermWrite thread, io:%p", pio); - - if (in_raw_mode == 0) { - /* convert stream to utf16 and dump on console */ - pio->write_details.buf[write_status.to_transfer] = '\0'; + + pio->write_details.buf[write_status.to_transfer] = '\0'; + + if (0 == in_raw_mode) { wchar_t* t = utf8_to_utf16(pio->write_details.buf); WriteConsoleW(WINHANDLE(pio), t, wcslen(t), 0, 0); - free(t); - write_status.transferred = write_status.to_transfer; + free(t); } else { - /* console mode */ - telProcessNetwork(pio->write_details.buf, write_status.to_transfer, &respbuf, &resplen); + processBuffer(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer, &respbuf, &resplen); /* TODO - respbuf is not null in some cases, this needs to be returned back via read stream */ - write_status.transferred = write_status.to_transfer; } + write_status.transferred = write_status.to_transfer; + if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) { debug("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio); pio->write_details.pending = FALSE; pio->write_details.error = GetLastError(); DebugBreak(); } + return 0; } diff --git a/contrib/win32/win32compat/tncon.c b/contrib/win32/win32compat/tncon.c index 6d6d81e..503816e 100644 --- a/contrib/win32/win32compat/tncon.c +++ b/contrib/win32/win32compat/tncon.c @@ -1,37 +1,37 @@ /* - * Author: Ray Hayes - * ANSI TTY Reader - Maps Windows console input events to ANSI stream - * - * Author: Balu - * Misc fixes and code cleanup - * - * Copyright (c) 2017 Microsoft Corp. - * All rights reserved - * - * This file is responsible for console reading calls for building an emulator - * over Windows Console. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +* Author: Ray Hayes +* ANSI TTY Reader - Maps Windows console input events to ANSI stream +* +* Author: Balu +* Misc fixes and code cleanup +* +* Copyright (c) 2017 Microsoft Corp. +* All rights reserved +* +* This file is responsible for console reading calls for building an emulator +* over Windows Console. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include #include #include @@ -75,10 +75,10 @@ TelParams* pParams = &Parameters; void queue_terminal_window_change_event(); /* - * For our case, in NetWriteString2(), we do not use socket, but write the out going data to - * a global buffer setup by ReadConsoleForTermEmul(). - */ -int +* For our case, in NetWriteString2(), we do not use socket, but write the out going data to +* a global buffer setup by ReadConsoleForTermEmul(). +*/ +int NetWriteString2(SOCKET sock, char* source, size_t len, int options) { while (len > 0) { @@ -91,7 +91,7 @@ NetWriteString2(SOCKET sock, char* source, size_t len, int options) return glob_outlen; } -BOOL +BOOL DataAvailable(HANDLE h) { DWORD dwRet = WaitForSingleObject(h, INFINITE); @@ -102,7 +102,7 @@ DataAvailable(HANDLE h) return FALSE; } -int +int ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) { HANDLE hHandle[] = { hInput, NULL }; @@ -130,7 +130,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) break; case FOCUS_EVENT: - /* FALLTHROUGH */ + /* FALLTHROUGH */ case MENU_EVENT: break; @@ -210,41 +210,41 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) case VK_F1: if (dwControlKeyState == 0) NetWriteString2(pParams->Socket, (char *)PF1_KEY, strlen(PF1_KEY), 0); - + else if (dwControlKeyState == SHIFT_PRESSED) NetWriteString2(pParams->Socket, (char *)SHIFT_PF1_KEY, strlen(SHIFT_PF1_KEY), 0); - + else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED) NetWriteString2(pParams->Socket, (char *)CTRL_PF1_KEY, strlen(CTRL_PF1_KEY), 0); - + else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED) NetWriteString2(pParams->Socket, (char *)ALT_PF1_KEY, strlen(ALT_PF1_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF1_KEY, strlen(SHIFT_ALT_CTRL_PF1_KEY), 0); - + else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF1_KEY, strlen(ALT_CTRL_PF1_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_PF1_KEY, strlen(SHIFT_ALT_PF1_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_CTRL_PF1_KEY, strlen(SHIFT_CTRL_PF1_KEY), 0); - + break; case VK_F2: if (dwControlKeyState == 0) NetWriteString2(pParams->Socket, (char *)PF2_KEY, strlen(PF2_KEY), 0); - + else if (dwControlKeyState == SHIFT_PRESSED) NetWriteString2(pParams->Socket, (char *)SHIFT_PF2_KEY, strlen(SHIFT_PF2_KEY), 0); - + else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED) NetWriteString2(pParams->Socket, (char *)CTRL_PF2_KEY, strlen(CTRL_PF2_KEY), 0); @@ -255,15 +255,15 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF2_KEY, strlen(SHIFT_ALT_CTRL_PF2_KEY), 0); - + else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF2_KEY, strlen(ALT_CTRL_PF2_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_PF2_KEY, strlen(SHIFT_ALT_PF2_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_CTRL_PF2_KEY, strlen(SHIFT_CTRL_PF2_KEY), 0); @@ -271,13 +271,13 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) case VK_F3: if (dwControlKeyState == 0) NetWriteString2(pParams->Socket, (char *)PF3_KEY, strlen(PF3_KEY), 0); - + else if (dwControlKeyState == SHIFT_PRESSED) NetWriteString2(pParams->Socket, (char *)SHIFT_PF3_KEY, strlen(SHIFT_PF3_KEY), 0); - + else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED) NetWriteString2(pParams->Socket, (char *)CTRL_PF3_KEY, strlen(CTRL_PF3_KEY), 0); - + else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED) NetWriteString2(pParams->Socket, (char *)ALT_PF3_KEY, strlen(ALT_PF3_KEY), 0); @@ -301,29 +301,29 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) case VK_F4: if (dwControlKeyState == 0) NetWriteString2(pParams->Socket, (char *)PF4_KEY, strlen(PF4_KEY), 0); - + else if (dwControlKeyState == SHIFT_PRESSED) NetWriteString2(pParams->Socket, (char *)SHIFT_PF4_KEY, strlen(SHIFT_PF4_KEY), 0); - + else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED) NetWriteString2(pParams->Socket, (char *)CTRL_PF4_KEY, strlen(CTRL_PF4_KEY), 0); - + else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED) NetWriteString2(pParams->Socket, (char *)ALT_PF4_KEY, strlen(ALT_PF4_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF4_KEY, strlen(SHIFT_ALT_CTRL_PF4_KEY), 0); - + else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF4_KEY, strlen(ALT_CTRL_PF4_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_PF4_KEY, strlen(SHIFT_ALT_PF4_KEY), 0); - + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_CTRL_PF4_KEY, strlen(SHIFT_CTRL_PF4_KEY), 0); @@ -331,10 +331,10 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) case VK_F5: if (dwControlKeyState == 0) NetWriteString2(pParams->Socket, (char *)PF5_KEY, strlen(PF5_KEY), 0); - + else if (dwControlKeyState == SHIFT_PRESSED) NetWriteString2(pParams->Socket, (char *)SHIFT_PF5_KEY, strlen(SHIFT_PF5_KEY), 0); - + else if (dwControlKeyState == LEFT_CTRL_PRESSED || dwControlKeyState == RIGHT_CTRL_PRESSED) NetWriteString2(pParams->Socket, (char *)CTRL_PF5_KEY, strlen(CTRL_PF5_KEY), 0); @@ -345,7 +345,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF5_KEY, strlen(SHIFT_ALT_CTRL_PF5_KEY), 0); - + else if ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)ALT_CTRL_PF5_KEY, strlen(ALT_CTRL_PF5_KEY), 0); @@ -492,7 +492,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) NetWriteString2(pParams->Socket, (char *)ALT_PF10_KEY, strlen(ALT_PF10_KEY), 0); else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || - (dwControlKeyState & LEFT_ALT_PRESSED)) &&((dwControlKeyState & LEFT_CTRL_PRESSED) || + (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF10_KEY, strlen(SHIFT_ALT_CTRL_PF10_KEY), 0); @@ -521,7 +521,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) else if (dwControlKeyState == LEFT_ALT_PRESSED || dwControlKeyState == RIGHT_ALT_PRESSED) NetWriteString2(pParams->Socket, (char *)ALT_PF11_KEY, strlen(ALT_PF11_KEY), 0); - else if ((dwControlKeyState & SHIFT_PRESSED) &&((dwControlKeyState & RIGHT_ALT_PRESSED) || + else if ((dwControlKeyState & SHIFT_PRESSED) && ((dwControlKeyState & RIGHT_ALT_PRESSED) || (dwControlKeyState & LEFT_ALT_PRESSED)) && ((dwControlKeyState & LEFT_CTRL_PRESSED) || (dwControlKeyState & RIGHT_CTRL_PRESSED))) NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_CTRL_PF11_KEY, strlen(SHIFT_ALT_CTRL_PF11_KEY), 0); diff --git a/contrib/win32/win32compat/tnnet.c b/contrib/win32/win32compat/tnnet.c index 9763010..310546e 100644 --- a/contrib/win32/win32compat/tnnet.c +++ b/contrib/win32/win32compat/tnnet.c @@ -35,17 +35,20 @@ #include #include #include "ansiprsr.h" +#include "inc\utf.h" #define dwBuffer 4096 +extern BOOL isAnsiParsingRequired; + /* * Server will always be returning a sequence of ANSI control characters which the client * protocol can either passthru directly to the console or transform based on an output terminal * type. We're not using termcap so we're only supporting the ANSI (vt100) sequences that * are hardcoded in the server and will be transformed to Windows Console commands. */ -size_t -telProcessNetwork(char *buf, size_t len, unsigned char **respbuf, size_t *resplen) +void +processBuffer(HANDLE handle, char *buf, size_t len, unsigned char **respbuf, size_t *resplen) { unsigned char szBuffer[dwBuffer + 8]; unsigned char* pszNewHead = NULL; @@ -53,7 +56,17 @@ telProcessNetwork(char *buf, size_t len, unsigned char **respbuf, size_t *resple unsigned char* pszTail = NULL; if (len == 0) - return len; + return; + + if (false == isAnsiParsingRequired) { + /* Console has the capability to parse so pass the raw buffer to console directly */ + ConRestoreViewRect(); /* Restore the visible window, otherwise WriteConsoleW() gets messy */ + wchar_t* t = utf8_to_utf16(buf); + WriteConsoleW(handle, t, wcslen(t), 0, 0); + free(t); + ConSaveViewRect(); + return; + } /* Transform a single carriage return into a single linefeed before continuing */ if ((len == 1) && (buf[0] == 13)) @@ -74,6 +87,4 @@ telProcessNetwork(char *buf, size_t len, unsigned char **respbuf, size_t *resple pszNewHead = ParseBuffer(pszHead, pszTail, respbuf, resplen); } while ((pszNewHead != pszHead) && (pszNewHead < pszTail) && (resplen == NULL || (resplen != NULL && *resplen == 0))); - len = 0; - return len; } diff --git a/contrib/win32/win32compat/tnnet.h b/contrib/win32/win32compat/tnnet.h index d2fb54b..c3f5c31 100644 --- a/contrib/win32/win32compat/tnnet.h +++ b/contrib/win32/win32compat/tnnet.h @@ -35,8 +35,6 @@ #ifndef __TNNET_H #define __TNNET_H +void processBuffer(HANDLE handle, char *buf, size_t len, unsigned char **respbuf, size_t *resplen); - size_t telProcessNetwork (char *buf, size_t len, unsigned char **respbuf, size_t *resplen); - -#endif - \ No newline at end of file +#endif \ No newline at end of file diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index 3cefb5b..52fcbb7 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -35,6 +35,7 @@ #include "inc\sys\types.h" #include "inc\unistd.h" #include "inc\fcntl.h" +#include "inc\sys\un.h" #include "w32fd.h" #include "signal_internal.h" @@ -206,14 +207,21 @@ w32_socket(int domain, int type, int protocol) errno = 0; if (min_index == -1) return -1; + + if (domain == AF_UNIX && type == SOCK_STREAM) { + pio = fileio_afunix_socket(); + if (pio == NULL) + return -1; + pio->type = NONSOCK_FD; + } else { + pio = socketio_socket(domain, type, protocol); + if (pio == NULL) + return -1; + pio->type = SOCK_FD; + } - pio = socketio_socket(domain, type, protocol); - if (pio == NULL) - return -1; - - pio->type = SOCK_FD; fd_table_set(pio, min_index); - debug("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index); + debug("socket:%d, socktype:%d, io:%p, fd:%d ", pio->sock, type, pio, min_index); return min_index; } @@ -290,6 +298,12 @@ int w32_connect(int fd, const struct sockaddr* name, int namelen) { CHECK_FD(fd); + + if (fd_table.w32_ios[fd]->type == NONSOCK_FD) { + struct sockaddr_un* addr = (struct sockaddr_un*)name; + return fileio_connect(fd_table.w32_ios[fd], addr->sun_path); + } + CHECK_SOCK_IO(fd_table.w32_ios[fd]); return socketio_connect(fd_table.w32_ios[fd], name, namelen); } @@ -298,6 +312,7 @@ int w32_recv(int fd, void *buf, size_t len, int flags) { CHECK_FD(fd); + CHECK_SOCK_IO(fd_table.w32_ios[fd]); return socketio_recv(fd_table.w32_ios[fd], buf, len, flags); } @@ -503,10 +518,16 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags) shi_flags = (flags & FD_CLOEXEC) ? 0 : HANDLE_FLAG_INHERIT; if (SetHandleInformation(WINHANDLE(pio), HANDLE_FLAG_INHERIT, shi_flags) == FALSE) { - debug("fcntl - SetHandleInformation failed %d, io:%p", - GetLastError(), pio); - errno = EOTHER; - return -1; + /* + * Ignore if handle is not valid yet. It will not be valid for + * UF_UNIX sockets that are not connected yet + */ + if (GetLastError() != ERROR_INVALID_HANDLE) { + debug("fcntl - SetHandleInformation failed %d, io:%p", + GetLastError(), pio); + errno = EOTHER; + return -1; + } } pio->fd_flags = flags; diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h index 1aad34a..0387a00 100644 --- a/contrib/win32/win32compat/w32fd.h +++ b/contrib/win32/win32compat/w32fd.h @@ -127,6 +127,8 @@ BOOL fileio_is_io_available(struct w32_io* pio, BOOL rd); void fileio_on_select(struct w32_io* pio, BOOL rd); int fileio_close(struct w32_io* pio); int fileio_pipe(struct w32_io* pio[2]); +struct w32_io* fileio_afunix_socket(); +int fileio_connect(struct w32_io*, char*); struct w32_io* fileio_open(const char *pathname, int flags, int mode); int fileio_read(struct w32_io* pio, void *dst, unsigned int max); int fileio_write(struct w32_io* pio, const void *buf, unsigned int max); diff --git a/contrib/win32/win32compat/win32-utf8.c b/contrib/win32/win32compat/win32-utf8.c new file mode 100644 index 0000000..f1fd186 --- /dev/null +++ b/contrib/win32/win32compat/win32-utf8.c @@ -0,0 +1,54 @@ +/* + * Temporary Windows versions of functions implemented in utf8.c + */ +#include +#include + +int +vfmprintf(FILE *f, const char *fmt, va_list list) +{ + return vfprintf(f, fmt, list); +} + +int +mprintf(const char *fmt, ...) +{ + int ret = 0; + va_list valist; + va_start(valist, fmt); + ret = vfmprintf(stdout, fmt, valist); + va_end(valist); + return ret; +} + +int +fmprintf(FILE *f, const char *fmt, ...) +{ + int ret = 0; + va_list valist; + va_start(valist, fmt); + ret = vfmprintf(f, fmt, valist); + va_end(valist); + return ret; +} + +int +snmprintf(char *buf, size_t len, int *written, const char *fmt, ...) +{ + int ret; + va_list valist; + va_start(valist, fmt); + if ((ret = vsnprintf(buf, len, fmt, valist)) >= len) + ret = len; + va_end(valist); + if (written != NULL && ret != -1) + *written = ret; + return ret; +} + +void +msetlocale(void) +{ + return; +} + diff --git a/contrib/win32/win32compat/wmain_common.c b/contrib/win32/win32compat/wmain_common.c index 7addd95..3d09cee 100644 --- a/contrib/win32/win32compat/wmain_common.c +++ b/contrib/win32/win32compat/wmain_common.c @@ -34,7 +34,8 @@ #include "inc\utf.h" #include "misc_internal.h" -int main(int, char **); +int +main(int, char **); int wmain(int argc, wchar_t **wargv) { @@ -48,6 +49,9 @@ wmain(int argc, wchar_t **wargv) { argv[i] = utf16_to_utf8(wargv[i]); } + if (getenv("SSH_AUTH_SOCK") == NULL) + _putenv("SSH_AUTH_SOCK=ssh-agent"); + w32posix_initialize(); r = main(argc, argv); w32posix_done(); diff --git a/contrib/win32/win32compat/wmain_sshd.c b/contrib/win32/win32compat/wmain_sshd.c index 5e75d01..3f1bc58 100644 --- a/contrib/win32/win32compat/wmain_sshd.c +++ b/contrib/win32/win32compat/wmain_sshd.c @@ -108,6 +108,9 @@ int sshd_main(int argc, wchar_t **wargv) { argv[i] = utf16_to_utf8(wargv[i]); } + if (getenv("SSH_AUTH_SOCK") == NULL) + _putenv("SSH_AUTH_SOCK=ssh-agent"); + w32posix_initialize(); if (getenv("SSHD_REMSOC")) is_child = 1; diff --git a/digest-openssl.c b/digest-openssl.c index 13b63c2..c55ceb9 100644 --- a/digest-openssl.c +++ b/digest-openssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */ +/* $OpenBSD: digest-openssl.c,v 1.6 2017/03/10 02:59:51 dtucker Exp $ */ /* * Copyright (c) 2013 Damien Miller * @@ -158,7 +158,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); u_int l = dlen; - if (dlen > UINT_MAX) + if (digest == NULL || dlen > UINT_MAX) return SSH_ERR_INVALID_ARGUMENT; if (dlen < digest->digest_len) /* No truncation allowed */ return SSH_ERR_INVALID_ARGUMENT; diff --git a/hostfile.c b/hostfile.c index 6543ac8..0c05942 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.67 2016/09/17 18:00:27 tedu Exp $ */ +/* $OpenBSD: hostfile.c,v 1.68 2017/03/10 04:26:06 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -419,19 +419,24 @@ write_host_entry(FILE *f, const char *host, const char *ip, const struct sshkey *key, int store_hash) { int r, success = 0; - char *hashed_host = NULL; + char *hashed_host = NULL, *lhost; + + lhost = xstrdup(host); + lowercase(lhost); if (store_hash) { - if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { + if ((hashed_host = host_hash(lhost, NULL, 0)) == NULL) { error("%s: host_hash failed", __func__); + free(lhost); return 0; } fprintf(f, "%s ", hashed_host); } else if (ip != NULL) - fprintf(f, "%s,%s ", host, ip); - else - fprintf(f, "%s ", host); - + fprintf(f, "%s,%s ", lhost, ip); + else { + fprintf(f, "%s ", lhost); + } + free(lhost); if ((r = sshkey_write(key, f)) == 0) success = 1; else diff --git a/kex.c b/kex.c index a30dabe..8ac0029 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.128 2017/02/03 23:01:19 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.130 2017/03/10 04:07:20 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -178,7 +178,7 @@ kex_names_valid(const char *names) char * kex_names_cat(const char *a, const char *b) { - char *ret = NULL, *tmp = NULL, *cp, *p; + char *ret = NULL, *tmp = NULL, *cp, *p, *m; size_t len; if (a == NULL || *a == '\0') @@ -195,8 +195,10 @@ kex_names_cat(const char *a, const char *b) } strlcpy(ret, a, len); for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { - if (match_list(ret, p, NULL) != NULL) + if ((m = match_list(ret, p, NULL)) != NULL) { + free(m); continue; /* Algorithm already present */ + } if (strlcat(ret, ",", len) >= len || strlcat(ret, p, len) >= len) { free(tmp); @@ -348,7 +350,7 @@ kex_send_ext_info(struct ssh *ssh) int r; char *algs; - if ((algs = sshkey_alg_list(0, 1, ',')) == NULL) + if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || (r = sshpkt_put_u32(ssh, 1)) != 0 || @@ -651,8 +653,10 @@ choose_enc(struct sshenc *enc, char *client, char *server) if (name == NULL) return SSH_ERR_NO_CIPHER_ALG_MATCH; - if ((enc->cipher = cipher_by_name(name)) == NULL) + if ((enc->cipher = cipher_by_name(name)) == NULL) { + free(name); return SSH_ERR_INTERNAL_ERROR; + } enc->name = name; enc->enabled = 0; enc->iv = NULL; @@ -670,8 +674,10 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) if (name == NULL) return SSH_ERR_NO_MAC_ALG_MATCH; - if (mac_setup(mac, name) < 0) + if (mac_setup(mac, name) < 0) { + free(name); return SSH_ERR_INTERNAL_ERROR; + } /* truncate the key */ if (ssh->compat & SSH_BUG_HMAC) mac->key_len = 16; @@ -695,6 +701,7 @@ choose_comp(struct sshcomp *comp, char *client, char *server) } else if (strcmp(name, "none") == 0) { comp->type = COMP_NONE; } else { + free(name); return SSH_ERR_INTERNAL_ERROR; } comp->name = name; diff --git a/log.c b/log.c index 53721f3..945fd9d 100644 --- a/log.c +++ b/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.48 2016/07/15 05:01:58 dtucker Exp $ */ +/* $OpenBSD: log.c,v 1.49 2017/03/10 03:15:58 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -453,7 +453,8 @@ do_log(LogLevel level, const char *fmt, va_list args) tmp_handler(level, fmtbuf, log_handler_ctx); log_handler = tmp_handler; } else if (log_on_stderr) { - snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); + snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n", + (int)sizeof msgbuf - 3, fmtbuf); #ifdef WINDOWS /* * In Windows, write is implemented as part of POSIX compat layer diff --git a/match.c b/match.c index aeba4bb..3cf4030 100644 --- a/match.c +++ b/match.c @@ -1,4 +1,4 @@ -/* $OpenBSD: match.c,v 1.34 2017/02/03 23:01:19 djm Exp $ */ +/* $OpenBSD: match.c,v 1.37 2017/03/10 04:24:55 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -42,9 +42,11 @@ #include #include #include +#include #include "xmalloc.h" #include "match.h" +#include "misc.h" /* * Returns true if the given string matches the pattern (which may contain ? @@ -145,7 +147,7 @@ match_pattern_list(const char *string, const char *pattern, int dolower) if (subi >= sizeof(sub) - 1) return 0; - /* If the subpattern was terminated by a comma, skip the comma. */ + /* If the subpattern was terminated by a comma, then skip it. */ if (i < len && pattern[i] == ',') i++; @@ -177,7 +179,13 @@ match_pattern_list(const char *string, const char *pattern, int dolower) int match_hostname(const char *host, const char *pattern) { - return match_pattern_list(host, pattern, 1); + char *hostcopy = xstrdup(host); + int r; + + lowercase(hostcopy); + r = match_pattern_list(hostcopy, pattern, 1); + free(hostcopy); + return r; } /* @@ -297,8 +305,11 @@ match_filter_list(const char *proposal, const char *filter) char *orig_prop = strdup(proposal); char *cp, *tmp; - if (fix_prop == NULL || orig_prop == NULL) + if (fix_prop == NULL || orig_prop == NULL) { + free(orig_prop); + free(fix_prop); return NULL; + } tmp = orig_prop; *fix_prop = '\0'; diff --git a/packet.c b/packet.c index 94e8460..01e2d45 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.245 2017/02/03 23:03:33 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.246 2017/02/28 06:10:08 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1466,8 +1466,10 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) break; } } - if (r == 0) - return SSH_ERR_CONN_TIMEOUT; + if (r == 0) { + r = SSH_ERR_CONN_TIMEOUT; + goto out; + } /* Read data from the socket. */ len = read(state->connection_in, buf, sizeof(buf)); if (len == 0) { diff --git a/readconf.c b/readconf.c index bfcd2b3..90ec464 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.268 2017/02/03 23:01:19 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.270 2017/03/10 04:27:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1505,6 +1505,7 @@ parse_keytypes: if (r == GLOB_NOMATCH) { debug("%.200s line %d: include %s matched no " "files",filename, linenum, arg2); + free(arg2); continue; } else if (r != 0 || gl.gl_pathc < 0) fatal("%.200s line %d: glob failed for %s.", @@ -1724,7 +1725,7 @@ read_config_file_depth(const char *filename, struct passwd *pw, int flags, int *activep, int depth) { FILE *f; - char line[1024]; + char line[4096]; int linenum; int bad_options = 0; @@ -1756,6 +1757,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, while (fgets(line, sizeof(line), f)) { /* Update line number counter. */ linenum++; + if (strlen(line) == sizeof(line) - 1) + fatal("%s line %d too long", filename, linenum); if (process_config_line_depth(options, pw, host, original_host, line, filename, linenum, activep, flags, depth) != 0) bad_options++; diff --git a/regress/test-exec.sh b/regress/test-exec.sh index bfa4880..dc033cd 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.58 2016/12/16 01:06:27 dtucker Exp $ +# $OpenBSD: test-exec.sh,v 1.59 2017/02/07 23:03:11 dtucker Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -444,12 +444,10 @@ Host * User $USER GlobalKnownHostsFile $OBJ/known_hosts UserKnownHostsFile $OBJ/known_hosts - RSAAuthentication yes PubkeyAuthentication yes ChallengeResponseAuthentication no HostbasedAuthentication no PasswordAuthentication no - RhostsRSAAuthentication no BatchMode yes StrictHostKeyChecking yes LogLevel DEBUG3 diff --git a/regress/unittests/utf8/tests.c b/regress/unittests/utf8/tests.c index c32121a..733fe60 100644 --- a/regress/unittests/utf8/tests.c +++ b/regress/unittests/utf8/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.3 2016/12/19 04:55:18 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.4 2017/02/19 00:11:29 djm Exp $ */ /* * Regress test for the utf8.h *mprintf() API * @@ -15,10 +15,7 @@ #include "utf8.h" -void badarg(void); -void one(const char *, const char *, int, int, int, const char *); - -void +static void badarg(void) { char buf[16]; @@ -33,8 +30,8 @@ badarg(void) TEST_DONE(); } -void -one(const char *name, const char *mbs, int width, +static void +one(int utf8, const char *name, const char *mbs, int width, int wantwidth, int wantlen, const char *wants) { char buf[16]; @@ -43,7 +40,7 @@ one(const char *name, const char *mbs, int width, if (wantlen == -2) wantlen = strlen(wants); - (void)strlcpy(buf, "utf8_", sizeof(buf)); + (void)strlcpy(buf, utf8 ? "utf8_" : "c_", sizeof(buf)); (void)strlcat(buf, name, sizeof(buf)); TEST_START(buf); wp = wantwidth == -2 ? NULL : &width; @@ -70,19 +67,41 @@ tests(void) TEST_DONE(); badarg(); - one("empty", "", 2, 0, 0, ""); - one("ascii", "x", -2, -2, -2, "x"); - one("newline", "a\nb", -2, -2, -2, "a\nb"); - one("cr", "a\rb", -2, -2, -2, "a\rb"); - one("tab", "a\tb", -2, -2, -2, "a\tb"); - one("esc", "\033x", -2, -2, -2, "\\033x"); - one("inv_badbyte", "\377x", -2, -2, -2, "\\377x"); - one("inv_nocont", "\341x", -2, -2, -2, "\\341x"); - one("inv_nolead", "a\200b", -2, -2, -2, "a\\200b"); - one("sz_ascii", "1234567890123456", -2, -2, 16, "123456789012345"); - one("sz_esc", "123456789012\033", -2, -2, 16, "123456789012"); - one("width_ascii", "123", 2, 2, -1, "12"); - one("width_double", "a\343\201\201", 2, 1, -1, "a"); - one("double_fit", "a\343\201\201", 3, 3, 4, "a\343\201\201"); - one("double_spc", "a\343\201\201", 4, 3, 4, "a\343\201\201"); + one(1, "empty", "", 2, 0, 0, ""); + one(1, "ascii", "x", -2, -2, -2, "x"); + one(1, "newline", "a\nb", -2, -2, -2, "a\nb"); + one(1, "cr", "a\rb", -2, -2, -2, "a\rb"); + one(1, "tab", "a\tb", -2, -2, -2, "a\tb"); + one(1, "esc", "\033x", -2, -2, -2, "\\033x"); + one(1, "inv_badbyte", "\377x", -2, -2, -2, "\\377x"); + one(1, "inv_nocont", "\341x", -2, -2, -2, "\\341x"); + one(1, "inv_nolead", "a\200b", -2, -2, -2, "a\\200b"); + one(1, "sz_ascii", "1234567890123456", -2, -2, 16, "123456789012345"); + one(1, "sz_esc", "123456789012\033", -2, -2, 16, "123456789012"); + one(1, "width_ascii", "123", 2, 2, -1, "12"); + one(1, "width_double", "a\343\201\201", 2, 1, -1, "a"); + one(1, "double_fit", "a\343\201\201", 3, 3, 4, "a\343\201\201"); + one(1, "double_spc", "a\343\201\201", 4, 3, 4, "a\343\201\201"); + + TEST_START("C_setlocale"); + loc = setlocale(LC_CTYPE, "C"); + ASSERT_PTR_NE(loc, NULL); + TEST_DONE(); + + badarg(); + one(0, "empty", "", 2, 0, 0, ""); + one(0, "ascii", "x", -2, -2, -2, "x"); + one(0, "newline", "a\nb", -2, -2, -2, "a\nb"); + one(0, "cr", "a\rb", -2, -2, -2, "a\rb"); + one(0, "tab", "a\tb", -2, -2, -2, "a\tb"); + one(0, "esc", "\033x", -2, -2, -2, "\\033x"); + one(0, "inv_badbyte", "\377x", -2, -2, -2, "\\377x"); + one(0, "inv_nocont", "\341x", -2, -2, -2, "\\341x"); + one(0, "inv_nolead", "a\200b", -2, -2, -2, "a\\200b"); + one(0, "sz_ascii", "1234567890123456", -2, -2, 16, "123456789012345"); + one(0, "sz_esc", "123456789012\033", -2, -2, 16, "123456789012"); + one(0, "width_ascii", "123", 2, 2, -1, "12"); + one(0, "width_double", "a\343\201\201", 2, 1, -1, "a"); + one(0, "double_fit", "a\343\201\201", 7, 5, -1, "a\\343"); + one(0, "double_spc", "a\343\201\201", 13, 13, 13, "a\\343\\201\\201"); } diff --git a/scp.c b/scp.c index 8e734db..f6b9bc2 100644 --- a/scp.c +++ b/scp.c @@ -1034,17 +1034,7 @@ rsource(char *name, struct stat *statp) (void) snprintf(path, sizeof path, "D%04o %d %.1024s\n", (u_int) (statp->st_mode & FILEMODEMASK), 0, last); if (verbose_mode) -#ifdef WINDOWS - /* TODO - make fmprintf work for Windows */ - { - printf("Entering directory: "); - wchar_t* wtmp = utf8_to_utf16(path); - WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0); - free(wtmp); - } -#else /* !WINDOWS */ fmprintf(stderr, "Entering directory: %s", path); -#endif /* !WINDOWS */ (void) atomicio(vwrite, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); @@ -1119,17 +1109,7 @@ sink(int argc, char **argv) } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); *cp = 0; if (verbose_mode) -#ifdef WINDOWS - /* TODO - make fmprintf work for Windows */ - { - printf("Sink: "); - wchar_t* wtmp = utf8_to_utf16(buf); - WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0); - free(wtmp); - } -#else /* !WINDOWS */ fmprintf(stderr, "Sink: %s", buf); -#endif /* !WINDOWS */ if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) { diff --git a/servconf.c b/servconf.c index 12765b7..f9910e9 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.304 2017/02/03 23:01:19 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.305 2017/03/10 04:11:00 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -2164,8 +2164,6 @@ dump_cfg_fmtint(ServerOpCodes code, int val) static void dump_cfg_string(ServerOpCodes code, const char *val) { - if (val == NULL) - return; printf("%s %s\n", lookup_opcode_name(code), val == NULL ? "none" : val); } diff --git a/session.c b/session.c index 54b3087..97426ec 100644 --- a/session.c +++ b/session.c @@ -482,6 +482,9 @@ int do_exec_windows(Session *s, const char *command, int pty) { fcntl(pipeout[0], F_SETFD, FD_CLOEXEC); fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC); + /* setup Environment varibles */ + setup_session_vars(s); + /* prepare exec - path used with CreateProcess() */ if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) { /* relative or absolute */ @@ -530,17 +533,13 @@ int do_exec_windows(Session *s, const char *command, int pty) { *c = '\0'; } - /* setup Environment varibles */ - setup_session_vars(s); - - extern int debug_flag; - /* start the process */ { PROCESS_INFORMATION pi; STARTUPINFOW si; BOOL b; HANDLE hToken = INVALID_HANDLE_VALUE; + extern int debug_flag; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); diff --git a/sftp.c b/sftp.c index 6510a01..5baaa48 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.177 2016/10/18 12:41:22 millert Exp $ */ +/* $OpenBSD: sftp.c,v 1.178 2017/02/15 01:46:47 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -292,27 +292,6 @@ help(void) "? Synonym for help\n"); } -#ifdef WINDOWS -/* printf version to account for utf-8 input */ -/* TODO - merge this with vfmprint */ -static void printf_utf8(char *fmt, ... ) { - /* TODO - is 1024 sufficient */ - char buf[1024]; - int length = 0; - - va_list valist; - va_start(valist, fmt); - length = vsnprintf(buf, 1024, fmt, valist); - va_end(valist); - - write(STDOUT_FILENO, buf, length); -} - -/* override mprintf */ -#define mprintf(a,...) printf_utf8((a), __VA_ARGS__) -#define printf(a,...) printf_utf8((a), __VA_ARGS__) -#endif /* WINDOWS */ - static void local_do_shell(const char *args) { @@ -420,7 +399,7 @@ make_absolute(char *p, const char *pwd) p = abs_str; } - /* convert '\\' tp '/' */ + /* convert '\\' to '/' */ convertToForwardslash(p); /* Append "/" if needed to the absolute windows path */ @@ -925,23 +904,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path, } else mprintf("%s\n", d[n]->longname); } else { -#ifdef WINDOWS - /* cannot use printf_utf8 becuase of width specification */ - /* printf_utf8 does not account for utf-16 based argument widths */ - char *p = NULL; - wchar_t buf[1024]; - wchar_t* wtmp = utf8_to_utf16(fname); - swprintf(buf, 1024, L"%-*s", colspace, wtmp); - - if ((p = utf16_to_utf8(buf)) == NULL) - continue; - - write(STDOUT_FILENO, p, strlen(p)); - free(wtmp); - free(p); -#else mprintf("%-*s", colspace, fname); -#endif if (c >= columns) { printf("\n"); c = 1; @@ -1025,23 +988,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path, mprintf("%s\n", lname); free(lname); } else { -#ifdef WINDOWS - /* cannot use printf_utf8 becuase of width specification */ - /* printf_utf8 does not account for utf-16 based argument widths */ - char *p = NULL; - wchar_t buf[1024]; - wchar_t* wtmp = utf8_to_utf16(fname); - swprintf(buf, 1024, L"%-*s", colspace, wtmp); - - if ((p = utf16_to_utf8(buf)) == NULL) - continue; - - write(STDOUT_FILENO, p, strlen(p)); - free(wtmp); - free(p); -#else mprintf("%-*s", colspace, fname); -#endif if (c >= columns) { printf("\n"); c = 1; @@ -1065,23 +1012,34 @@ static int do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) { struct sftp_statvfs st; - char s_used[FMT_SCALED_STRSIZE]; - char s_avail[FMT_SCALED_STRSIZE]; - char s_root[FMT_SCALED_STRSIZE]; - char s_total[FMT_SCALED_STRSIZE]; - unsigned long long ffree; + char s_used[FMT_SCALED_STRSIZE], s_avail[FMT_SCALED_STRSIZE]; + char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE]; + char s_icapacity[16], s_dcapacity[16]; if (do_statvfs(conn, path, &st, 1) == -1) return -1; + if (st.f_files == 0) + strlcpy(s_icapacity, "ERR", sizeof(s_icapacity)); + else { + snprintf(s_icapacity, sizeof(s_icapacity), "%3llu%%", + (unsigned long long)(100 * (st.f_files - st.f_ffree) / + st.f_files)); + } + if (st.f_blocks == 0) + strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity)); + else { + snprintf(s_dcapacity, sizeof(s_dcapacity), "%3llu%%", + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } if (iflag) { - ffree = st.f_files ? (100 * (st.f_files - st.f_ffree) / st.f_files) : 0; printf(" Inodes Used Avail " "(root) %%Capacity\n"); - printf("%11llu %11llu %11llu %11llu %3llu%%\n", + printf("%11llu %11llu %11llu %11llu %s\n", (unsigned long long)st.f_files, (unsigned long long)(st.f_files - st.f_ffree), (unsigned long long)st.f_favail, - (unsigned long long)st.f_ffree, ffree); + (unsigned long long)st.f_ffree, s_icapacity); } else if (hflag) { strlcpy(s_used, "error", sizeof(s_used)); strlcpy(s_avail, "error", sizeof(s_avail)); @@ -1092,21 +1050,18 @@ do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) fmt_scaled(st.f_bfree * st.f_frsize, s_root); fmt_scaled(st.f_blocks * st.f_frsize, s_total); printf(" Size Used Avail (root) %%Capacity\n"); - printf("%7sB %7sB %7sB %7sB %3llu%%\n", - s_total, s_used, s_avail, s_root, - (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / - st.f_blocks)); + printf("%7sB %7sB %7sB %7sB %s\n", + s_total, s_used, s_avail, s_root, s_dcapacity); } else { printf(" Size Used Avail " "(root) %%Capacity\n"); - printf("%12llu %12llu %12llu %12llu %3llu%%\n", + printf("%12llu %12llu %12llu %12llu %s\n", (unsigned long long)(st.f_frsize * st.f_blocks / 1024), (unsigned long long)(st.f_frsize * (st.f_blocks - st.f_bfree) / 1024), (unsigned long long)(st.f_frsize * st.f_bavail / 1024), (unsigned long long)(st.f_frsize * st.f_bfree / 1024), - (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / - st.f_blocks)); + s_dcapacity); } return 0; } @@ -2211,20 +2166,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) interactive = !batchmode && isatty(STDIN_FILENO); err = 0; -#ifdef WINDOWS - /* Min buffer size allowed in Windows is 2*/ - setvbuf(stdout, NULL, _IOLBF, 2); - - /* We do this only in interactive mode as we are unable to read files with UTF8 BOM */ - if (interactive) { - setvbuf(infile, NULL, _IOLBF, 2); - _setmode(_fileno(stdin), O_U16TEXT); /* prepare for Unicode input */ - } -#else /* !WINDOWS */ setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(infile, NULL, _IOLBF, 0); -#endif /* !WINDOWS */ - for (;;) { char *cp; @@ -2232,25 +2175,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) signal(SIGINT, SIG_IGN); if (el == NULL) { -#ifdef WINDOWS - /* fgets on Windows does not support Unicode input*/ - if (interactive) { - wchar_t wcmd[2048]; - printf("sftp> "); - if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) { - printf("\n"); - break; - } - else { - char *pcmd = NULL; - if ((pcmd = utf16_to_utf8(wcmd)) == NULL) - fatal("failed to convert input arguments"); - strcpy(cmd, pcmd); - free(pcmd); - } - } else if (fgets(cmd, sizeof(cmd), infile) == NULL) - break; -#else /* !WINDOWS */ if (interactive) printf("sftp> "); if (fgets(cmd, sizeof(cmd), infile) == NULL) { @@ -2258,7 +2182,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) printf("\n"); break; } -#endif/* !WINDOWS */ if (!interactive) { /* Echo command */ mprintf("sftp> %s", cmd); if (strlen(cmd) > 0 && diff --git a/ssh-keygen.c b/ssh-keygen.c index 0734468..6d0f032 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.292 2016/09/12 03:29:16 dtucker Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.299 2017/03/10 04:26:06 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -37,6 +37,7 @@ #include #include #include +#include #include "xmalloc.h" #include "sshkey.h" @@ -57,6 +58,7 @@ #include "atomicio.h" #include "krl.h" #include "digest.h" +#include "utf8.h" #ifdef WITH_OPENSSL # define DEFAULT_KEY_TYPE_NAME "rsa" @@ -847,7 +849,7 @@ fingerprint_one_key(const struct sshkey *public, const char *comment) ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint failed", __func__); - printf("%u %s %s (%s)\n", sshkey_size(public), fp, + mprintf("%u %s %s (%s)\n", sshkey_size(public), fp, comment ? comment : "no comment", sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); @@ -1093,6 +1095,7 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; char *hashed, *cp, *hosts, *ohosts; int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); + int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM; switch (l->status) { case HKF_STATUS_OK: @@ -1101,11 +1104,10 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) * Don't hash hosts already already hashed, with wildcard * characters or a CA/revocation marker. */ - if ((l->match & HKF_MATCH_HOST_HASHED) != 0 || - has_wild || l->marker != MRK_NONE) { + if (was_hashed || has_wild || l->marker != MRK_NONE) { fprintf(ctx->out, "%s\n", l->line); if (has_wild && !find_host) { - logit("%s:%ld: ignoring host name " + logit("%s:%lu: ignoring host name " "with wildcard: %.64s", l->path, l->linenum, l->hosts); } @@ -1117,6 +1119,7 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) */ ohosts = hosts = xstrdup(l->hosts); while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { + lowercase(cp); if ((hashed = host_hash(cp, NULL, 0)) == NULL) fatal("hash_host failed"); fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); @@ -1127,7 +1130,7 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) case HKF_STATUS_INVALID: /* Retain invalid lines, but mark file as invalid. */ ctx->invalid = 1; - logit("%s:%ld: invalid line", l->path, l->linenum); + logit("%s:%lu: invalid line", l->path, l->linenum); /* FALLTHROUGH */ default: fprintf(ctx->out, "%s\n", l->line); @@ -1161,14 +1164,14 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) */ ctx->found_key = 1; if (!quiet) - printf("# Host %s found: line %ld\n", + printf("# Host %s found: line %lu\n", ctx->host, l->linenum); } return 0; } else if (find_host) { ctx->found_key = 1; if (!quiet) { - printf("# Host %s found: line %ld %s\n", + printf("# Host %s found: line %lu %s\n", ctx->host, l->linenum, l->marker == MRK_CA ? "CA" : (l->marker == MRK_REVOKE ? "REVOKED" : "")); @@ -1177,7 +1180,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) known_hosts_hash(l, ctx); else if (print_fingerprint) { fp = sshkey_fingerprint(l->key, fptype, rep); - printf("%s %s %s %s\n", ctx->host, + mprintf("%s %s %s %s\n", ctx->host, sshkey_type(l->key), fp, l->comment); free(fp); } else @@ -1188,7 +1191,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) /* Retain non-matching hosts when deleting */ if (l->status == HKF_STATUS_INVALID) { ctx->invalid = 1; - logit("%s:%ld: invalid line", l->path, l->linenum); + logit("%s:%lu: invalid line", l->path, l->linenum); } fprintf(ctx->out, "%s\n", l->line); } @@ -1333,7 +1336,7 @@ do_change_passphrase(struct passwd *pw) fatal("Failed to load key %s: %s", identity_file, ssh_err(r)); } if (comment) - printf("Key has comment '%s'\n", comment); + mprintf("Key has comment '%s'\n", comment); /* Ask the new passphrase (twice). */ if (identity_new_passphrase) { @@ -1457,7 +1460,10 @@ do_change_comment(struct passwd *pw) sshkey_free(private); exit(1); } - printf("Key now has comment '%s'\n", comment); + if (comment) + printf("Key now has comment '%s'\n", comment); + else + printf("Key now has no comment\n"); if (identity_comment) { strlcpy(new_comment, identity_comment, sizeof(new_comment)); @@ -2220,11 +2226,17 @@ do_check_krl(struct passwd *pw, int argc, char **argv) exit(ret); } +#ifdef WITH_SSH1 +# define RSA1_USAGE " | rsa1" +#else +# define RSA1_USAGE "" +#endif + static void usage(void) { fprintf(stderr, - "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]\n" + "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa%s]\n" " [-N new_passphrase] [-C comment] [-f output_keyfile]\n" " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n" " ssh-keygen -i [-m key_format] [-f input_keyfile]\n" @@ -2232,7 +2244,7 @@ usage(void) " ssh-keygen -y [-f input_keyfile]\n" " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" - " ssh-keygen -B [-f input_keyfile]\n"); + " ssh-keygen -B [-f input_keyfile]\n", RSA1_USAGE); #ifdef ENABLE_PKCS11 fprintf(stderr, " ssh-keygen -D pkcs11\n"); @@ -2297,6 +2309,8 @@ main(int argc, char **argv) seed_rng(); + msetlocale(); + /* we need this for the home * directory. */ pw = getpwuid(getuid()); if (!pw) diff --git a/ssh-keyscan.c b/ssh-keyscan.c index eea8d0a..1f95239 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.107 2017/01/06 03:41:58 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.109 2017/03/10 04:26:06 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -321,16 +321,18 @@ keygrab_ssh2(con *c) } static void -keyprint_one(char *host, struct sshkey *key) +keyprint_one(const char *host, struct sshkey *key) { char *hostport; - - if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL) - fatal("host_hash failed"); + const char *known_host, *hashed; hostport = put_host_port(host, ssh_port); + lowercase(hostport); + if (hash_hosts && (hashed = host_hash(host, NULL, 0)) == NULL) + fatal("host_hash failed"); + known_host = hash_hosts ? hashed : hostport; if (!get_cert) - fprintf(stdout, "%s ", hostport); + fprintf(stdout, "%s ", known_host); sshkey_write(key, stdout); fputs("\n", stdout); free(hostport); diff --git a/ssh.c b/ssh.c index f718e42..2abc23d 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.448 2016/12/06 07:48:01 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.451 2017/03/10 04:07:20 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -684,11 +684,11 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0) cp = kex_alg_list('\n'); else if (strcmp(optarg, "key") == 0) - cp = sshkey_alg_list(0, 0, '\n'); + cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) - cp = sshkey_alg_list(1, 0, '\n'); + cp = sshkey_alg_list(1, 0, 0, '\n'); else if (strcmp(optarg, "key-plain") == 0) - cp = sshkey_alg_list(0, 1, '\n'); + cp = sshkey_alg_list(0, 1, 0, '\n'); else if (strcmp(optarg, "protocol-version") == 0) { #ifdef WITH_SSH1 cp = xstrdup("1\n2"); @@ -1103,7 +1103,7 @@ main(int ac, char **av) options.proxy_use_fdpass = 0; snprintf(port_s, sizeof(port_s), "%d", options.jump_port); xasprintf(&options.proxy_command, - "ssh%s%s%s%s%s%s%s%s%s%.*s -W %%h:%%p %s", + "ssh%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s", /* Optional "-l user" argument if jump_user set */ options.jump_user == NULL ? "" : " -l ", options.jump_user == NULL ? "" : options.jump_user, diff --git a/ssh_config.5 b/ssh_config.5 index 016adbc..532745b 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.241 2017/02/03 23:01:19 djm Exp $ -.Dd $Mdocdate: February 3 2017 $ +.\" $OpenBSD: ssh_config.5,v 1.242 2017/02/27 14:30:33 jmc Exp $ +.Dd $Mdocdate: February 27 2017 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -1147,7 +1147,7 @@ However, this option disables host authentication for localhost. The argument to this keyword must be .Cm yes or -.Cm no . +.Cm no (the default). .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. diff --git a/sshconnect.c b/sshconnect.c index ac3b40c..e3ad04d 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.272 2016/09/12 01:22:38 deraadt Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.273 2017/03/10 03:22:40 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1553,6 +1553,7 @@ maybe_add_key_to_agent(char *authfile, Key *private, char *comment, if (options.add_keys_to_agent == 2 && !ask_permission("Add key %s (%s) to agent?", authfile, comment)) { debug3("user denied adding this key"); + close(auth_sock); return; } @@ -1561,4 +1562,5 @@ maybe_add_key_to_agent(char *authfile, Key *private, char *comment, debug("identity added to agent: %s", authfile); else debug("could not add identity to agent: %s (%d)", authfile, r); + close(auth_sock); } diff --git a/sshconnect1.c b/sshconnect1.c index a045361..dc00b4c 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect1.c,v 1.79 2016/09/19 07:52:42 natano Exp $ */ +/* $OpenBSD: sshconnect1.c,v 1.80 2017/03/10 03:53:11 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -520,7 +520,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) cookie[i] = packet_get_char(); /* Get the public key. */ - server_key = key_new(KEY_RSA1); + if ((server_key = key_new(KEY_RSA1)) == NULL) + fatal("%s: key_new(KEY_RSA1) failed", __func__); bits = packet_get_int(); packet_get_bignum(server_key->rsa->e); packet_get_bignum(server_key->rsa->n); @@ -532,7 +533,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) logit("Warning: This may be due to an old implementation of ssh."); } /* Get the host key. */ - host_key = key_new(KEY_RSA1); + if ((host_key = key_new(KEY_RSA1)) == NULL) + fatal("%s: key_new(KEY_RSA1) failed", __func__); bits = packet_get_int(); packet_get_bignum(host_key->rsa->e); packet_get_bignum(host_key->rsa->n); diff --git a/sshd.c b/sshd.c index 364ac9e..226c4e4 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.482 2017/02/06 09:22:51 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.483 2017/02/24 03:16:34 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1084,15 +1084,11 @@ server_listen(void) close(listen_sock); continue; } -#ifdef WINDOWS - /* disable inheritance on listener socket */ - if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) != 0) { - error("F_SETFD FD_CLOEXEC on socket %d error %d", - listen_sock, errno); + if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) { + verbose("socket: CLOEXEC: %s", strerror(errno)); close(listen_sock); continue; } -#endif /* WINDOWS */ /* * Set socket options. * Allow local port reuse in TIME_WAIT. diff --git a/sshkey.c b/sshkey.c index c01da6c..53a7674 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.41 2016/10/24 01:09:17 dtucker Exp $ */ +/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -89,7 +89,9 @@ static const struct keytype keytypes[] = { { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", KEY_ED25519_CERT, 0, 1, 0 }, #ifdef WITH_OPENSSL +# ifdef WITH_SSH1 { NULL, "RSA1", KEY_RSA1, 0, 0, 0 }, +# endif { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, @@ -195,14 +197,16 @@ sshkey_ecdsa_nid_from_name(const char *name) } char * -sshkey_alg_list(int certs_only, int plain_only, char sep) +sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) { char *tmp, *ret = NULL; size_t nlen, rlen = 0; const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { - if (kt->name == NULL || kt->sigonly) + if (kt->name == NULL) + continue; + if (!include_sigonly && kt->sigonly) continue; if ((certs_only && !kt->cert) || (plain_only && kt->cert)) continue; @@ -1237,6 +1241,9 @@ sshkey_read(struct sshkey *ret, char **cpp) u_long bits; #endif /* WITH_SSH1 */ + if (ret == NULL) + return SSH_ERR_INVALID_ARGUMENT; + cp = *cpp; switch (ret->type) { @@ -3786,7 +3793,46 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase)) == NULL) { - r = SSH_ERR_KEY_WRONG_PASSPHRASE; + unsigned long pem_err = ERR_peek_last_error(); + int pem_reason = ERR_GET_REASON(pem_err); + + /* + * Translate OpenSSL error codes to determine whether + * passphrase is required/incorrect. + */ + switch (ERR_GET_LIB(pem_err)) { + case ERR_LIB_PEM: + switch (pem_reason) { + case PEM_R_BAD_PASSWORD_READ: + case PEM_R_PROBLEMS_GETTING_PASSWORD: + case PEM_R_BAD_DECRYPT: + r = SSH_ERR_KEY_WRONG_PASSPHRASE; + goto out; + default: + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + case ERR_LIB_EVP: + switch (pem_reason) { + case EVP_R_BAD_DECRYPT: + r = SSH_ERR_KEY_WRONG_PASSPHRASE; + goto out; + case EVP_R_BN_DECODE_ERROR: + case EVP_R_DECODE_ERROR: +#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + case EVP_R_PRIVATE_KEY_DECODE_ERROR: +#endif + r = SSH_ERR_INVALID_FORMAT; + goto out; + default: + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + case ERR_LIB_ASN1: + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (pk->type == EVP_PKEY_RSA && @@ -3860,6 +3906,8 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { + int r = SSH_ERR_INTERNAL_ERROR; + if (keyp != NULL) *keyp = NULL; if (commentp != NULL) @@ -3882,9 +3930,11 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, return sshkey_parse_private2(blob, type, passphrase, keyp, commentp); case KEY_UNSPEC: - if (sshkey_parse_private2(blob, type, passphrase, keyp, - commentp) == 0) - return 0; + r = sshkey_parse_private2(blob, type, passphrase, keyp, + commentp); + /* Do not fallback to PEM parser if only passphrase is wrong. */ + if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE) + return r; #ifdef WITH_OPENSSL return sshkey_parse_private_pem_fileblob(blob, type, passphrase, keyp); diff --git a/sshkey.h b/sshkey.h index f393638..1b9e42f 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.14 2016/09/12 23:31:27 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.15 2017/03/10 04:07:20 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -156,7 +156,7 @@ int sshkey_ec_validate_private(const EC_KEY *); const char *sshkey_ssh_name(const struct sshkey *); const char *sshkey_ssh_name_plain(const struct sshkey *); int sshkey_names_valid2(const char *, int); -char *sshkey_alg_list(int, int, char); +char *sshkey_alg_list(int, int, int, char); int sshkey_from_blob(const u_char *, size_t, struct sshkey **); int sshkey_fromb(struct sshbuf *, struct sshkey **); diff --git a/sshtty.c b/sshtty.c index aca8899..5825c85 100644 --- a/sshtty.c +++ b/sshtty.c @@ -52,8 +52,8 @@ static int _in_raw_mode = 0; * TTY raw mode routines for Windows */ -int ConInit(DWORD OutputHandle, BOOL fSmartInit); -int ConUnInit(void); +int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit); +int ConExitRawMode(void); struct termios term_settings; @@ -70,12 +70,12 @@ struct termios * void leave_raw_mode(int quiet) { - ConUnInit(); + ConExitRawMode(); } void enter_raw_mode(int quiet) { - ConInit(STD_OUTPUT_HANDLE, TRUE); + ConEnterRawMode(STD_OUTPUT_HANDLE, TRUE); } #else /* !WINDOWS */ struct termios * diff --git a/utf8.c b/utf8.c index 1f0dc44..6fb05bb 100644 --- a/utf8.c +++ b/utf8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utf8.c,v 1.4 2017/02/02 10:54:25 jsg Exp $ */ +/* $OpenBSD: utf8.c,v 1.5 2017/02/19 00:10:57 djm Exp $ */ /* * Copyright (c) 2016 Ingo Schwarze * @@ -57,16 +57,11 @@ static int vasnmprintf(char **, size_t, int *, const char *, va_list); static int dangerous_locale(void) { -#ifdef WINDOWS - wchar_t loc[LOCALE_NAME_MAX_LENGTH]; - GetSystemDefaultLocaleName(loc, LOCALE_NAME_MAX_LENGTH); - return wcscmp(loc, L"US-ASCII") && wcscmp(loc, L"UTF-8"); -#else /* !WINDOWS */ char *loc; loc = nl_langinfo(CODESET); - return strcmp(loc, "US-ASCII") && strcmp(loc, "UTF-8"); -#endif /* !WINDOWS */ + return strcmp(loc, "US-ASCII") != 0 && strcmp(loc, "UTF-8") != 0 && + strcmp(loc, "ANSI_X3.4-1968") != 0; } static int @@ -337,3 +332,4 @@ msetlocale(void) /* We can handle this locale */ setlocale(LC_CTYPE, ""); } +