mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-21 04:54:48 +02:00
Source snapshot from Powershell/openssh-portable:latestw_cwb
This commit is contained in:
parent
15c6a77338
commit
a4b577b5a0
2
README
2
README
@ -1,4 +1,4 @@
|
||||
See https://www.openssh.com/releasenotes.html#7.3p1 for the release notes.
|
||||
See https://www.openssh.com/releasenotes.html#7.4p1 for the release notes.
|
||||
|
||||
Please read https://www.openssh.com/report.html for bug reporting
|
||||
instructions and note that we do not use Github for bug reporting or
|
||||
|
@ -1,10 +1,10 @@
|
||||
version: 0.0.4.0.{build}
|
||||
version: 0.0.6.0.{build}
|
||||
image: Visual Studio 2015
|
||||
|
||||
branches:
|
||||
only:
|
||||
- V_7_3w
|
||||
- latestw_cwb
|
||||
- latestw_all
|
||||
- latestw_all_openssl
|
||||
|
||||
init:
|
||||
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
8
auth.c
8
auth.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.c,v 1.118 2016/11/08 22:04:34 djm Exp $ */
|
||||
/* $OpenBSD: auth.c,v 1.119 2016/12/15 21:29:05 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -192,7 +192,7 @@ allowed_user(struct passwd * pw)
|
||||
|
||||
/* Return false if user is listed in DenyUsers */
|
||||
if (options.num_deny_users > 0) {
|
||||
for (i = 0; i < options.num_deny_users; i++)
|
||||
for (i = 0; i < options.num_deny_users; i++) {
|
||||
r = match_user(pw->pw_name, hostname, ipaddr,
|
||||
options.deny_users[i]);
|
||||
if (r < 0) {
|
||||
@ -204,6 +204,7 @@ allowed_user(struct passwd * pw)
|
||||
pw->pw_name, hostname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Return false if AllowUsers isn't empty and user isn't listed there */
|
||||
if (options.num_allow_users > 0) {
|
||||
@ -576,7 +577,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
||||
struct stat st;
|
||||
int fd;
|
||||
FILE *f;
|
||||
|
||||
|
||||
#ifdef WINDOWS
|
||||
/* Windows POSIX adpater does not support fdopen() on open(file)*/
|
||||
if ((f = fopen(file, "r")) == NULL) {
|
||||
@ -616,6 +617,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -245,10 +245,11 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
* if a user is not allowed to login. is this an
|
||||
* issue? -markus
|
||||
*/
|
||||
#ifndef WINDOWS
|
||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0)))
|
||||
#endif /* !WINDOWS */
|
||||
#ifdef WINDOWS /* key validation in done in agent for Windows */
|
||||
{
|
||||
#else /* !WINDOWS */
|
||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
|
||||
#endif /* !WINDOWS */
|
||||
packet_start(SSH2_MSG_USERAUTH_PK_OK);
|
||||
packet_put_string(pkalg, alen);
|
||||
packet_put_string(pkblob, blen);
|
||||
|
@ -2049,6 +2049,7 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
|
||||
c->notbefore = monotime() + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WINDOWS /*TODO - implement user check for Windows*/
|
||||
if (getpeereid(newsock, &euid, &egid) < 0) {
|
||||
error("%s getpeereid failed: %s", __func__,
|
||||
|
@ -1273,6 +1273,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
||||
}
|
||||
continue;
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
case '?':
|
||||
print_escape_help(berr, escape_char, compat20,
|
||||
(c && c->ctl_chan != -1),
|
||||
|
@ -1,4 +1,4 @@
|
||||
%define ver 7.3p1
|
||||
%define ver 7.4p1
|
||||
%define rel 1
|
||||
|
||||
# OpenSSH privilege separation requires a user & group ID
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
||||
Name: openssh
|
||||
Version: 7.3p1
|
||||
Version: 7.4p1
|
||||
URL: https://www.openssh.com/
|
||||
Release: 1
|
||||
Source0: openssh-%{version}.tar.gz
|
||||
|
@ -3,6 +3,7 @@ Set-StrictMode -Version Latest
|
||||
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE
|
||||
[string] $script:vcPath = $null
|
||||
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
|
||||
[System.IO.DirectoryInfo] $script:gitRoot = $null
|
||||
[bool] $script:Verbose = $false
|
||||
[string] $script:BuildLogFile = $null
|
||||
|
||||
@ -268,6 +269,34 @@ function Start-SSHBootstrap
|
||||
}
|
||||
}
|
||||
|
||||
function Clone-Win32OpenSSH
|
||||
{
|
||||
$win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH"
|
||||
if (-not (Test-Path -Path $win32OpenSSHPath -PathType Container))
|
||||
{
|
||||
Write-BuildMsg -AsInfo -Message "clone repo Win32-OpenSSH"
|
||||
Push-Location $gitRoot
|
||||
git clone -q --recursive https://github.com/PowerShell/Win32-OpenSSH.git $win32OpenSSHPath
|
||||
Pop-Location
|
||||
}
|
||||
Write-BuildMsg -AsInfo -Message "pull latest from repo Win32-OpenSSH"
|
||||
Push-Location $win32OpenSSHPath
|
||||
git fetch -q origin
|
||||
git checkout -qf L1-Prod
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
function Copy-OpenSSLSDK
|
||||
{
|
||||
$sourcePath = Join-Path $script:gitRoot "Win32-OpenSSH\contrib\win32\openssh\OpenSSLSDK"
|
||||
Write-BuildMsg -AsInfo -Message "copying $sourcePath"
|
||||
Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e
|
||||
if($e -ne $null)
|
||||
{
|
||||
Write-BuildMsg -AsError -ErrorAction Stop -Message "Copy OpenSSL from $sourcePath failed "
|
||||
}
|
||||
}
|
||||
|
||||
function Start-SSHBuild
|
||||
{
|
||||
[CmdletBinding(SupportsShouldProcess=$false)]
|
||||
@ -286,6 +315,8 @@ function Start-SSHBuild
|
||||
|
||||
# Get openssh-portable root
|
||||
$script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName
|
||||
$script:gitRoot = split-path $script:OpenSSHRoot
|
||||
|
||||
|
||||
if($PSBoundParameters.ContainsKey("Verbose"))
|
||||
{
|
||||
@ -302,6 +333,9 @@ function Start-SSHBuild
|
||||
Write-BuildMsg -AsInfo -Message "Build Log: $($script:BuildLogFile)"
|
||||
|
||||
Start-SSHBootstrap
|
||||
|
||||
Clone-Win32OpenSSH
|
||||
Copy-OpenSSLSDK
|
||||
$msbuildCmd = "msbuild.exe"
|
||||
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
|
||||
$cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
|
||||
@ -380,4 +414,4 @@ function Get-RepositoryRoot
|
||||
throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository")
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile
|
||||
Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile, Clone-Win32OpenSSH, Copy-OpenSSLSDK
|
@ -876,7 +876,7 @@
|
||||
/* #undef HAVE_SET_ID */
|
||||
|
||||
/* Define to 1 if you have the `SHA256_Update' function. */
|
||||
#define HAVE_SHA256_UPDATE 1
|
||||
/* #undef HAVE_SHA256_UPDATE */
|
||||
|
||||
/* Define to 1 if you have the <sha2.h> header file. */
|
||||
/* #undef HAVE_SHA2_H */
|
||||
|
@ -1,11 +1,15 @@
|
||||
$scriptpath = $MyInvocation.MyCommand.Path
|
||||
# @manojampalam - authored initial script
|
||||
# @friism - Fixed issue with invalid SDDL on Set-Acl
|
||||
|
||||
$scriptpath = $MyInvocation.MyCommand.Path
|
||||
$scriptdir = Split-Path $scriptpath
|
||||
|
||||
$sshdpath = Join-Path $scriptdir "sshd.exe"
|
||||
$sshagentpath = Join-Path $scriptdir "ssh-agent.exe"
|
||||
$logsdir = Join-Path $scriptdir "logs"
|
||||
|
||||
$ntrights = "ntrights.exe -u `"NT SERVICE\SSHD`" +r SeAssignPrimaryTokenPrivilege"
|
||||
$account = "NT SERVICE\SSHD"
|
||||
$ntrights = "ntrights.exe -u `"{0}`" +r SeAssignPrimaryTokenPrivilege" -f $account
|
||||
|
||||
if (-not (Test-Path $sshdpath)) {
|
||||
throw "sshd.exe is not present in script path"
|
||||
@ -27,7 +31,7 @@ New-Service -Name ssh-agent -BinaryPathName $sshagentpath -Description "SSH Agen
|
||||
cmd.exe /c 'sc.exe sdset ssh-agent D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)'
|
||||
|
||||
New-Service -Name sshd -BinaryPathName $sshdpath -Description "SSH Deamon" -StartupType Manual -DependsOn ssh-agent | Out-Null
|
||||
sc.exe config sshd obj= "NT SERVICE\SSHD"
|
||||
sc.exe config sshd obj= $account
|
||||
|
||||
Push-Location
|
||||
cd $scriptdir
|
||||
@ -35,9 +39,9 @@ cmd.exe /c $ntrights
|
||||
Pop-Location
|
||||
|
||||
mkdir $logsdir > $null
|
||||
$sddl = "O:SYG:DUD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x12019f;;;S-1-5-80-3847866527-469524349-687026318-516638107-1125189541)"
|
||||
$rights = [System.Security.AccessControl.FileSystemRights]"Read, Write"
|
||||
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($account, $rights, "ContainerInherit,ObjectInherit", "None", "Allow")
|
||||
$acl = Get-Acl -Path $logsdir
|
||||
$acl.SetSecurityDescriptorSddlForm($sddl)
|
||||
$Acl.SetAccessRule($accessRule)
|
||||
Set-Acl -Path $logsdir -AclObject $acl
|
||||
Write-Host -ForegroundColor Green "sshd and ssh-agent services successfully installed"
|
||||
|
||||
|
@ -194,7 +194,7 @@
|
||||
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)digest-libc.c">
|
||||
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="$(UseOpenSSL)==true">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)dispatch.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)dns.c" />
|
||||
@ -285,7 +285,9 @@
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)sandbox-pledge.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)utf8.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\ttymodes_windows.c" />
|
||||
<ClCompile Include="..\..\..\digest-openssl.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)digest-openssl.c">
|
||||
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)crypto-wrap.h" />
|
||||
|
Binary file not shown.
@ -155,11 +155,11 @@
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_dirent.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\no-ops.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_zlib.c" />
|
||||
<ClCompile Include="..\win32compat\ansiprsr.c" />
|
||||
<ClCompile Include="..\win32compat\conio.c" />
|
||||
<ClCompile Include="..\win32compat\console.c" />
|
||||
<ClCompile Include="..\win32compat\tncon.c" />
|
||||
<ClCompile Include="..\win32compat\tnnet.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ansiprsr.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\conio.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
|
||||
@ -198,6 +198,7 @@
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\termios.h" />
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\dirent.h" />
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\misc_internal.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -117,6 +117,7 @@
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
||||
<ClInclude Include="..\win32compat\misc_internal.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="inc">
|
||||
|
@ -199,9 +199,14 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cf_flags->dwShareMode = 0;
|
||||
|
||||
switch (rwflags) {
|
||||
case O_RDONLY:
|
||||
cf_flags->dwDesiredAccess = GENERIC_READ;
|
||||
/*todo: need to review to make sure all flags are correct*/
|
||||
if (flags & O_NONBLOCK)
|
||||
cf_flags->dwShareMode = FILE_SHARE_READ;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
cf_flags->dwDesiredAccess = GENERIC_WRITE;
|
||||
@ -211,8 +216,6 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
||||
break;
|
||||
}
|
||||
|
||||
cf_flags->dwShareMode = 0;
|
||||
|
||||
cf_flags->securityAttributes.lpSecurityDescriptor = NULL;
|
||||
cf_flags->securityAttributes.bInheritHandle = TRUE;
|
||||
cf_flags->securityAttributes.nLength = 0;
|
||||
@ -230,7 +233,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
||||
if (c_s_flags & O_APPEND)
|
||||
cf_flags->dwDesiredAccess = FILE_APPEND_DATA;
|
||||
|
||||
cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION;
|
||||
cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION | FILE_FLAG_BACKUP_SEMANTICS;
|
||||
|
||||
/*TODO - map mode */
|
||||
|
||||
|
@ -159,3 +159,6 @@ explicit_bzero(void *b, size_t len);
|
||||
#define fopen w32_fopen_utf8
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
|
||||
void convertToBackslash(char *str);
|
||||
void convertToForwardslash(char *str);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "inc\sys\time.h"
|
||||
#include <time.h>
|
||||
#include <Shlwapi.h>
|
||||
#include "misc_internal.h"
|
||||
|
||||
int usleep(unsigned int useconds)
|
||||
{
|
||||
@ -302,11 +303,25 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) {
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
BOOL b;
|
||||
char* abs_cmd;
|
||||
char *abs_cmd, *t;
|
||||
wchar_t * cmd_utf16;
|
||||
int add_module_path = 0;
|
||||
|
||||
/* relative ? if so, add current module path to start */
|
||||
if (!(cmd && cmd[0] != '\0' && (cmd[1] == ':' || cmd[0] == '\\' || cmd[0] == '.'))) {
|
||||
/* should module path be added */
|
||||
do{
|
||||
if(!cmd)
|
||||
break;
|
||||
t = cmd;
|
||||
if (*t == '\"')
|
||||
t++;
|
||||
if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
|
||||
break;
|
||||
add_module_path = 1;
|
||||
|
||||
} while (0);
|
||||
|
||||
/* add current module path to start if needed */
|
||||
if (add_module_path) {
|
||||
char* ctr;
|
||||
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1);
|
||||
if (abs_cmd == NULL) {
|
||||
@ -478,8 +493,6 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *realpath_win(const char *path, char resolved[MAX_PATH]);
|
||||
|
||||
int
|
||||
w32_utimes(const char *filename, struct timeval *tvp) {
|
||||
struct utimbuf ub;
|
||||
@ -487,10 +500,7 @@ w32_utimes(const char *filename, struct timeval *tvp) {
|
||||
ub.modtime = tvp[1].tv_sec;
|
||||
int ret;
|
||||
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(filename, resolvedPathName);
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename));
|
||||
if (resolvedPathName_utf16 == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -517,16 +527,9 @@ link(const char *oldpath, const char *newpath) {
|
||||
|
||||
int
|
||||
w32_rename(const char *old_name, const char *new_name) {
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedOldPathName[MAX_PATH];
|
||||
realpath_win(old_name, resolvedOldPathName);
|
||||
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedNewPathName[MAX_PATH];
|
||||
realpath_win(new_name, resolvedNewPathName);
|
||||
|
||||
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(resolvedOldPathName);
|
||||
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(resolvedNewPathName);
|
||||
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(sanitized_path(old_name));
|
||||
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(sanitized_path(new_name));
|
||||
|
||||
if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -541,11 +544,8 @@ w32_rename(const char *old_name, const char *new_name) {
|
||||
|
||||
int
|
||||
w32_unlink(const char *path) {
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(path, resolvedPathName);
|
||||
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
||||
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
|
||||
if (NULL == resolvedPathName_utf16) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -559,11 +559,7 @@ w32_unlink(const char *path) {
|
||||
|
||||
int
|
||||
w32_rmdir(const char *path) {
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(path, resolvedPathName);
|
||||
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
|
||||
if (NULL == resolvedPathName_utf16) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -606,11 +602,8 @@ w32_getcwd(char *buffer, int maxlen) {
|
||||
|
||||
int
|
||||
w32_mkdir(const char *path_utf8, unsigned short mode) {
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(path_utf8, resolvedPathName);
|
||||
|
||||
wchar_t *path_utf16 = utf8_to_utf16(resolvedPathName);
|
||||
|
||||
wchar_t *path_utf16 = utf8_to_utf16(sanitized_path(path_utf8));
|
||||
if (path_utf16 == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -621,86 +614,62 @@ w32_mkdir(const char *path_utf8, unsigned short mode) {
|
||||
return returnStatus;
|
||||
}
|
||||
|
||||
void
|
||||
getrnd(u_char *s, size_t len) {
|
||||
HCRYPTPROV hProvider;
|
||||
if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT) == FALSE ||
|
||||
CryptGenRandom(hProvider, len, s) == FALSE ||
|
||||
CryptReleaseContext(hProvider, 0) == FALSE)
|
||||
DebugBreak();
|
||||
}
|
||||
|
||||
int
|
||||
w32_stat(const char *path, struct w32_stat *buf) {
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(path, resolvedPathName);
|
||||
|
||||
return fileio_stat(resolvedPathName, (struct _stat64*)buf);
|
||||
return fileio_stat(sanitized_path(path), (struct _stat64*)buf);
|
||||
}
|
||||
|
||||
// if file is symbolic link, copy its link into "link" .
|
||||
int
|
||||
readlink(const char *path, char *link, int linklen)
|
||||
{
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(path, resolvedPathName);
|
||||
|
||||
strcpy_s(link, linklen, resolvedPathName);
|
||||
strcpy_s(link, linklen, sanitized_path(path));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// convert forward slash to back slash
|
||||
void
|
||||
convertToBackslash(char *str) {
|
||||
while (*str) {
|
||||
if (*str == '/')
|
||||
*str = '\\';
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
// convert back slash to forward slash
|
||||
void
|
||||
convertToForwardslash(char *str) {
|
||||
while (*str) {
|
||||
if (*str == '\\')
|
||||
*str = '/';
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This method will expands all symbolic links and resolves references to /./,
|
||||
* /../ and extra '/' characters in the null-terminated string named by
|
||||
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
|
||||
* path to produce a canonicalized absolute pathname.
|
||||
*/
|
||||
char *
|
||||
realpath(const char *path, char resolved[MAX_PATH])
|
||||
{
|
||||
realpath(const char *path, char resolved[MAX_PATH]) {
|
||||
char tempPath[MAX_PATH];
|
||||
|
||||
if ((0 == strcmp(path, "./")) || (0 == strcmp(path, "."))) {
|
||||
tempPath[0] = '/';
|
||||
_getcwd(&tempPath[1], sizeof(tempPath) - 1);
|
||||
slashconvert(tempPath);
|
||||
|
||||
strncpy(resolved, tempPath, strlen(tempPath) + 1);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
if (path[0] != '/')
|
||||
strlcpy(resolved, path, sizeof(tempPath));
|
||||
|
||||
if (*path == '/' && *(path + 2) == ':')
|
||||
strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
|
||||
else
|
||||
strlcpy(resolved, path + 1, sizeof(tempPath));
|
||||
strncpy(resolved, path, strlen(path) + 1);
|
||||
|
||||
backslashconvert(resolved);
|
||||
PathCanonicalizeA(tempPath, resolved);
|
||||
slashconvert(tempPath);
|
||||
|
||||
// Store terminating slash in 'X:/' on Windows.
|
||||
if (tempPath[1] == ':' && tempPath[2] == 0) {
|
||||
tempPath[2] = '/';
|
||||
tempPath[3] = 0;
|
||||
}
|
||||
if (_fullpath(tempPath, resolved, MAX_PATH) == NULL)
|
||||
return NULL;
|
||||
|
||||
convertToForwardslash(tempPath);
|
||||
|
||||
resolved[0] = '/'; // will be our first slash in /x:/users/test1 format
|
||||
strncpy(resolved + 1, tempPath, sizeof(tempPath) - 1);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
// like realpathWin32() but takes out the first slash so that windows systems can work on the actual file or directory
|
||||
char *
|
||||
realpath_win(const char *path, char resolved[MAX_PATH])
|
||||
{
|
||||
char tempPath[MAX_PATH];
|
||||
realpath(path, tempPath);
|
||||
|
||||
strncpy(resolved, &tempPath[1], sizeof(tempPath) - 1);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
// Maximum reparse buffer info size. The max user defined reparse
|
||||
// data is 16KB, plus there's a header.
|
||||
#define MAX_REPARSE_SIZE 17000
|
||||
@ -737,8 +706,7 @@ typedef struct _REPARSE_DATA_BUFFER {
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
BOOL
|
||||
ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags)
|
||||
{
|
||||
ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) {
|
||||
HANDLE fileHandle;
|
||||
BYTE reparseBuffer[MAX_REPARSE_SIZE];
|
||||
PBYTE reparseData;
|
||||
|
3
contrib/win32/win32compat/misc_internal.h
Normal file
3
contrib/win32/win32compat/misc_internal.h
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
|
||||
#define sanitized_path(p) (((p)[0] == '/' && (p)[1] != '\0' && (p)[2] == ':')? (p)+1 : (p))
|
@ -231,32 +231,6 @@ char *user_from_uid(uid_t uid, int nouser) {
|
||||
return "-";
|
||||
}
|
||||
|
||||
|
||||
/* TODO - this is moved from realpath.c in openbsdcompat. Review and finalize its position*/
|
||||
|
||||
#include <Shlwapi.h>
|
||||
|
||||
void backslashconvert(char *str)
|
||||
{
|
||||
while (*str) {
|
||||
if (*str == '/')
|
||||
*str = '\\'; // convert forward slash to back slash
|
||||
str++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// convert back slash to forward slash
|
||||
void slashconvert(char *str)
|
||||
{
|
||||
while (*str) {
|
||||
if (*str == '\\')
|
||||
*str = '/'; // convert back slash to forward slash
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uid_t
|
||||
getuid(void) {
|
||||
return 0;
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <winioctl.h>
|
||||
#include "Shlwapi.h"
|
||||
#include <sys\utime.h>
|
||||
#include "misc_internal.h"
|
||||
|
||||
/* internal table that stores the fd to w32_io mapping*/
|
||||
struct w32fd_table {
|
||||
@ -347,7 +348,7 @@ w32_pipe(int *pfds) {
|
||||
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
||||
return 0;
|
||||
}
|
||||
char *realpath_win(const char *path, char resolved[MAX_PATH]);
|
||||
|
||||
int
|
||||
w32_open(const char *pathname, int flags, ...) {
|
||||
int min_index = fd_table_get_min_index();
|
||||
@ -357,18 +358,14 @@ w32_open(const char *pathname, int flags, ...) {
|
||||
if (min_index == -1)
|
||||
return -1;
|
||||
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(pathname, resolvedPathName);
|
||||
|
||||
pio = fileio_open(resolvedPathName, flags, 0);
|
||||
pio = fileio_open(sanitized_path(pathname), flags, 0);
|
||||
if (pio == NULL)
|
||||
return -1;
|
||||
|
||||
pio->type = NONSOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
||||
debug3("open - path:%s", resolvedPathName);
|
||||
debug3("open - path:%s", pathname);
|
||||
return min_index;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "inc\dirent.h"
|
||||
#include "inc\libgen.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
|
||||
struct DIR_ {
|
||||
@ -19,8 +20,6 @@ struct DIR_ {
|
||||
int first;
|
||||
};
|
||||
|
||||
char * realpath_win(const char *path, char resolved[MAX_PATH]);
|
||||
|
||||
/* Open a directory stream on NAME.
|
||||
Return a DIR stream on the directory, or NULL if it could not be opened. */
|
||||
DIR * opendir(const char *name)
|
||||
@ -32,11 +31,7 @@ DIR * opendir(const char *name)
|
||||
wchar_t* wname = NULL;
|
||||
int needed;
|
||||
|
||||
// Skip the first '/' in the pathname
|
||||
char resolvedPathName[MAX_PATH];
|
||||
realpath_win(name, resolvedPathName);
|
||||
|
||||
if ((wname = utf8_to_utf16(resolvedPathName)) == NULL) {
|
||||
if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
4
dh.c
4
dh.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: dh.c,v 1.61 2016/09/12 01:22:38 deraadt Exp $ */
|
||||
/* $OpenBSD: dh.c,v 1.62 2016/12/15 21:20:41 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
*
|
||||
@ -152,7 +152,7 @@ choose_dh(int min, int wantbits, int max)
|
||||
struct dhgroup dhg;
|
||||
|
||||
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
|
||||
logit("WARNING: could open open %s (%s), using fixed modulus",
|
||||
logit("WARNING: could not open %s (%s), using fixed modulus",
|
||||
_PATH_DH_MODULI, strerror(errno));
|
||||
return (dh_new_group_fallback(max));
|
||||
}
|
||||
|
1
log.c
1
log.c
@ -446,7 +446,6 @@ do_log(LogLevel level, const char *fmt, va_list args)
|
||||
}
|
||||
strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
|
||||
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
|
||||
|
||||
if (log_handler != NULL) {
|
||||
/* Avoid recursion */
|
||||
tmp_handler = log_handler;
|
||||
|
2
misc.c
2
misc.c
@ -432,7 +432,6 @@ char *
|
||||
colon(char *cp)
|
||||
{
|
||||
int flag = 0;
|
||||
int len = 0;
|
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return NULL;
|
||||
@ -627,6 +626,7 @@ tilde_expand_filename(const char *filename, uid_t uid)
|
||||
|
||||
if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
|
||||
fatal("tilde_expand_filename: Path too long");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,18 @@ _rs_init(u_char *buf, size_t n)
|
||||
}
|
||||
|
||||
#ifndef WITH_OPENSSL
|
||||
#ifdef WINDOWS
|
||||
#include <Wincrypt.h>
|
||||
static void
|
||||
getrnd(u_char *s, size_t len) {
|
||||
HCRYPTPROV hProvider;
|
||||
if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT) == FALSE ||
|
||||
CryptGenRandom(hProvider, len, s) == FALSE ||
|
||||
CryptReleaseContext(hProvider, 0) == FALSE)
|
||||
DebugBreak();
|
||||
}
|
||||
|
||||
#else /* !WINDOWS */
|
||||
#define SSH_RANDOM_DEV "/dev/urandom"
|
||||
/* XXX use getrandom() if supported on Linux */
|
||||
static void
|
||||
@ -101,6 +113,7 @@ getrnd(u_char *s, size_t len)
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
#endif /* !WINDOWS */
|
||||
#endif
|
||||
|
||||
static void
|
||||
|
@ -469,6 +469,7 @@ default_ssh_port(void)
|
||||
static int
|
||||
execute_in_shell(const char *cmd)
|
||||
{
|
||||
char *shell;
|
||||
#ifdef WINDOWS
|
||||
fatal("LocalCommand execution is not supported on Windows yet");
|
||||
return 0;
|
||||
@ -1725,6 +1726,7 @@ read_config_file_depth(const char *filename, struct passwd *pw,
|
||||
fatal("Bad owner or permissions on %s", filename);
|
||||
}
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
debug("Reading configuration data %.200s", filename);
|
||||
|
||||
/*
|
||||
|
19
readpass.c
19
readpass.c
@ -145,6 +145,8 @@ read_passphrase(const char *prompt, int flags)
|
||||
|
||||
/* prompt user */
|
||||
wchar_t* wtmp = utf8_to_utf16(prompt);
|
||||
if (wtmp == NULL)
|
||||
fatal("unable to alloc memory");
|
||||
_cputws(wtmp);
|
||||
free(wtmp);
|
||||
|
||||
@ -158,28 +160,28 @@ read_passphrase(const char *prompt, int flags)
|
||||
buf[len] = (unsigned char)_getch();
|
||||
|
||||
if (buf[len] == '\r') {
|
||||
if (_kbhit())
|
||||
_getch(); // read linefeed if its there
|
||||
if (_kbhit()) /* read linefeed if its there */
|
||||
_getch();
|
||||
break;
|
||||
}
|
||||
else if (buf[len] == '\n') {
|
||||
break;
|
||||
}
|
||||
else if (buf[len] == '\b') { // backspace
|
||||
else if (buf[len] == '\b') { /* backspace */
|
||||
if (len > 0)
|
||||
len--; // overwrite last character
|
||||
len--; /* overwrite last character */
|
||||
}
|
||||
else if (buf[len] == '\003') {
|
||||
/* exit on Ctrl+C */
|
||||
fatal("");
|
||||
}
|
||||
else {
|
||||
len++; // keep reading in the loop
|
||||
len++; /* keep reading in the loop */
|
||||
}
|
||||
}
|
||||
|
||||
buf[len] = '\0'; // get rid of the cr/lf
|
||||
_cputs("\n"); // show a newline as we do not echo password or the line
|
||||
buf[len] = '\0'; /* get rid of the cr/lf */
|
||||
_cputs("\n"); /*show a newline as we do not echo password or the line */
|
||||
|
||||
ret = xstrdup(buf);
|
||||
|
||||
@ -188,7 +190,6 @@ read_passphrase(const char *prompt, int flags)
|
||||
return ret;
|
||||
|
||||
#else /* !WINDOWS */
|
||||
|
||||
char *askpass = NULL, *ret, buf[1024];
|
||||
int rppflags, use_askpass = 0, ttyfd;
|
||||
|
||||
@ -235,9 +236,7 @@ read_passphrase(const char *prompt, int flags)
|
||||
ret = xstrdup(buf);
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
return ret;
|
||||
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.93 2016/11/01 13:43:27 tb Exp $
|
||||
# $OpenBSD: Makefile,v 1.94 2016/12/16 03:51:19 dtucker Exp $
|
||||
|
||||
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
|
||||
tests: prep $(REGRESS_TARGETS)
|
||||
@ -78,7 +78,8 @@ LTESTS= connect \
|
||||
hostkey-rotate \
|
||||
principals-command \
|
||||
cert-file \
|
||||
cfginclude
|
||||
cfginclude \
|
||||
allow-deny-users
|
||||
|
||||
|
||||
# dhgex \
|
||||
|
40
regress/allow-deny-users.sh
Normal file
40
regress/allow-deny-users.sh
Normal file
@ -0,0 +1,40 @@
|
||||
# Public Domain
|
||||
# Zev Weiss, 2016
|
||||
|
||||
tid="AllowUsers/DenyUsers"
|
||||
|
||||
me="$LOGNAME"
|
||||
if [ "x$me" = "x" ]; then
|
||||
me=`whoami`
|
||||
fi
|
||||
other="nobody"
|
||||
|
||||
test_auth()
|
||||
{
|
||||
deny="$1"
|
||||
allow="$2"
|
||||
should_succeed="$3"
|
||||
failmsg="$4"
|
||||
|
||||
start_sshd -oDenyUsers="$deny" -oAllowUsers="$allow"
|
||||
|
||||
${SSH} -F $OBJ/ssh_config "$me@somehost" true
|
||||
status=$?
|
||||
|
||||
if (test $status -eq 0 && ! $should_succeed) \
|
||||
|| (test $status -ne 0 && $should_succeed); then
|
||||
fail "$failmsg"
|
||||
fi
|
||||
|
||||
stop_sshd
|
||||
}
|
||||
|
||||
# DenyUsers AllowUsers should_succeed failure_message
|
||||
test_auth "" "" true "user in neither DenyUsers nor AllowUsers denied"
|
||||
test_auth "$other $me" "" false "user in DenyUsers allowed"
|
||||
test_auth "$me $other" "" false "user in DenyUsers allowed"
|
||||
test_auth "" "$other" false "user not in AllowUsers allowed"
|
||||
test_auth "" "$other $me" true "user in AllowUsers denied"
|
||||
test_auth "" "$me $other" true "user in AllowUsers denied"
|
||||
test_auth "$me $other" "$me $other" false "user in both DenyUsers and AllowUsers allowed"
|
||||
test_auth "$other $me" "$other $me" false "user in both DenyUsers and AllowUsers allowed"
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: cert-file.sh,v 1.2 2015/09/24 07:15:39 djm Exp $
|
||||
# $OpenBSD: cert-file.sh,v 1.4 2016/12/16 02:48:55 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="ssh with certificates"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: login-timeout.sh,v 1.7 2014/03/13 20:44:49 djm Exp $
|
||||
# $OpenBSD: login-timeout.sh,v 1.8 2016/12/16 01:06:27 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="connect after login grace timeout"
|
||||
@ -17,7 +17,7 @@ if [ $? -ne 0 ]; then
|
||||
fail "ssh connect after login grace timeout failed with privsep"
|
||||
fi
|
||||
|
||||
$SUDO kill `$SUDO cat $PIDFILE`
|
||||
stop_sshd
|
||||
|
||||
trace "test login grace without privsep"
|
||||
echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
|
||||
|
@ -26,13 +26,12 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
$client.SetupClient($server)
|
||||
$server.SetupServer($client)
|
||||
|
||||
$testData = @(
|
||||
<# known issue 340
|
||||
$testData = @(
|
||||
@{
|
||||
Title = 'Simple copy local file to local file'
|
||||
Source = $SourceFilePath
|
||||
Destination = $DestinationFilePath
|
||||
},#>
|
||||
},
|
||||
@{
|
||||
Title = 'Simple copy local file to remote file'
|
||||
Source = $SourceFilePath
|
||||
@ -42,13 +41,12 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
Title = 'Simple copy remote file to local file'
|
||||
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
|
||||
Destination = $DestinationFilePath
|
||||
},
|
||||
<# known issue 340
|
||||
},
|
||||
@{
|
||||
Title = 'Simple copy local file to local dir'
|
||||
Source = $SourceFilePath
|
||||
Destination = $DestinationDir
|
||||
},#>
|
||||
},
|
||||
@{
|
||||
Title = 'simple copy local file to remote dir'
|
||||
Source = $SourceFilePath
|
||||
@ -66,7 +64,7 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
Title = 'copy from local dir to remote dir'
|
||||
Source = $sourceDir
|
||||
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir"
|
||||
},
|
||||
},
|
||||
@{
|
||||
Title = 'copy from local dir to local dir'
|
||||
Source = $sourceDir
|
||||
@ -84,16 +82,16 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
$client.CleanupClient()
|
||||
$server.CleanupServer()
|
||||
|
||||
Get-Item $SourceDir | Remove-Item -Recurse -Force -ea silentlycontinue
|
||||
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ea silentlycontinue
|
||||
Get-Item $SourceDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
BeforeAll {
|
||||
$null = New-Item $DestinationDir -ItemType directory -Force
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
Get-ChildItem $DestinationDir -Recurse -Directory | Remove-Item -Recurse -Force -ea silentlycontinue
|
||||
Get-ChildItem $DestinationDir -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
<#Context "SCP usage" {
|
||||
@ -121,7 +119,7 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
$equal | Should Be $true
|
||||
}
|
||||
|
||||
<#It 'Directory recursive Copy with -i option: <Title> ' -TestCases:$testData1 {
|
||||
It 'Directory recursive Copy with -i option: <Title> ' -TestCases:$testData1 {
|
||||
param([string]$Title, $Source, $Destination)
|
||||
|
||||
.\scp -r -i $identifyFile $Source $Destination
|
||||
@ -129,10 +127,10 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
|
||||
#known issue 364
|
||||
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
#$equal | Should Be $true
|
||||
}#>
|
||||
|
||||
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
#this context only run on windows
|
||||
@ -149,37 +147,34 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
|
||||
#cleanup single signon
|
||||
.\ssh-add.exe -D
|
||||
}
|
||||
}
|
||||
|
||||
It 'File Copy with -S option (positive)' {
|
||||
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
|
||||
#validate file content. DestPath is the path to the file.
|
||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 #todo: add LastWriteTime in comparison when issue is fixed
|
||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
}
|
||||
|
||||
<#It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData {
|
||||
It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData {
|
||||
param([string]$Title, $Source, $Destination)
|
||||
|
||||
.\scp -p -c aes128-ctr -C $Source $Destination #Todo: add -v after it is supported.
|
||||
.\scp -p -c aes128-ctr -v -C $Source $Destination
|
||||
#validate file content. DestPath is the path to the file.
|
||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 #todo: add LastWriteTime in comparison when issue is fixed
|
||||
$equal | Should Be $true
|
||||
}#>
|
||||
|
||||
<# known issue 369
|
||||
It 'Directory recursive Copy with -v option: <Title> ' -TestCases:$testData1 {
|
||||
param([string]$Title, $Source, $Destination)
|
||||
|
||||
.\scp -r -p $Source $Destination
|
||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
}
|
||||
|
||||
It 'Directory recursive Copy with -r -p -v option: <Title> ' -TestCases:$testData1 {
|
||||
param([string]$Title, $Source, $Destination)
|
||||
.\scp -r -p -c aes128-ctr -v $Source $Destination
|
||||
|
||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime).Length -eq 0
|
||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
|
||||
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
|
||||
#known issue 364
|
||||
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime).Length -eq 0
|
||||
#$equal | Should Be $true
|
||||
}#>
|
||||
}
|
||||
}
|
||||
|
||||
Context "Key based authentication with -i -C -q options. host keys are not secured on server" {
|
||||
@ -192,23 +187,20 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
|
||||
.\scp -i $identifyFile -C -q $Source $Destination
|
||||
#validate file content. DestPath is the path to the file.
|
||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 # need to validate LastWriteTime after issue 356 is fixed.
|
||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
}
|
||||
|
||||
|
||||
<#It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
|
||||
It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
|
||||
param([string]$Title, $Source, $Destination)
|
||||
|
||||
.\scp -i $identifyFile -r -q $Source $Destination
|
||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
|
||||
#known issue 364
|
||||
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
#$equal | Should Be $true
|
||||
}#>
|
||||
}
|
||||
|
||||
|
||||
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||
$equal | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: reexec.sh,v 1.8 2015/03/03 22:35:19 markus Exp $
|
||||
# $OpenBSD: reexec.sh,v 1.10 2016/12/16 01:06:27 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="reexec tests"
|
||||
@ -39,8 +39,7 @@ echo "InvalidXXX=no" >> $OBJ/sshd_config
|
||||
|
||||
copy_tests
|
||||
|
||||
$SUDO kill `$SUDO cat $PIDFILE`
|
||||
rm -f $PIDFILE
|
||||
stop_sshd
|
||||
|
||||
cp $OBJ/sshd_config.orig $OBJ/sshd_config
|
||||
|
||||
@ -54,8 +53,7 @@ rm -f $SSHD_COPY
|
||||
|
||||
copy_tests
|
||||
|
||||
$SUDO kill `$SUDO cat $PIDFILE`
|
||||
rm -f $PIDFILE
|
||||
stop_sshd
|
||||
|
||||
verbose "test reexec fallback without privsep"
|
||||
|
||||
@ -67,7 +65,6 @@ rm -f $SSHD_COPY
|
||||
|
||||
copy_tests
|
||||
|
||||
$SUDO kill `$SUDO cat $PIDFILE`
|
||||
rm -f $PIDFILE
|
||||
stop_sshd
|
||||
|
||||
fi
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: test-exec.sh,v 1.57 2016/11/25 03:02:01 dtucker Exp $
|
||||
# $OpenBSD: test-exec.sh,v 1.58 2016/12/16 01:06:27 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
#SUDO=sudo
|
||||
@ -293,16 +293,8 @@ md5 () {
|
||||
}
|
||||
# End of portable specific functions
|
||||
|
||||
# helper
|
||||
cleanup ()
|
||||
stop_sshd ()
|
||||
{
|
||||
if [ "x$SSH_PID" != "x" ]; then
|
||||
if [ $SSH_PID -lt 2 ]; then
|
||||
echo bad pid for ssh: $SSH_PID
|
||||
else
|
||||
kill $SSH_PID
|
||||
fi
|
||||
fi
|
||||
if [ -f $PIDFILE ]; then
|
||||
pid=`$SUDO cat $PIDFILE`
|
||||
if [ "X$pid" = "X" ]; then
|
||||
@ -325,6 +317,19 @@ cleanup ()
|
||||
fi
|
||||
}
|
||||
|
||||
# helper
|
||||
cleanup ()
|
||||
{
|
||||
if [ "x$SSH_PID" != "x" ]; then
|
||||
if [ $SSH_PID -lt 2 ]; then
|
||||
echo bad pid for ssh: $SSH_PID
|
||||
else
|
||||
kill $SSH_PID
|
||||
fi
|
||||
fi
|
||||
stop_sshd
|
||||
}
|
||||
|
||||
start_debug_log ()
|
||||
{
|
||||
echo "trace: $@" >$TEST_REGRESS_LOGFILE
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tests.c,v 1.2 2016/05/30 12:05:56 schwarze Exp $ */
|
||||
/* $OpenBSD: tests.c,v 1.3 2016/12/19 04:55:18 djm Exp $ */
|
||||
/*
|
||||
* Regress test for the utf8.h *mprintf() API
|
||||
*
|
||||
@ -69,7 +69,6 @@ tests(void)
|
||||
TEST_DONE();
|
||||
|
||||
badarg();
|
||||
one("null", NULL, 8, 6, 6, "(null)");
|
||||
one("empty", "", 2, 0, 0, "");
|
||||
one("ascii", "x", -2, -2, -2, "x");
|
||||
one("newline", "a\nb", -2, -2, -2, "a\nb");
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "sandbox.h"
|
||||
#include "monitor.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* Darwin/OS X sandbox */
|
||||
|
120
scp.c
120
scp.c
@ -214,7 +214,7 @@ do_local_cmd(arglist *a)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
if ((pid = fork()) == -1)
|
||||
fatal("do_local_cmd: fork: %s", strerror(errno));
|
||||
|
||||
@ -239,7 +239,7 @@ do_local_cmd(arglist *a)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -282,6 +282,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
||||
|
||||
/* Fork a child to execute the command on the remote host using ssh. */
|
||||
#ifdef WINDOWS
|
||||
/* generate command line and spawn_child */
|
||||
replacearg(&args, 0, "%s", ssh_program);
|
||||
if (remuser != NULL) {
|
||||
addargs(&args, "-l");
|
||||
@ -314,11 +315,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
||||
do_cmd_pid = spawn_child(full_cmd, pin[0], pout[1], STDERR_FILENO, 0);
|
||||
free(full_cmd);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
do_cmd_pid = fork();
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
if (do_cmd_pid == 0) {
|
||||
/* Child. */
|
||||
close(pin[1]);
|
||||
@ -373,6 +372,7 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
|
||||
|
||||
/* Fork a child to execute the command on the remote host using ssh. */
|
||||
#ifdef WINDOWS
|
||||
/* generate command line and spawn_child */
|
||||
replacearg(&args, 0, "%s", ssh_program);
|
||||
if (remuser != NULL) {
|
||||
addargs(&args, "-l");
|
||||
@ -403,10 +403,10 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
|
||||
|
||||
pid = spawn_child(full_cmd, fdin, fdout, STDERR_FILENO, 0);
|
||||
free(full_cmd);
|
||||
}
|
||||
#else
|
||||
}
|
||||
#else /* !WINDOWS */
|
||||
pid = fork();
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
if (pid == 0) {
|
||||
dup2(fdin, 0);
|
||||
dup2(fdout, 1);
|
||||
@ -592,6 +592,18 @@ main(int argc, char **argv)
|
||||
remin = STDIN_FILENO;
|
||||
remout = STDOUT_FILENO;
|
||||
|
||||
#ifdef WINDOWS
|
||||
/*
|
||||
* To support both Windows and Unix style paths
|
||||
* convert '\\' to '/' in rest of arguments
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; i++)
|
||||
convertToForwardslash(argv[i]);
|
||||
}
|
||||
#endif /* WINDOWS */
|
||||
|
||||
if (fflag) {
|
||||
/* Follow "protocol", send data. */
|
||||
(void) response();
|
||||
@ -807,6 +819,41 @@ tolocal(int argc, char **argv)
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
if (!(src = colon(argv[i]))) { /* Local to local. */
|
||||
freeargs(&alist);
|
||||
#ifdef WINDOWS
|
||||
#define _PATH_XCOPY "xcopy"
|
||||
#define _PATH_COPY "copy"
|
||||
/* local to local on windows - need to use local native copy command */
|
||||
struct stat stb;
|
||||
int exists;
|
||||
char *last;
|
||||
|
||||
exists = stat(argv[i], &stb) == 0;
|
||||
/* convert '/' to '\\' */
|
||||
convertToBackslash(argv[i]);
|
||||
convertToBackslash(argv[argc - 1]);
|
||||
if (exists && (S_ISDIR(stb.st_mode))) {
|
||||
addargs(&alist, "%s", _PATH_XCOPY);
|
||||
if (iamrecursive)
|
||||
addargs(&alist, "/S /E /H");
|
||||
if (pflag)
|
||||
addargs(&alist, "/K /X");
|
||||
addargs(&alist, "/Y /F /I");
|
||||
addargs(&alist, "%s", argv[i]);
|
||||
|
||||
if ((last = strrchr(argv[i], '\\')) == NULL)
|
||||
last = argv[i];
|
||||
else
|
||||
++last;
|
||||
|
||||
addargs(&alist, "%s%s%s", argv[argc - 1],
|
||||
strcmp(argv[argc - 1], "\\") ? "\\" : "", last);
|
||||
} else {
|
||||
addargs(&alist, "%s", _PATH_COPY);
|
||||
addargs(&alist, "/Y");
|
||||
addargs(&alist, "%s", argv[i]);
|
||||
addargs(&alist, "%s", argv[argc - 1]);
|
||||
}
|
||||
#else /* !WINDOWS */
|
||||
addargs(&alist, "%s", _PATH_CP);
|
||||
if (iamrecursive)
|
||||
addargs(&alist, "-r");
|
||||
@ -815,6 +862,7 @@ tolocal(int argc, char **argv)
|
||||
addargs(&alist, "--");
|
||||
addargs(&alist, "%s", argv[i]);
|
||||
addargs(&alist, "%s", argv[argc-1]);
|
||||
#endif /* !WINDOWS */
|
||||
if (do_local_cmd(&alist))
|
||||
++errs;
|
||||
continue;
|
||||
@ -892,26 +940,10 @@ syserr: run_err("%s: %s", name, strerror(errno));
|
||||
run_err("%s: not a regular file", name);
|
||||
goto next;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
/* account for both slashes on Windows */
|
||||
{
|
||||
char *lastf = NULL, *lastr = NULL;
|
||||
if ((lastf = strrchr(name, '/')) == NULL && (lastr = strrchr(name, '\\')) == NULL)
|
||||
last = name;
|
||||
else {
|
||||
if (lastf)
|
||||
last = lastf;
|
||||
if (lastr)
|
||||
last = lastr;
|
||||
++last;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ((last = strrchr(name, '/')) == NULL)
|
||||
last = name;
|
||||
else
|
||||
++last;
|
||||
#endif
|
||||
curfile = last;
|
||||
if (pflag) {
|
||||
if (do_times(remout, verbose_mode, &stb) < 0)
|
||||
@ -1000,16 +1032,16 @@ rsource(char *name, struct stat *statp)
|
||||
(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
|
||||
/* 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
|
||||
#endif /* !WINDOWS */
|
||||
(void) atomicio(vwrite, remout, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
closedir(dirp);
|
||||
@ -1085,16 +1117,17 @@ sink(int argc, char **argv)
|
||||
*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
|
||||
/* 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
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
if (buf[0] == '\01' || buf[0] == '\02') {
|
||||
if (iamremote == 0) {
|
||||
(void) snmprintf(visbuf, sizeof(visbuf),
|
||||
@ -1496,3 +1529,4 @@ lostconn(int signo)
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -606,7 +606,7 @@ derelativise_path(const char *path)
|
||||
expanded = tilde_expand_filename(path, getuid());
|
||||
#ifdef WINDOWS
|
||||
/* Windows absolute paths have a drive letter followed by :*/
|
||||
if (expanded[1] == ':')
|
||||
if (*expanded != '\0' && expanded[1] == ':')
|
||||
#else /* !WINDOWS */
|
||||
if (*expanded == '/')
|
||||
#endif /* !WINDOWS */
|
||||
|
552
session.c
552
session.c
@ -183,8 +183,8 @@ static int
|
||||
auth_input_request_forwarding(struct passwd * pw)
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
packet_send_debug("Agent forwarding not supported yet in Windows");
|
||||
return 0;
|
||||
packet_send_debug("Agent forwarding not supported yet in Windows");
|
||||
return 0;
|
||||
#else /* !WINDOWS */
|
||||
Channel *nc;
|
||||
int sock = -1;
|
||||
@ -296,7 +296,7 @@ xauth_valid_string(const char *s)
|
||||
* do_exec* on Windows
|
||||
* - Read and set user environment variables from registry
|
||||
* - Build subsystem cmdline path
|
||||
* - Interative shell/commands are executed using ssh-shellhost.exe
|
||||
* - Interactive shell/commands are executed using ssh-shellhost.exe
|
||||
* - ssh-shellhost.exe implements server-side PTY for Windows
|
||||
*/
|
||||
#include <Shlobj.h>
|
||||
@ -312,360 +312,336 @@ xauth_valid_string(const char *s)
|
||||
|
||||
void setup_session_vars(Session* s)
|
||||
{
|
||||
wchar_t* pw_dir_w;
|
||||
wchar_t* tmp;
|
||||
char buf[128];
|
||||
char* laddr;
|
||||
wchar_t* pw_dir_w;
|
||||
wchar_t* tmp;
|
||||
char buf[128];
|
||||
char* laddr;
|
||||
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
|
||||
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
|
||||
fatal("%s: out of memory");
|
||||
|
||||
if ((tmp = utf8_to_utf16(s->pw->pw_name)) == NULL)
|
||||
fatal("%s, out of memory");
|
||||
SetEnvironmentVariableW(L"USERNAME", tmp);
|
||||
free(tmp);
|
||||
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
|
||||
fatal("%s: out of memory");
|
||||
|
||||
if (s->display)
|
||||
SetEnvironmentVariableA("DISPLAY", s->display);
|
||||
if ((tmp = utf8_to_utf16(s->pw->pw_name)) == NULL)
|
||||
fatal("%s, out of memory");
|
||||
SetEnvironmentVariableW(L"USERNAME", tmp);
|
||||
free(tmp);
|
||||
|
||||
if (s->display)
|
||||
SetEnvironmentVariableA("DISPLAY", s->display);
|
||||
|
||||
|
||||
SetEnvironmentVariableW(L"HOMEPATH", pw_dir_w);
|
||||
SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w);
|
||||
SetEnvironmentVariableW(L"HOMEPATH", pw_dir_w);
|
||||
SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w);
|
||||
|
||||
if (pw_dir_w[1] == L':') {
|
||||
wchar_t wc = pw_dir_w[2];
|
||||
pw_dir_w[2] = L'\0';
|
||||
SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w);
|
||||
pw_dir_w[2] = wc;
|
||||
}
|
||||
if (pw_dir_w[1] == L':') {
|
||||
wchar_t wc = pw_dir_w[2];
|
||||
pw_dir_w[2] = L'\0';
|
||||
SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w);
|
||||
pw_dir_w[2] = wc;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof buf, "%.50s %d %d",
|
||||
ssh->remote_ipaddr, ssh->remote_port, ssh->local_port);
|
||||
snprintf(buf, sizeof buf, "%.50s %d %d",
|
||||
ssh->remote_ipaddr, ssh->remote_port, ssh->local_port);
|
||||
|
||||
SetEnvironmentVariableA("SSH_CLIENT", buf);
|
||||
SetEnvironmentVariableA("SSH_CLIENT", buf);
|
||||
|
||||
laddr = get_local_ipaddr(packet_get_connection_in());
|
||||
laddr = get_local_ipaddr(packet_get_connection_in());
|
||||
|
||||
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
|
||||
ssh->remote_ipaddr, ssh->remote_port, laddr, ssh->local_port);
|
||||
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
|
||||
ssh->remote_ipaddr, ssh->remote_port, laddr, ssh->local_port);
|
||||
|
||||
free(laddr);
|
||||
free(laddr);
|
||||
|
||||
SetEnvironmentVariableA("SSH_CONNECTION", buf);
|
||||
SetEnvironmentVariableA("SSH_CONNECTION", buf);
|
||||
|
||||
if (original_command)
|
||||
SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command);
|
||||
if (original_command)
|
||||
SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command);
|
||||
|
||||
|
||||
if ((s->term) && (s->term[0]))
|
||||
SetEnvironmentVariable("TERM", s->term);
|
||||
if ((s->term) && (s->term[0]))
|
||||
SetEnvironmentVariable("TERM", s->term);
|
||||
|
||||
if (!s->is_subsystem) {
|
||||
snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME"));
|
||||
SetEnvironmentVariableA("PROMPT", buf);
|
||||
}
|
||||
if (!s->is_subsystem) {
|
||||
snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME"));
|
||||
SetEnvironmentVariableA("PROMPT", buf);
|
||||
}
|
||||
|
||||
/*set user environment variables*/
|
||||
{
|
||||
UCHAR InfoBuffer[1000];
|
||||
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
|
||||
DWORD dwInfoBufferSize, tmp_len;
|
||||
LPWSTR sid_str = NULL;
|
||||
wchar_t reg_path[MAX_PATH];
|
||||
HKEY reg_key = 0;
|
||||
HANDLE token = s->authctxt->methoddata;
|
||||
|
||||
tmp_len = MAX_PATH;
|
||||
if (GetTokenInformation(token, TokenUser, InfoBuffer,
|
||||
1000, &dwInfoBufferSize) == FALSE ||
|
||||
ConvertSidToStringSidW(pTokenUser->User.Sid, &sid_str) == FALSE ||
|
||||
swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_str) == MAX_PATH ||
|
||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_key) != 0 ||
|
||||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)pw_dir_w, &tmp_len) != 0) {
|
||||
/* one of the above failed */
|
||||
debug("cannot retirve profile path - perhaps user profile is not created yet");
|
||||
}
|
||||
/*set user environment variables*/
|
||||
{
|
||||
UCHAR InfoBuffer[1000];
|
||||
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
|
||||
DWORD dwInfoBufferSize, tmp_len;
|
||||
LPWSTR sid_str = NULL;
|
||||
wchar_t reg_path[MAX_PATH];
|
||||
HKEY reg_key = 0;
|
||||
HANDLE token = s->authctxt->methoddata;
|
||||
|
||||
tmp_len = MAX_PATH;
|
||||
if (GetTokenInformation(token, TokenUser, InfoBuffer,
|
||||
1000, &dwInfoBufferSize) == FALSE ||
|
||||
ConvertSidToStringSidW(pTokenUser->User.Sid, &sid_str) == FALSE ||
|
||||
swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_str) == MAX_PATH ||
|
||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_key) != 0 ||
|
||||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)pw_dir_w, &tmp_len) != 0) {
|
||||
/* one of the above failed */
|
||||
debug("cannot retirve profile path - perhaps user profile is not created yet");
|
||||
}
|
||||
|
||||
if (sid_str)
|
||||
LocalFree(sid_str);
|
||||
if (sid_str)
|
||||
LocalFree(sid_str);
|
||||
|
||||
if (reg_key)
|
||||
RegCloseKey(reg_key);
|
||||
|
||||
{ /* retrieve and set env variables. */
|
||||
/* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/
|
||||
if (reg_key)
|
||||
RegCloseKey(reg_key);
|
||||
|
||||
/* retrieve and set env variables. */
|
||||
{
|
||||
#define MAX_VALUE_LEN 1000
|
||||
#define MAX_DATA_LEN 2000
|
||||
#define MAX_EXPANDED_DATA_LEN 5000
|
||||
wchar_t *path;
|
||||
wchar_t value_name[MAX_VALUE_LEN];
|
||||
wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply;
|
||||
DWORD value_type, name_len, data_len;
|
||||
int i;
|
||||
LONG ret;
|
||||
/* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/
|
||||
wchar_t *path;
|
||||
wchar_t value_name[MAX_VALUE_LEN];
|
||||
wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply;
|
||||
DWORD value_type, name_len, data_len;
|
||||
int i;
|
||||
LONG ret;
|
||||
|
||||
if (ImpersonateLoggedOnUser(token) == FALSE)
|
||||
debug("Failed to impersonate user token, %d", GetLastError());
|
||||
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
|
||||
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
|
||||
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
|
||||
reg_key = 0;
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS) {
|
||||
i = 0;
|
||||
while (1) {
|
||||
name_len = MAX_VALUE_LEN * 2;
|
||||
data_len = MAX_DATA_LEN * 2;
|
||||
to_apply = NULL;
|
||||
if (RegEnumValueW(reg_key, i++, value_name, &name_len, 0, &value_type, (LPBYTE)&value_data, &data_len) != ERROR_SUCCESS)
|
||||
break;
|
||||
if (value_type == REG_SZ)
|
||||
to_apply = value_data;
|
||||
else if (value_type == REG_EXPAND_SZ) {
|
||||
ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
||||
to_apply = value_data_expanded;
|
||||
}
|
||||
if (ImpersonateLoggedOnUser(token) == FALSE)
|
||||
debug("Failed to impersonate user token, %d", GetLastError());
|
||||
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
|
||||
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
|
||||
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
|
||||
reg_key = 0;
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS) {
|
||||
i = 0;
|
||||
while (1) {
|
||||
name_len = MAX_VALUE_LEN * 2;
|
||||
data_len = MAX_DATA_LEN * 2;
|
||||
to_apply = NULL;
|
||||
if (RegEnumValueW(reg_key, i++, value_name, &name_len, 0, &value_type, (LPBYTE)&value_data, &data_len) != ERROR_SUCCESS)
|
||||
break;
|
||||
if (value_type == REG_SZ)
|
||||
to_apply = value_data;
|
||||
else if (value_type == REG_EXPAND_SZ) {
|
||||
ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
||||
to_apply = value_data_expanded;
|
||||
}
|
||||
|
||||
if (wcsicmp(value_name, L"PATH") == 0) {
|
||||
DWORD size;
|
||||
if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) {
|
||||
memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2);
|
||||
GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
||||
value_data_expanded[size - 1] = L';';
|
||||
to_apply = value_data_expanded;
|
||||
}
|
||||
if (wcsicmp(value_name, L"PATH") == 0) {
|
||||
DWORD size;
|
||||
if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) {
|
||||
memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2);
|
||||
GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
||||
value_data_expanded[size - 1] = L';';
|
||||
to_apply = value_data_expanded;
|
||||
}
|
||||
|
||||
}
|
||||
if (to_apply)
|
||||
SetEnvironmentVariableW(value_name, to_apply);
|
||||
}
|
||||
if (to_apply)
|
||||
SetEnvironmentVariableW(value_name, to_apply);
|
||||
}
|
||||
RegCloseKey(reg_key);
|
||||
}
|
||||
RevertToSelf();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
RegCloseKey(reg_key);
|
||||
}
|
||||
|
||||
|
||||
RevertToSelf();
|
||||
}
|
||||
}
|
||||
|
||||
free(pw_dir_w);
|
||||
free(pw_dir_w);
|
||||
}
|
||||
|
||||
int do_exec_windows(Session *s, const char *command, int pty) {
|
||||
int pipein[2], pipeout[2], pipeerr[2], r;
|
||||
char *exec_command = NULL, *progdir = w32_programdir();
|
||||
wchar_t *exec_command_w = NULL, *pw_dir_w;
|
||||
int pipein[2], pipeout[2], pipeerr[2], r;
|
||||
char *exec_command = NULL, *progdir = w32_programdir();
|
||||
wchar_t *exec_command_w = NULL, *pw_dir_w;
|
||||
|
||||
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR)
|
||||
{
|
||||
error("sub system not supported, exiting\n");
|
||||
fflush(NULL);
|
||||
exit(1);
|
||||
}
|
||||
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR) {
|
||||
error("sub system not supported, exiting\n");
|
||||
fflush(NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create three pipes for stdin, stdout and stderr */
|
||||
if (pipe(pipein) == -1 || pipe(pipeout) == -1 || pipe(pipeerr) == -1)
|
||||
fatal("%s: cannot create pipe: %.100s", __func__, strerror(errno));
|
||||
|
||||
/* Create three pipes for stdin, stdout and stderr */
|
||||
if (pipe(pipein) == -1 || pipe(pipeout) == -1 || pipe(pipeerr) == -1)
|
||||
fatal("%s: cannot create pipe: %.100s", __func__, strerror(errno));
|
||||
|
||||
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
|
||||
fatal("%s: out of memory");
|
||||
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
|
||||
fatal("%s: out of memory");
|
||||
|
||||
|
||||
set_nonblock(pipein[0]);
|
||||
set_nonblock(pipein[1]);
|
||||
set_nonblock(pipeout[0]);
|
||||
set_nonblock(pipeout[1]);
|
||||
set_nonblock(pipeerr[0]);
|
||||
set_nonblock(pipeerr[1]);
|
||||
set_nonblock(pipein[0]);
|
||||
set_nonblock(pipein[1]);
|
||||
set_nonblock(pipeout[0]);
|
||||
set_nonblock(pipeout[1]);
|
||||
set_nonblock(pipeerr[0]);
|
||||
set_nonblock(pipeerr[1]);
|
||||
|
||||
fcntl(pipein[1], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(pipeout[0], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(pipein[1], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(pipeout[0], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* prepare exec - path used with CreateProcess() */
|
||||
if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) {
|
||||
/* relative or absolute */
|
||||
if (command == NULL || command[0] == '\0')
|
||||
fatal("expecting command for a subsystem");
|
||||
/* prepare exec - path used with CreateProcess() */
|
||||
if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) {
|
||||
/* relative or absolute */
|
||||
if (command == NULL || command[0] == '\0')
|
||||
fatal("expecting command for a subsystem");
|
||||
|
||||
if (command[1] == ':') /* absolute */
|
||||
exec_command = xstrdup(command);
|
||||
else {/*relative*/
|
||||
exec_command = malloc(strlen(progdir) + 1 + strlen(command));
|
||||
if (exec_command == NULL)
|
||||
fatal("%s, out of memory");
|
||||
memcpy(exec_command, progdir, strlen(progdir));
|
||||
exec_command[strlen(progdir)] = '\\';
|
||||
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
|
||||
}
|
||||
} else {
|
||||
char *shell_host = pty ? "ssh-shellhost.exe " : "ssh-shellhost.exe -nopty ", *c;
|
||||
exec_command = malloc(strlen(progdir) + 1 + strlen(shell_host) + (command ? strlen(command) : 0) + 1);
|
||||
if (exec_command == NULL)
|
||||
fatal("%s, out of memory");
|
||||
c = exec_command;
|
||||
memcpy(c, progdir, strlen(progdir));
|
||||
c += strlen(progdir);
|
||||
*c++ = '\\';
|
||||
memcpy(c, shell_host, strlen(shell_host));
|
||||
c += strlen(shell_host);
|
||||
if (command) {
|
||||
memcpy(c, command, strlen(command));
|
||||
c += strlen(command);
|
||||
}
|
||||
*c = '\0';
|
||||
}
|
||||
if (command[1] == ':') /* absolute */
|
||||
exec_command = xstrdup(command);
|
||||
else {/*relative*/
|
||||
exec_command = malloc(strlen(progdir) + 1 + strlen(command));
|
||||
if (exec_command == NULL)
|
||||
fatal("%s, out of memory");
|
||||
memcpy(exec_command, progdir, strlen(progdir));
|
||||
exec_command[strlen(progdir)] = '\\';
|
||||
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
|
||||
}
|
||||
} else {
|
||||
char *shell_host = pty ? "ssh-shellhost.exe " : "ssh-shellhost.exe -nopty ", *c;
|
||||
exec_command = malloc(strlen(progdir) + 1 + strlen(shell_host) + (command ? strlen(command) : 0) + 1);
|
||||
if (exec_command == NULL)
|
||||
fatal("%s, out of memory");
|
||||
c = exec_command;
|
||||
memcpy(c, progdir, strlen(progdir));
|
||||
c += strlen(progdir);
|
||||
*c++ = '\\';
|
||||
memcpy(c, shell_host, strlen(shell_host));
|
||||
c += strlen(shell_host);
|
||||
if (command) {
|
||||
memcpy(c, command, strlen(command));
|
||||
c += strlen(command);
|
||||
}
|
||||
*c = '\0';
|
||||
}
|
||||
|
||||
/* setup Environment varibles */
|
||||
setup_session_vars(s);
|
||||
|
||||
extern int debug_flag;
|
||||
/* setup Environment varibles */
|
||||
setup_session_vars(s);
|
||||
extern int debug_flag;
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
{
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
|
||||
BOOL b;
|
||||
BOOL b;
|
||||
|
||||
HANDLE hToken = INVALID_HANDLE_VALUE;
|
||||
HANDLE hToken = INVALID_HANDLE_VALUE;
|
||||
|
||||
|
||||
/*
|
||||
* Assign sockets to StartupInfo
|
||||
*/
|
||||
/*
|
||||
* Assign sockets to StartupInfo
|
||||
*/
|
||||
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.lpReserved = 0;
|
||||
si.lpTitle = NULL; /* NULL means use exe name as title */
|
||||
si.dwX = 0;
|
||||
si.dwY = 0;
|
||||
si.dwXSize = 5;
|
||||
si.dwYSize = 5;
|
||||
si.dwXCountChars = s->col;
|
||||
si.dwYCountChars = s->row;
|
||||
si.dwFillAttribute = 0;
|
||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
|
||||
si.wShowWindow = 0; // FALSE ;
|
||||
si.cbReserved2 = 0;
|
||||
si.lpReserved2 = 0;
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.lpReserved = 0;
|
||||
si.lpTitle = NULL; /* NULL means use exe name as title */
|
||||
si.dwX = 0;
|
||||
si.dwY = 0;
|
||||
si.dwXSize = 5;
|
||||
si.dwYSize = 5;
|
||||
si.dwXCountChars = s->col;
|
||||
si.dwYCountChars = s->row;
|
||||
si.dwFillAttribute = 0;
|
||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
|
||||
si.wShowWindow = 0; // FALSE ;
|
||||
si.cbReserved2 = 0;
|
||||
si.lpReserved2 = 0;
|
||||
|
||||
si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]);
|
||||
si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]);
|
||||
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
|
||||
si.lpDesktop = NULL;
|
||||
si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]);
|
||||
si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]);
|
||||
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
|
||||
si.lpDesktop = NULL;
|
||||
|
||||
hToken = s->authctxt->methoddata;
|
||||
hToken = s->authctxt->methoddata;
|
||||
|
||||
debug("Executing command: %s", exec_command);
|
||||
debug("Executing command: %s", exec_command);
|
||||
|
||||
/* Create the child process */
|
||||
/* Create the child process */
|
||||
|
||||
exec_command_w = utf8_to_utf16(exec_command);
|
||||
exec_command_w = utf8_to_utf16(exec_command);
|
||||
|
||||
if (debug_flag)
|
||||
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
DETACHED_PROCESS, NULL, pw_dir_w,
|
||||
&si, &pi);
|
||||
else
|
||||
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
DETACHED_PROCESS , NULL, pw_dir_w,
|
||||
&si, &pi);
|
||||
if (debug_flag)
|
||||
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
DETACHED_PROCESS, NULL, pw_dir_w,
|
||||
&si, &pi);
|
||||
else
|
||||
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
DETACHED_PROCESS , NULL, pw_dir_w,
|
||||
&si, &pi);
|
||||
|
||||
if (!b)
|
||||
{
|
||||
debug("ERROR. Cannot create process (%u).\n", GetLastError());
|
||||
free(pw_dir_w);
|
||||
free(exec_command_w);
|
||||
CloseHandle(hToken);
|
||||
if (!b)
|
||||
{
|
||||
debug("ERROR. Cannot create process (%u).\n", GetLastError());
|
||||
free(pw_dir_w);
|
||||
free(exec_command_w);
|
||||
CloseHandle(hToken);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
else if (pty) { /*attach to shell console */
|
||||
FreeConsole();
|
||||
if (!debug_flag)
|
||||
ImpersonateLoggedOnUser(hToken);
|
||||
Sleep(20);
|
||||
while (AttachConsole(pi.dwProcessId) == FALSE) {
|
||||
DWORD exit_code;
|
||||
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
|
||||
break;
|
||||
Sleep(100);
|
||||
}
|
||||
if (!debug_flag)
|
||||
RevertToSelf();
|
||||
{
|
||||
/* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the
|
||||
* attached console agein */
|
||||
exit(1);
|
||||
}
|
||||
else if (pty) { /*attach to shell console */
|
||||
FreeConsole();
|
||||
if (!debug_flag)
|
||||
ImpersonateLoggedOnUser(hToken);
|
||||
Sleep(20);
|
||||
while (AttachConsole(pi.dwProcessId) == FALSE) {
|
||||
DWORD exit_code;
|
||||
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
|
||||
break;
|
||||
Sleep(100);
|
||||
}
|
||||
if (!debug_flag)
|
||||
RevertToSelf();
|
||||
{
|
||||
/* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the
|
||||
* attached console agein */
|
||||
|
||||
COORD coord;
|
||||
coord.X = s->col;
|
||||
coord.Y = 9999;;
|
||||
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||
}
|
||||
}
|
||||
COORD coord;
|
||||
coord.X = s->col;
|
||||
coord.Y = 9999;;
|
||||
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||
}
|
||||
}
|
||||
|
||||
s->pid = pi.dwProcessId;
|
||||
sw_add_child(pi.hProcess, pi.dwProcessId);
|
||||
CloseHandle(pi.hThread);
|
||||
s->pid = pi.dwProcessId;
|
||||
sw_add_child(pi.hProcess, pi.dwProcessId);
|
||||
}
|
||||
/*
|
||||
* Set interactive/non-interactive mode.
|
||||
*/
|
||||
packet_set_interactive(s->display != NULL, options.ip_qos_interactive,
|
||||
options.ip_qos_bulk);
|
||||
|
||||
/*
|
||||
* Set interactive/non-interactive mode.
|
||||
*/
|
||||
/* Close the child sides of the socket pairs. */
|
||||
close(pipein[0]);
|
||||
close(pipeout[1]);
|
||||
close(pipeerr[1]);
|
||||
|
||||
packet_set_interactive(s->display != NULL, options.ip_qos_interactive,
|
||||
options.ip_qos_bulk);
|
||||
/*
|
||||
* Enter the interactive session. Note: server_loop must be able to
|
||||
* handle the case that fdin and fdout are the same.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We are the parent. Close the child sides of the socket pairs.
|
||||
*/
|
||||
|
||||
close(pipein[0]);
|
||||
close(pipeout[1]);
|
||||
close(pipeerr[1]);
|
||||
|
||||
|
||||
/*
|
||||
* Close child thread handles as we do not need it. Process handle we keep so that we can know if it has died o not
|
||||
*/
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
// CloseHandle(pi.hProcess);
|
||||
|
||||
/*
|
||||
* Clear loginmsg, since it's the child's responsibility to display
|
||||
* it to the user, otherwise multiple sessions may accumulate
|
||||
* multiple copies of the login messages.
|
||||
*/
|
||||
|
||||
buffer_clear(&loginmsg);
|
||||
|
||||
/*
|
||||
* Enter the interactive session. Note: server_loop must be able to
|
||||
* handle the case that fdin and fdout are the same.
|
||||
*/
|
||||
|
||||
if (s->ttyfd == -1)
|
||||
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 0);
|
||||
else
|
||||
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 1); // tty interactive session
|
||||
if (s->ttyfd == -1)
|
||||
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 0);
|
||||
else
|
||||
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 1); // tty interactive session
|
||||
|
||||
free(pw_dir_w);
|
||||
free(exec_command_w);
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
do_exec_no_pty(Session *s, const char *command) {
|
||||
return do_exec_windows(s, command, 0);
|
||||
return do_exec_windows(s, command, 0);
|
||||
}
|
||||
|
||||
int
|
||||
do_exec_pty(Session *s, const char *command) {
|
||||
return do_exec_windows(s, command, 1);
|
||||
return do_exec_windows(s, command, 1);
|
||||
}
|
||||
|
||||
#else /* !WINDOWS */
|
||||
|
@ -1384,11 +1384,9 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||
"server reordered requests", local_path);
|
||||
}
|
||||
debug("truncating at %llu", (unsigned long long)highwater);
|
||||
#ifndef WIN32_VS
|
||||
if (ftruncate(local_fd, highwater) == -1)
|
||||
error("ftruncate \"%s\": %s", local_path,
|
||||
strerror(errno));
|
||||
#endif
|
||||
}
|
||||
if (read_error) {
|
||||
error("Couldn't read from remote file \"%s\" : %s",
|
||||
@ -1428,7 +1426,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||
if (fsync(local_fd) == -1)
|
||||
error("Couldn't sync file \"%s\": %s",
|
||||
local_path, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
close(local_fd);
|
||||
sshbuf_free(msg);
|
||||
|
@ -222,7 +222,7 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
|
||||
|
||||
strmode(st->st_mode, mode);
|
||||
if (!remote) {
|
||||
user = user_from_uid(st->st_uid, 0);
|
||||
user = user_from_uid(st->st_uid, 0);
|
||||
} else {
|
||||
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
|
||||
user = ubuf;
|
||||
@ -233,7 +233,6 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
|
||||
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
|
||||
group = gbuf;
|
||||
}
|
||||
|
||||
if (ltime != NULL) {
|
||||
now = time(NULL);
|
||||
if (now - (365*24*60*60)/2 < st->st_mtime &&
|
||||
|
@ -1,533 +0,0 @@
|
||||
/* $OpenBSD: sftp-common.c,v 1.28 2015/01/20 23:14:00 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
*
|
||||
* 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 "includes.h"
|
||||
|
||||
|
||||
#include <sys/param.h> /* MAX */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssherr.h"
|
||||
#include "sshbuf.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "sftp.h"
|
||||
#include "sftp-common.h"
|
||||
|
||||
/* Clear contents of attributes structure */
|
||||
void
|
||||
attrib_clear(Attrib *a)
|
||||
{
|
||||
a->flags = 0;
|
||||
a->size = 0;
|
||||
a->uid = 0;
|
||||
a->gid = 0;
|
||||
a->perm = 0;
|
||||
a->atime = 0;
|
||||
a->mtime = 0;
|
||||
}
|
||||
|
||||
/* Convert from struct stat to filexfer attribs */
|
||||
void
|
||||
stat_to_attrib(const struct stat *st, Attrib *a)
|
||||
{
|
||||
attrib_clear(a);
|
||||
a->flags = 0;
|
||||
a->flags |= SSH2_FILEXFER_ATTR_SIZE;
|
||||
a->size = st->st_size;
|
||||
a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
|
||||
a->uid = st->st_uid;
|
||||
a->gid = st->st_gid;
|
||||
a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
|
||||
a->perm = st->st_mode;
|
||||
a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
|
||||
a->atime = st->st_atime;
|
||||
a->mtime = st->st_mtime;
|
||||
}
|
||||
|
||||
/* Convert from filexfer attribs to struct stat */
|
||||
void
|
||||
attrib_to_stat(const Attrib *a, struct stat *st)
|
||||
{
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
|
||||
st->st_size = a->size;
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
||||
st->st_uid = a->uid;
|
||||
st->st_gid = a->gid;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
|
||||
st->st_mode = a->perm;
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
|
||||
st->st_atime = a->atime;
|
||||
st->st_mtime = a->mtime;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode attributes in buffer */
|
||||
int
|
||||
decode_attrib(struct sshbuf *b, Attrib *a)
|
||||
{
|
||||
int r;
|
||||
|
||||
attrib_clear(a);
|
||||
if ((r = sshbuf_get_u32(b, &a->flags)) != 0)
|
||||
return r;
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
|
||||
if ((r = sshbuf_get_u64(b, &a->size)) != 0)
|
||||
return r;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
||||
if ((r = sshbuf_get_u32(b, &a->uid)) != 0 ||
|
||||
(r = sshbuf_get_u32(b, &a->gid)) != 0)
|
||||
return r;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
|
||||
if ((r = sshbuf_get_u32(b, &a->perm)) != 0)
|
||||
return r;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
|
||||
if ((r = sshbuf_get_u32(b, &a->atime)) != 0 ||
|
||||
(r = sshbuf_get_u32(b, &a->mtime)) != 0)
|
||||
return r;
|
||||
}
|
||||
/* vendor-specific extensions */
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) {
|
||||
char *type;
|
||||
u_char *data;
|
||||
size_t dlen;
|
||||
u_int i, count;
|
||||
|
||||
if ((r = sshbuf_get_u32(b, &count)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
for (i = 0; i < count; i++) {
|
||||
if ((r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
|
||||
(r = sshbuf_get_string(b, &data, &dlen)) != 0)
|
||||
return r;
|
||||
debug3("Got file attribute \"%.100s\" len %zu",
|
||||
type, dlen);
|
||||
free(type);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encode attributes to buffer */
|
||||
int
|
||||
encode_attrib(struct sshbuf *b, const Attrib *a)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = sshbuf_put_u32(b, a->flags)) != 0)
|
||||
return r;
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
|
||||
if ((r = sshbuf_put_u64(b, a->size)) != 0)
|
||||
return r;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
||||
if ((r = sshbuf_put_u32(b, a->uid)) != 0 ||
|
||||
(r = sshbuf_put_u32(b, a->gid)) != 0)
|
||||
return r;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
|
||||
if ((r = sshbuf_put_u32(b, a->perm)) != 0)
|
||||
return r;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
|
||||
if ((r = sshbuf_put_u32(b, a->atime)) != 0 ||
|
||||
(r = sshbuf_put_u32(b, a->mtime)) != 0)
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert from SSH2_FX_ status to text error message */
|
||||
const char *
|
||||
fx2txt(int status)
|
||||
{
|
||||
switch (status) {
|
||||
case SSH2_FX_OK:
|
||||
return("No error");
|
||||
case SSH2_FX_EOF:
|
||||
return("End of file");
|
||||
case SSH2_FX_NO_SUCH_FILE:
|
||||
return("No such file or directory");
|
||||
case SSH2_FX_PERMISSION_DENIED:
|
||||
return("Permission denied");
|
||||
case SSH2_FX_FAILURE:
|
||||
return("Failure");
|
||||
case SSH2_FX_BAD_MESSAGE:
|
||||
return("Bad message");
|
||||
case SSH2_FX_NO_CONNECTION:
|
||||
return("No connection");
|
||||
case SSH2_FX_CONNECTION_LOST:
|
||||
return("Connection lost");
|
||||
case SSH2_FX_OP_UNSUPPORTED:
|
||||
return("Operation unsupported");
|
||||
default:
|
||||
return("Unknown status");
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh
|
||||
*/
|
||||
char *
|
||||
ls_file(const char *name, const struct stat *st, int remote, int si_units)
|
||||
{
|
||||
int ulen, glen, sz = 0;
|
||||
struct tm *ltime = localtime(&st->st_mtime);
|
||||
char *user, *group;
|
||||
char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
|
||||
char sbuf[FMT_SCALED_STRSIZE];
|
||||
time_t now;
|
||||
|
||||
strmode(st->st_mode, mode);
|
||||
|
||||
if (!remote) {
|
||||
user = user_from_uid(st->st_uid, 0);
|
||||
} else {
|
||||
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
|
||||
user = ubuf;
|
||||
}
|
||||
if (!remote) {
|
||||
group = group_from_gid(st->st_gid, 0);
|
||||
} else {
|
||||
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
|
||||
group = gbuf;
|
||||
}
|
||||
|
||||
if (ltime != NULL) {
|
||||
now = time(NULL);
|
||||
if (now - (365*24*60*60)/2 < st->st_mtime &&
|
||||
now >= st->st_mtime)
|
||||
sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime);
|
||||
else
|
||||
sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime);
|
||||
}
|
||||
if (sz == 0)
|
||||
tbuf[0] = '\0';
|
||||
ulen = MAX(strlen(user), 8);
|
||||
glen = MAX(strlen(group), 8);
|
||||
if (si_units) {
|
||||
fmt_scaled((long long)st->st_size, sbuf);
|
||||
snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode,
|
||||
(u_int)st->st_nlink, ulen, user, glen, group,
|
||||
sbuf, tbuf, name);
|
||||
} else {
|
||||
snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
|
||||
(u_int)st->st_nlink, ulen, user, glen, group,
|
||||
(unsigned long long)st->st_size, tbuf, name);
|
||||
}
|
||||
return xstrdup(buf);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <windows.h>
|
||||
|
||||
void
|
||||
strmode(mode_t mode, char *p)
|
||||
{
|
||||
/* print type */
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFDIR: /* directory */
|
||||
*p++ = 'd';
|
||||
break;
|
||||
case S_IFCHR: /* character special */
|
||||
*p++ = 'c';
|
||||
break;
|
||||
//case S_IFBLK: /* block special */
|
||||
// *p++ = 'b';
|
||||
// break;
|
||||
case S_IFREG: /* regular */
|
||||
*p++ = '-';
|
||||
break;
|
||||
//case S_IFLNK: /* symbolic link */
|
||||
// *p++ = 'l';
|
||||
// break;
|
||||
#ifdef S_IFSOCK
|
||||
case S_IFSOCK: /* socket */
|
||||
*p++ = 's';
|
||||
break;
|
||||
#endif
|
||||
case _S_IFIFO: /* fifo */
|
||||
*p++ = 'p';
|
||||
break;
|
||||
default: /* unknown */
|
||||
*p++ = '?';
|
||||
break;
|
||||
}
|
||||
/* usr */
|
||||
if (mode & S_IRUSR)
|
||||
*p++ = 'r';
|
||||
else
|
||||
*p++ = '-';
|
||||
if (mode & S_IWUSR)
|
||||
*p++ = 'w';
|
||||
else
|
||||
*p++ = '-';
|
||||
switch (mode & (S_IXUSR)) {
|
||||
case 0:
|
||||
*p++ = '-';
|
||||
break;
|
||||
case S_IXUSR:
|
||||
*p++ = 'x';
|
||||
break;
|
||||
//case S_ISUID:
|
||||
// *p++ = 'S';
|
||||
// break;
|
||||
//case S_IXUSR | S_ISUID:
|
||||
// *p++ = 's';
|
||||
// break;
|
||||
}
|
||||
/* group */
|
||||
if (mode & S_IRGRP)
|
||||
*p++ = 'r';
|
||||
else
|
||||
*p++ = '-';
|
||||
if (mode & S_IWGRP)
|
||||
*p++ = 'w';
|
||||
else
|
||||
*p++ = '-';
|
||||
switch (mode & (S_IXGRP)) {
|
||||
case 0:
|
||||
*p++ = '-';
|
||||
break;
|
||||
case S_IXGRP:
|
||||
*p++ = 'x';
|
||||
break;
|
||||
//case S_ISGID:
|
||||
// *p++ = 'S';
|
||||
// break;
|
||||
//case S_IXGRP | S_ISGID:
|
||||
// *p++ = 's';
|
||||
// break;
|
||||
}
|
||||
/* other */
|
||||
if (mode & S_IROTH)
|
||||
*p++ = 'r';
|
||||
else
|
||||
*p++ = '-';
|
||||
if (mode & S_IWOTH)
|
||||
*p++ = 'w';
|
||||
else
|
||||
*p++ = '-';
|
||||
switch (mode & (S_IXOTH)) {
|
||||
case 0:
|
||||
*p++ = '-';
|
||||
break;
|
||||
case S_IXOTH:
|
||||
*p++ = 'x';
|
||||
break;
|
||||
}
|
||||
*p++ = ' '; /* will be a '+' if ACL's implemented */
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
#include <winioctl.h>
|
||||
// Maximum reparse buffer info size. The max user defined reparse
|
||||
// data is 16KB, plus there's a header.
|
||||
//
|
||||
#define MAX_REPARSE_SIZE 17000
|
||||
|
||||
#define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO
|
||||
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt ntifs
|
||||
#define IO_REPARSE_TAG_HSM (0xC0000004L) // winnt ntifs
|
||||
#define IO_REPARSE_TAG_SIS (0x80000007L) // winnt ntifs
|
||||
|
||||
|
||||
//
|
||||
// Undocumented FSCTL_SET_REPARSE_POINT structure definition
|
||||
//
|
||||
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
|
||||
typedef struct {
|
||||
DWORD ReparseTag;
|
||||
DWORD ReparseDataLength;
|
||||
WORD Reserved;
|
||||
WORD ReparseTargetLength;
|
||||
WORD ReparseTargetMaximumLength;
|
||||
WORD Reserved1;
|
||||
WCHAR ReparseTarget[1];
|
||||
} REPARSE_MOUNTPOINT_DATA_BUFFER, *PREPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||
|
||||
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
};
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
BOOL ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags)
|
||||
{
|
||||
HANDLE fileHandle;
|
||||
BYTE reparseBuffer[MAX_REPARSE_SIZE];
|
||||
PBYTE reparseData;
|
||||
PREPARSE_GUID_DATA_BUFFER reparseInfo = (PREPARSE_GUID_DATA_BUFFER)reparseBuffer;
|
||||
PREPARSE_DATA_BUFFER msReparseInfo = (PREPARSE_DATA_BUFFER)reparseBuffer;
|
||||
DWORD returnedLength;
|
||||
|
||||
if (Flags & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
fileHandle = CreateFileW(tLink, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
//
|
||||
// Open the file
|
||||
//
|
||||
fileHandle = CreateFileW(tLink, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
}
|
||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
swprintf_s(ret, *plen, L"%ls", tLink);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (GetFileAttributesW(tLink) & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
|
||||
if (DeviceIoControl(fileHandle, FSCTL_GET_REPARSE_POINT,
|
||||
NULL, 0, reparseInfo, sizeof(reparseBuffer),
|
||||
&returnedLength, NULL)) {
|
||||
|
||||
if (IsReparseTagMicrosoft(reparseInfo->ReparseTag)) {
|
||||
|
||||
switch (reparseInfo->ReparseTag) {
|
||||
case 0x80000000 | IO_REPARSE_TAG_SYMBOLIC_LINK:
|
||||
case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
if (*plen >= msReparseInfo->MountPointReparseBuffer.SubstituteNameLength)
|
||||
{
|
||||
reparseData = (PBYTE)&msReparseInfo->SymbolicLinkReparseBuffer.PathBuffer;
|
||||
WCHAR temp[1024];
|
||||
wcsncpy_s(temp, 1024,
|
||||
(PWCHAR)(reparseData + msReparseInfo->MountPointReparseBuffer.SubstituteNameOffset),
|
||||
(size_t)msReparseInfo->MountPointReparseBuffer.SubstituteNameLength);
|
||||
temp[msReparseInfo->MountPointReparseBuffer.SubstituteNameLength] = 0;
|
||||
swprintf_s(ret, *plen, L"%ls", &temp[4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf_s(ret, *plen, L"%ls", tLink);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
swprintf_s(ret, *plen, L"%ls", tLink);
|
||||
}
|
||||
|
||||
CloseHandle(fileHandle);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char * get_inside_path(char * opath, BOOL bResolve, BOOL bMustExist)
|
||||
{
|
||||
char * ipath;
|
||||
char * temp_name;
|
||||
wchar_t temp[1024];
|
||||
DWORD templen = 1024;
|
||||
WIN32_FILE_ATTRIBUTE_DATA FileInfo;
|
||||
|
||||
wchar_t* opath_w = utf8_to_utf16(opath);
|
||||
if (!GetFileAttributesExW(opath_w, GetFileExInfoStandard, &FileInfo) && bMustExist)
|
||||
{
|
||||
free(opath_w);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bResolve)
|
||||
{
|
||||
ResolveLink(opath_w, temp, &templen, FileInfo.dwFileAttributes);
|
||||
ipath = utf16_to_utf8(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipath = xstrdup(opath);
|
||||
}
|
||||
|
||||
free(opath_w);
|
||||
return ipath;
|
||||
}
|
||||
|
||||
// if file is symbolic link, copy its link into "link" .
|
||||
int readlink(const char *path, char *link, int linklen)
|
||||
{
|
||||
strcpy_s(link, linklen, path);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
>>>>>>> V_7_3w
|
@ -67,7 +67,6 @@ fudge_readdir(struct SFTP_OPENDIR *od)
|
||||
/* Solaris needs sizeof(dirent) + path length (see below) */
|
||||
static char buf[sizeof(struct dirent) + MAXPATHLEN];
|
||||
struct dirent *ret = (struct dirent *)buf;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
static int inum = 1;
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
|
@ -688,7 +688,6 @@ process_open(u_int32_t id)
|
||||
debug3("request %u: open flags %d", id, pflags);
|
||||
flags = flags_from_portable(pflags);
|
||||
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
|
||||
|
||||
logit("open \"%s\" flags %s mode 0%o",
|
||||
name, string_from_portable(pflags), mode);
|
||||
if (readonly &&
|
||||
@ -821,15 +820,13 @@ process_do_stat(u_int32_t id, int do_lstat)
|
||||
struct stat st;
|
||||
char *name;
|
||||
int r, status = SSH2_FX_FAILURE;
|
||||
|
||||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
r = do_lstat ? lstat(name, &st) : stat(name, &st);
|
||||
|
||||
debug3("request %u: %sstat", id, do_lstat ? "l" : "");
|
||||
verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
|
||||
|
||||
r = do_lstat ? lstat(name, &st) : stat(name, &st);
|
||||
if (r < 0) {
|
||||
status = errno_to_portable(errno);
|
||||
} else {
|
||||
@ -899,9 +896,8 @@ process_setstat(u_int32_t id)
|
||||
char *name;
|
||||
int r, status = SSH2_FX_OK;
|
||||
|
||||
// sshbuf_get_cstring() is called twice.. is this correct?
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
|
||||
(r = decode_attrib(iqueue, &a)) != 0)
|
||||
(r = decode_attrib(iqueue, &a)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
debug("request %u: setstat name \"%s\"", id, name);
|
||||
@ -936,7 +932,6 @@ process_setstat(u_int32_t id)
|
||||
if (r == -1)
|
||||
status = errno_to_portable(errno);
|
||||
}
|
||||
|
||||
send_status(id, status);
|
||||
free(name);
|
||||
}
|
||||
@ -962,7 +957,6 @@ process_fsetstat(u_int32_t id)
|
||||
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
|
||||
logit("set \"%s\" size %llu",
|
||||
name, (unsigned long long)a.size);
|
||||
|
||||
r = ftruncate(fd, a.size);
|
||||
if (r == -1)
|
||||
status = errno_to_portable(errno);
|
||||
@ -995,7 +989,6 @@ process_fsetstat(u_int32_t id)
|
||||
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
||||
logit("set \"%s\" owner %lu group %lu", name,
|
||||
(u_long)a.uid, (u_long)a.gid);
|
||||
|
||||
#ifdef HAVE_FCHOWN
|
||||
r = fchown(fd, a.uid, a.gid);
|
||||
#else
|
||||
@ -1018,11 +1011,9 @@ process_opendir(u_int32_t id)
|
||||
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
dirp = opendir(path);
|
||||
|
||||
debug3("request %u: opendir", id);
|
||||
logit("opendir \"%s\"", path);
|
||||
|
||||
dirp = opendir(path);
|
||||
if (dirp == NULL) {
|
||||
status = errno_to_portable(errno);
|
||||
} else {
|
||||
@ -1064,7 +1055,6 @@ process_readdir(u_int32_t id)
|
||||
int nstats = 10, count = 0, i;
|
||||
|
||||
stats = xcalloc(nstats, sizeof(Stat));
|
||||
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (count >= nstats) {
|
||||
nstats *= 2;
|
||||
@ -1078,7 +1068,7 @@ process_readdir(u_int32_t id)
|
||||
stat_to_attrib(&st, &(stats[count].attrib));
|
||||
stats[count].name = xstrdup(dp->d_name);
|
||||
stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
|
||||
count++;
|
||||
count++;
|
||||
/* send up to 100 entries in one message */
|
||||
/* XXX check packet size instead */
|
||||
if (count == 100)
|
||||
@ -1108,7 +1098,6 @@ process_remove(u_int32_t id)
|
||||
|
||||
debug3("request %u: remove", id);
|
||||
logit("remove name \"%s\"", name);
|
||||
|
||||
r = unlink(name);
|
||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||
send_status(id, status);
|
||||
@ -1130,8 +1119,6 @@ process_mkdir(u_int32_t id)
|
||||
a.perm & 07777 : 0777;
|
||||
debug3("request %u: mkdir", id);
|
||||
logit("mkdir name \"%s\" mode 0%o", name, mode);
|
||||
|
||||
|
||||
r = mkdir(name, mode);
|
||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||
send_status(id, status);
|
||||
@ -1149,7 +1136,6 @@ process_rmdir(u_int32_t id)
|
||||
|
||||
debug3("request %u: rmdir", id);
|
||||
logit("rmdir name \"%s\"", name);
|
||||
|
||||
r = rmdir(name);
|
||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||
send_status(id, status);
|
||||
@ -1170,7 +1156,6 @@ process_realpath(u_int32_t id)
|
||||
free(path);
|
||||
path = xstrdup(".");
|
||||
}
|
||||
|
||||
debug3("request %u: realpath", id);
|
||||
verbose("realpath \"%s\"", path);
|
||||
if (realpath(path, resolvedname) == NULL) {
|
||||
@ -1233,8 +1218,7 @@ process_rename(u_int32_t id)
|
||||
unlink(newpath);
|
||||
} else
|
||||
status = SSH2_FX_OK;
|
||||
}
|
||||
else if (stat(newpath, &sb) == -1) {
|
||||
} else if (stat(newpath, &sb) == -1) {
|
||||
if (rename(oldpath, newpath) == -1)
|
||||
status = errno_to_portable(errno);
|
||||
else
|
||||
@ -1257,7 +1241,6 @@ process_readlink(u_int32_t id)
|
||||
|
||||
debug3("request %u: readlink", id);
|
||||
verbose("readlink \"%s\"", path);
|
||||
|
||||
if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
|
||||
send_status(id, errno_to_portable(errno));
|
||||
else {
|
||||
@ -1275,7 +1258,7 @@ static void
|
||||
process_symlink(u_int32_t id)
|
||||
{
|
||||
char *oldpath, *newpath;
|
||||
int r, status= SSH2_FX_OP_UNSUPPORTED;
|
||||
int r, status;
|
||||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
|
||||
@ -1283,12 +1266,10 @@ process_symlink(u_int32_t id)
|
||||
|
||||
debug3("request %u: symlink", id);
|
||||
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
|
||||
|
||||
/* this will fail if 'newpath' exists */
|
||||
r = symlink(oldpath, newpath);
|
||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||
send_status(id, status);
|
||||
|
||||
free(oldpath);
|
||||
free(newpath);
|
||||
}
|
||||
@ -1317,7 +1298,6 @@ process_extended_statvfs(u_int32_t id)
|
||||
{
|
||||
char *path;
|
||||
struct statvfs st;
|
||||
|
||||
int r;
|
||||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
|
||||
@ -1346,19 +1326,17 @@ process_extended_fstatvfs(u_int32_t id)
|
||||
send_status(id, SSH2_FX_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (statvfs(handle_to_name(handle), &st) != 0)
|
||||
if (fstatvfs(fd, &st) != 0)
|
||||
send_status(id, errno_to_portable(errno));
|
||||
else
|
||||
send_statvfs(id, &st);
|
||||
if (fstatvfs(fd, &st) != 0)
|
||||
send_status(id, errno_to_portable(errno));
|
||||
else
|
||||
send_statvfs(id, &st);
|
||||
}
|
||||
|
||||
static void
|
||||
process_extended_hardlink(u_int32_t id)
|
||||
{
|
||||
char *oldpath, *newpath;
|
||||
int r, status = SSH2_FX_OP_UNSUPPORTED;
|
||||
int r, status;
|
||||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
|
||||
@ -1366,10 +1344,8 @@ process_extended_hardlink(u_int32_t id)
|
||||
|
||||
debug3("request %u: hardlink", id);
|
||||
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
|
||||
|
||||
r = link(oldpath, newpath);
|
||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||
|
||||
send_status(id, status);
|
||||
free(oldpath);
|
||||
free(newpath);
|
||||
@ -1429,11 +1405,10 @@ process(void)
|
||||
const u_char *cp;
|
||||
int i, r;
|
||||
u_int32_t id;
|
||||
|
||||
|
||||
buf_len = sshbuf_len(iqueue);
|
||||
if (buf_len < 5) {
|
||||
if (buf_len < 5)
|
||||
return; /* Incomplete message. */
|
||||
}
|
||||
cp = sshbuf_ptr(iqueue);
|
||||
msg_len = get_u32(cp);
|
||||
if (msg_len > SFTP_MAX_MSG_LENGTH) {
|
||||
@ -1441,9 +1416,8 @@ process(void)
|
||||
client_addr, pw->pw_name);
|
||||
sftp_server_cleanup_exit(11);
|
||||
}
|
||||
if (buf_len < msg_len + 4) {
|
||||
if (buf_len < msg_len + 4)
|
||||
return;
|
||||
}
|
||||
if ((r = sshbuf_consume(iqueue, 4)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
buf_len -= 4;
|
||||
@ -1529,8 +1503,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0;
|
||||
ssize_t len, olen, set_size;
|
||||
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
|
||||
|
||||
char *cp, *homedir = NULL, buf[4*4096];
|
||||
char *cp, *homedir = NULL, buf[4*4096];
|
||||
long mask;
|
||||
|
||||
extern char *optarg;
|
||||
@ -1608,7 +1581,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
sftp_server_usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log_init(__progname, log_level, log_facility, log_stderr);
|
||||
|
||||
/*
|
||||
@ -1732,6 +1705,4 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
fatal("%s: sshbuf_check_reserve: %s",
|
||||
__func__, ssh_err(r));
|
||||
}
|
||||
//#endif /* else WIN32 */
|
||||
}
|
||||
|
||||
|
246
sftp.c
246
sftp.c
@ -73,7 +73,6 @@ typedef void EditLine;
|
||||
|
||||
#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
|
||||
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
|
||||
#define MAX_COMMAND_LINE 2048
|
||||
|
||||
/* File to read commands from */
|
||||
FILE* infile;
|
||||
@ -295,6 +294,7 @@ help(void)
|
||||
|
||||
#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];
|
||||
@ -311,6 +311,8 @@ static void printf_utf8(char *fmt, ... ) {
|
||||
free(wtmp);
|
||||
}
|
||||
|
||||
/* override mprintf */
|
||||
#define mprintf(a,...) printf_utf8((a), __VA_ARGS__)
|
||||
#define printf(a,...) printf_utf8((a), __VA_ARGS__)
|
||||
#endif /* WINDOWS */
|
||||
|
||||
@ -324,7 +326,7 @@ local_do_shell(const char *args)
|
||||
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
|
||||
}
|
||||
system(args); // execute the shell or cmd given
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
int status;
|
||||
char *shell;
|
||||
pid_t pid;
|
||||
@ -358,7 +360,7 @@ local_do_shell(const char *args)
|
||||
error("Shell exited abnormally");
|
||||
else if (WEXITSTATUS(status))
|
||||
error("Shell exited with status %d", WEXITSTATUS(status));
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -418,11 +420,7 @@ make_absolute(char *p, const char *pwd)
|
||||
}
|
||||
|
||||
/* convert '\\' tp '/' */
|
||||
s1 = p;
|
||||
while ((s2 = strchr(s1, '\\')) != NULL) {
|
||||
*s2 = '/';
|
||||
s1 = s2 + 1;
|
||||
}
|
||||
convertToForwardslash(p);
|
||||
|
||||
/* Append "/" if needed to the absolute windows path */
|
||||
if (p && p[0] != '\0' && p[1] == ':') {
|
||||
@ -431,13 +429,14 @@ make_absolute(char *p, const char *pwd)
|
||||
p = s1;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
if (p && p[0] != '/') {
|
||||
abs_str = path_append(pwd, p);
|
||||
free(p);
|
||||
return(abs_str);
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
return(p);
|
||||
#endif /* !WINDOWS */
|
||||
return(p);
|
||||
|
||||
}
|
||||
@ -672,7 +671,6 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
|
||||
abs_src = xstrdup(src);
|
||||
abs_src = make_absolute(abs_src, pwd);
|
||||
|
||||
memset(&g, 0, sizeof(g));
|
||||
|
||||
debug3("Looking up %s", abs_src);
|
||||
@ -712,7 +710,7 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
} else {
|
||||
abs_dst = xstrdup(dst);
|
||||
}
|
||||
} else if (dst) {
|
||||
} else if (dst) {
|
||||
abs_dst = path_append(dst, filename);
|
||||
} else {
|
||||
abs_dst = xstrdup(filename);
|
||||
@ -720,10 +718,12 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
free(tmp);
|
||||
|
||||
resume |= global_aflag;
|
||||
if (!quiet && resume)
|
||||
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst);
|
||||
else if (!quiet && !resume)
|
||||
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
|
||||
if (!quiet && resume)
|
||||
mprintf("Resuming %s to %s\n",
|
||||
g.gl_pathv[i], abs_dst);
|
||||
else if (!quiet && !resume)
|
||||
mprintf("Fetching %s to %s\n",
|
||||
g.gl_pathv[i], abs_dst);
|
||||
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
|
||||
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
|
||||
pflag || global_pflag, 1, resume,
|
||||
@ -771,10 +771,8 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
}
|
||||
|
||||
/* If we aren't fetching to pwd then stash this status for later */
|
||||
if (tmp_dst != NULL) {
|
||||
if (tmp_dst != NULL)
|
||||
dst_is_dir = remote_is_dir(conn, tmp_dst);
|
||||
}
|
||||
|
||||
|
||||
/* If multiple matches, dst may be directory or unspecified */
|
||||
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
|
||||
@ -805,7 +803,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
abs_dst = path_append(tmp_dst, filename);
|
||||
else
|
||||
abs_dst = xstrdup(tmp_dst);
|
||||
} else if (tmp_dst) {
|
||||
} else if (tmp_dst) {
|
||||
abs_dst = path_append(tmp_dst, filename);
|
||||
} else {
|
||||
abs_dst = make_absolute(xstrdup(filename), pwd);
|
||||
@ -814,10 +812,11 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
|
||||
resume |= global_aflag;
|
||||
if (!quiet && resume)
|
||||
printf("Resuming upload of %s to %s\n", g.gl_pathv[i],
|
||||
abs_dst);
|
||||
mprintf("Resuming upload of %s to %s\n",
|
||||
g.gl_pathv[i], abs_dst);
|
||||
else if (!quiet && !resume)
|
||||
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
|
||||
mprintf("Uploading %s to %s\n",
|
||||
g.gl_pathv[i], abs_dst);
|
||||
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
|
||||
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
|
||||
pflag || global_pflag, 1, resume,
|
||||
@ -887,6 +886,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
|
||||
|
||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
||||
width = ws.ws_col;
|
||||
|
||||
columns = width / (m + 2);
|
||||
columns = MAXIMUM(columns, 1);
|
||||
colspace = width / columns;
|
||||
@ -919,24 +919,21 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
|
||||
attrib_to_stat(&d[n]->a, &sb);
|
||||
lname = ls_file(fname, &sb, 1,
|
||||
(lflag & LS_SI_UNITS));
|
||||
printf("%s\n", lname);
|
||||
mprintf("%s\n", lname);
|
||||
free(lname);
|
||||
}
|
||||
else {
|
||||
printf("%s\n", d[n]->longname);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} 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 */
|
||||
wchar_t buf[1024];
|
||||
wchar_t* wtmp = utf8_to_utf16(fname);
|
||||
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
||||
free(wtmp);
|
||||
/* cannot use printf_utf8 becuase of width specification */
|
||||
/* printf_utf8 does not account for utf-16 based argument widths */
|
||||
wchar_t buf[1024];
|
||||
wchar_t* wtmp = utf8_to_utf16(fname);
|
||||
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
||||
free(wtmp);
|
||||
#else
|
||||
printf("%-*s", colspace, fname);
|
||||
mprintf("%-*s", colspace, fname);
|
||||
#endif
|
||||
if (c >= columns) {
|
||||
printf("\n");
|
||||
@ -995,7 +992,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
|
||||
globfree(&g);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
||||
width = ws.ws_col;
|
||||
|
||||
@ -1018,21 +1015,21 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
|
||||
}
|
||||
lname = ls_file(fname, g.gl_statv[i], 1,
|
||||
(lflag & LS_SI_UNITS));
|
||||
printf("%s\n", lname);
|
||||
free(lname);
|
||||
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 */
|
||||
wchar_t buf[1024];
|
||||
wchar_t* wtmp = utf8_to_utf16(fname);
|
||||
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
||||
free(wtmp);
|
||||
/* cannot use printf_utf8 becuase of width specification */
|
||||
/* printf_utf8 does not account for utf-16 based argument widths */
|
||||
wchar_t buf[1024];
|
||||
wchar_t* wtmp = utf8_to_utf16(fname);
|
||||
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
||||
free(wtmp);
|
||||
#else
|
||||
printf("%-*s", colspace, fname);
|
||||
mprintf("%-*s", colspace, fname);
|
||||
#endif
|
||||
if (c >= columns) {
|
||||
if (c >= columns) {
|
||||
printf("\n");
|
||||
c = 1;
|
||||
} else
|
||||
@ -1513,23 +1510,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
path1 = path2 = NULL;
|
||||
#ifdef WINDOWS
|
||||
/*
|
||||
* convert '/' to '\' in Windows styled paths.
|
||||
* convert '\\' to '/' in Windows styled paths.
|
||||
* else they get treated as escape sequence in makeargv
|
||||
*/
|
||||
{
|
||||
char *s1 = cmd, *s2;
|
||||
while ((s2 = strchr(s1, '\\')) != NULL) {
|
||||
*s2 = '/';
|
||||
s1 = s2 + 1;
|
||||
}
|
||||
}
|
||||
convertToForwardslash(cmd);
|
||||
#endif
|
||||
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
|
||||
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
|
||||
if (ignore_errors != 0)
|
||||
err_abort = 0;
|
||||
|
||||
memset(&g, 0, sizeof(g));
|
||||
memset(&g, 0, sizeof(g));
|
||||
|
||||
/* Perform command */
|
||||
switch (cmdnum) {
|
||||
@ -1570,10 +1561,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
case I_RM:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
|
||||
|
||||
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
||||
if (!quiet)
|
||||
printf("Removing %s\n", g.gl_pathv[i]);
|
||||
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
||||
if (!quiet)
|
||||
mprintf("Removing %s\n", g.gl_pathv[i]);
|
||||
err = do_rm(conn, g.gl_pathv[i]);
|
||||
if (err != 0 && err_abort)
|
||||
break;
|
||||
@ -1673,7 +1663,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
|
||||
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
||||
if (!quiet)
|
||||
printf("Changing mode on %s\n", g.gl_pathv[i]);
|
||||
mprintf("Changing mode on %s\n",
|
||||
g.gl_pathv[i]);
|
||||
err = do_setstat(conn, g.gl_pathv[i], &a);
|
||||
if (err != 0 && err_abort)
|
||||
break;
|
||||
@ -1703,13 +1694,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||
if (cmdnum == I_CHOWN) {
|
||||
if (!quiet)
|
||||
printf("Changing owner on %s\n",
|
||||
g.gl_pathv[i]);
|
||||
mprintf("Changing owner on %s\n",
|
||||
g.gl_pathv[i]);
|
||||
aa->uid = n_arg;
|
||||
} else {
|
||||
if (!quiet)
|
||||
printf("Changing group on %s\n",
|
||||
g.gl_pathv[i]);
|
||||
mprintf("Changing group on %s\n",
|
||||
g.gl_pathv[i]);
|
||||
aa->gid = n_arg;
|
||||
}
|
||||
err = do_setstat(conn, g.gl_pathv[i], aa);
|
||||
@ -1718,7 +1709,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
}
|
||||
break;
|
||||
case I_PWD:
|
||||
printf("Remote working directory: %s\n", *pwd);
|
||||
mprintf("Remote working directory: %s\n", *pwd);
|
||||
break;
|
||||
case I_LPWD:
|
||||
if (!getcwd(path_buf, sizeof(path_buf))) {
|
||||
@ -1726,7 +1717,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
printf("Local working directory: %s\n", path_buf);
|
||||
mprintf("Local working directory: %s\n", path_buf);
|
||||
break;
|
||||
case I_QUIT:
|
||||
/* Processed below */
|
||||
@ -2129,7 +2120,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
{
|
||||
char *remote_path;
|
||||
char *dir = NULL;
|
||||
char cmd[MAX_COMMAND_LINE];
|
||||
char cmd[2048];
|
||||
int err, interactive;
|
||||
EditLine *el = NULL;
|
||||
#ifdef USE_LIBEDIT
|
||||
@ -2179,7 +2170,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
|
||||
if (remote_is_dir(conn, dir) && file2 == NULL) {
|
||||
if (!quiet)
|
||||
printf("Changing to: %s\n", dir);
|
||||
mprintf("Changing to: %s\n", dir);
|
||||
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
|
||||
if (parse_dispatch_command(conn, cmd,
|
||||
&remote_path, 1) != 0) {
|
||||
@ -2205,13 +2196,13 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
/* Min buffer size allowed in Windows is 2*/
|
||||
setvbuf(stdout, NULL, _IOLBF, 2);
|
||||
setvbuf(infile, NULL, _IOLBF, 2);
|
||||
#else
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
/* Min buffer size allowed in Windows is 2*/
|
||||
setvbuf(stdout, NULL, _IOLBF, 2);
|
||||
setvbuf(infile, NULL, _IOLBF, 2);
|
||||
#else /* !WINDOWS */
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
setvbuf(infile, NULL, _IOLBF, 0);
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
interactive = !batchmode && isatty(STDIN_FILENO);
|
||||
err = 0;
|
||||
@ -2222,35 +2213,32 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
|
||||
if (el == NULL) {
|
||||
#ifdef WINDOWS
|
||||
if (interactive) {
|
||||
wchar_t wcmd[MAX_COMMAND_LINE];
|
||||
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
|
||||
if (interactive) {
|
||||
printf("sftp> ");
|
||||
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
|
||||
if (interactive)
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* 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) {
|
||||
if (interactive)
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
#endif/* !WINDOWS */
|
||||
if (!interactive) { /* Echo command */
|
||||
mprintf("sftp> %s", cmd);
|
||||
if (strlen(cmd) > 0 &&
|
||||
@ -2324,6 +2312,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
|
||||
#endif /* USE_PIPES */
|
||||
|
||||
#ifdef WINDOWS
|
||||
/* fork replacement on Windows */
|
||||
{
|
||||
size_t cmdlen = 0;
|
||||
int i = 0;
|
||||
@ -2331,14 +2320,15 @@ connect_to_server(char *path, char **args, int *in, int *out)
|
||||
|
||||
cmdlen = strlen(path) + 1;
|
||||
for (i = 1; args[i]; i++)
|
||||
cmdlen += strlen(args[i]) + 1;
|
||||
cmdlen += strlen(args[i]) + 1 + 2;
|
||||
|
||||
full_cmd = xmalloc(cmdlen);
|
||||
full_cmd[0] = '\0';
|
||||
strcat(full_cmd, path);
|
||||
for (i = 1; args[i]; i++) {
|
||||
strcat(full_cmd, " ");
|
||||
strcat(full_cmd, " \"");
|
||||
strcat(full_cmd, args[i]);
|
||||
strcat(full_cmd, "\"");
|
||||
}
|
||||
|
||||
/* disable inheritance on local pipe ends*/
|
||||
@ -2350,9 +2340,9 @@ connect_to_server(char *path, char **args, int *in, int *out)
|
||||
}
|
||||
|
||||
if (sshpid == -1)
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
if ((sshpid = fork()) == -1)
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
fatal("fork: %s", strerror(errno));
|
||||
else if (sshpid == 0) {
|
||||
if ((dup2(c_in, STDIN_FILENO) == -1) ||
|
||||
@ -2426,11 +2416,7 @@ main(int argc, char **argv)
|
||||
size_t num_requests = DEFAULT_NUM_REQUESTS;
|
||||
long long limit_kbps = 0;
|
||||
|
||||
#ifdef WINDOWS
|
||||
/*TODO - is this really needed ???*/
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
#endif
|
||||
|
||||
ssh_malloc_init(); /* must be called before any mallocs */
|
||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||
sanitise_stdfd();
|
||||
msetlocale();
|
||||
@ -2439,17 +2425,18 @@ main(int argc, char **argv)
|
||||
memset(&args, '\0', sizeof(args));
|
||||
args.list = NULL;
|
||||
addargs(&args, "%s", ssh_program);
|
||||
|
||||
addargs(&args, "\"-oForwardX11 no\"");
|
||||
addargs(&args, "\"-oForwardAgent no\"");
|
||||
addargs(&args, "\"-oPermitLocalCommand no\"");
|
||||
addargs(&args, "\"-oClearAllForwardings yes\"");
|
||||
addargs(&args, "-oForwardX11 no");
|
||||
addargs(&args, "-oForwardAgent no");
|
||||
addargs(&args, "-oPermitLocalCommand no");
|
||||
addargs(&args, "-oClearAllForwardings yes");
|
||||
|
||||
ll = SYSLOG_LEVEL_INFO;
|
||||
|
||||
#ifdef WINDOWS
|
||||
_setmode(_fileno(stdin), O_U16TEXT);
|
||||
/* prepare for Unicode input */
|
||||
_setmode(_fileno(stdin), O_U16TEXT);
|
||||
#endif
|
||||
infile = stdin;
|
||||
infile = stdin;
|
||||
|
||||
while ((ch = getopt(argc, argv,
|
||||
"1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
|
||||
@ -2475,8 +2462,8 @@ main(int argc, char **argv)
|
||||
addargs(&args, "-%c", ch);
|
||||
break;
|
||||
case 'P':
|
||||
addargs(&args, "\"-oPort %s\"", optarg);
|
||||
break;
|
||||
addargs(&args, "-oPort %s", optarg);
|
||||
break;
|
||||
case 'v':
|
||||
if (debug_level < 3) {
|
||||
addargs(&args, "-v");
|
||||
@ -2510,8 +2497,8 @@ main(int argc, char **argv)
|
||||
fatal("%s (%s).", strerror(errno), optarg);
|
||||
showprogress = 0;
|
||||
quiet = batchmode = 1;
|
||||
addargs(&args, "\"-obatchmode yes\"");
|
||||
break;
|
||||
addargs(&args, "-obatchmode yes");
|
||||
break;
|
||||
case 'f':
|
||||
global_fflag = 1;
|
||||
break;
|
||||
@ -2584,7 +2571,8 @@ main(int argc, char **argv)
|
||||
fprintf(stderr, "Missing hostname\n");
|
||||
usage();
|
||||
}
|
||||
addargs(&args, "\"-oProtocol %d\"", sshver);
|
||||
|
||||
addargs(&args, "-oProtocol %d", sshver);
|
||||
|
||||
/* no subsystem if the server-spec contains a '/' */
|
||||
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
|
||||
|
2
ssh.c
2
ssh.c
@ -1475,7 +1475,7 @@ control_persist_detach(void)
|
||||
*/
|
||||
fatal("ControlMaster is not supported in Windows yet");
|
||||
#else /* !WINDOWS */
|
||||
pid_t pid;
|
||||
pid_t pid;
|
||||
int devnull, keep_stderr;
|
||||
|
||||
debug("%s: backgrounding master process", __func__);
|
||||
|
82
sshd.c
82
sshd.c
@ -164,11 +164,11 @@ int saved_argc;
|
||||
/* re-exec */
|
||||
int rexeced_flag = 0;
|
||||
#ifdef WINDOWS
|
||||
/* rexec is not supported in Windows */
|
||||
/* rexec is not applicable in Windows */
|
||||
int rexec_flag = 0;
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
int rexec_flag = 1;
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
int rexec_argc = 0;
|
||||
char **rexec_argv;
|
||||
|
||||
@ -254,59 +254,6 @@ void destroy_sensitive_data(void);
|
||||
void demote_sensitive_data(void);
|
||||
static void do_ssh2_kex(void);
|
||||
|
||||
/*
|
||||
* Retrieve path to current running module.
|
||||
*
|
||||
* path - buffer, where to store path (OUT).
|
||||
* pathSize - size of path buffer in bytes (IN).
|
||||
*
|
||||
* RETURNS: 0 if OK.
|
||||
*/
|
||||
|
||||
int GetCurrentModulePath(char *path, int pathSize)
|
||||
{
|
||||
int exitCode = -1;
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
||||
char* dir = w32_programdir();
|
||||
if (strnlen(dir, pathSize) == pathSize)
|
||||
error("program directory path size exceeded provided pathSize %d", pathSize);
|
||||
else {
|
||||
memcpy(path, dir, strnlen(dir, pathSize) + 1);
|
||||
exitCode = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Linux.
|
||||
//
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
if (readlink ("/proc/self/exe", path, pathSize) != -1)
|
||||
{
|
||||
dirname(path);
|
||||
|
||||
strcat(path, "/");
|
||||
|
||||
exitCode = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// MacOS.
|
||||
//
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#endif
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close all listening sockets
|
||||
*/
|
||||
@ -591,7 +538,7 @@ reseed_prngs(void)
|
||||
/*
|
||||
* No-OP defs for preauth routines for Windows
|
||||
* these should go away once the privilege separation
|
||||
* related is refactored to be invoked only when applicable
|
||||
* related code is refactored to be invoked only when applicable
|
||||
*/
|
||||
static void
|
||||
privsep_preauth_child(void) {
|
||||
@ -608,7 +555,7 @@ privsep_postauth(Authctxt *authctxt) {
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
/* Unix privilege separation routines */
|
||||
static void
|
||||
privsep_preauth_child(void)
|
||||
@ -645,6 +592,7 @@ privsep_preauth_child(void)
|
||||
if (setgroups(1, gidset) < 0)
|
||||
fatal("setgroups: %.100s", strerror(errno));
|
||||
permanently_set_uid(privsep_pw);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -768,7 +716,7 @@ privsep_postauth(Authctxt *authctxt)
|
||||
packet_set_authenticated();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
static char *
|
||||
list_hostkey_types(void)
|
||||
@ -1143,7 +1091,7 @@ server_listen(void)
|
||||
close(listen_sock);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#endif /* WINDOWS */
|
||||
/*
|
||||
* Set socket options.
|
||||
* Allow local port reuse in TIME_WAIT.
|
||||
@ -1370,7 +1318,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
|
||||
free(path_utf8);
|
||||
close(*newsock);
|
||||
}
|
||||
#else
|
||||
#else /* !WINDOWS */
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
/*
|
||||
@ -1395,7 +1343,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
|
||||
close(config_s[0]);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
/* Parent. Stay in the loop. */
|
||||
platform_post_fork_parent(pid);
|
||||
if (pid < 0)
|
||||
@ -1764,7 +1712,7 @@ main(int ac, char **av)
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifndef WINDOWS
|
||||
#ifndef WINDOWS /* not applicable in Windows */
|
||||
/* Store privilege separation user for later use if required. */
|
||||
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
|
||||
if (use_privsep || options.kerberos_authentication)
|
||||
@ -1778,7 +1726,7 @@ main(int ac, char **av)
|
||||
privsep_pw->pw_passwd = xstrdup("*");
|
||||
}
|
||||
endpwent();
|
||||
#endif
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
/* load host keys */
|
||||
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
|
||||
@ -1796,7 +1744,7 @@ main(int ac, char **av)
|
||||
error("Could not connect to agent \"%s\": %s",
|
||||
options.host_key_agent, ssh_err(r));
|
||||
}
|
||||
#ifdef WIN32_FIXME
|
||||
#ifdef WINDOWS /* Windows version always needs and has agent running */
|
||||
have_agent = 1;
|
||||
#endif
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
@ -1977,7 +1925,7 @@ main(int ac, char **av)
|
||||
#ifdef WINDOWS
|
||||
/* For Windows child sshd, skip listener */
|
||||
if (is_child == 0)
|
||||
#endif
|
||||
#endif /* WINDOWS */
|
||||
server_listen();
|
||||
|
||||
signal(SIGHUP, sighup_handler);
|
||||
@ -2020,7 +1968,7 @@ main(int ac, char **av)
|
||||
fcntl(startup_pipe, F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
else /* Windows and Unix sshd parent */
|
||||
#endif
|
||||
#endif /* WINDOWS */
|
||||
|
||||
/* Accept a connection and return in a forked child */
|
||||
server_accept_loop(&sock_in, &sock_out,
|
||||
|
7
sshtty.c
7
sshtty.c
@ -74,9 +74,7 @@ void
|
||||
enter_raw_mode(int quiet) {
|
||||
ConInit(STD_OUTPUT_HANDLE, TRUE);
|
||||
}
|
||||
|
||||
#else /* !WINDOWS */
|
||||
|
||||
struct termios *
|
||||
get_saved_tio(void)
|
||||
{
|
||||
@ -124,7 +122,4 @@ enter_raw_mode(int quiet)
|
||||
} else
|
||||
_in_raw_mode = 1;
|
||||
}
|
||||
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
|
||||
#endif /* !WINDOWS */
|
11
utf8.c
11
utf8.c
@ -57,16 +57,15 @@ static int vasnmprintf(char **, size_t, int *, const char *, va_list);
|
||||
|
||||
static int
|
||||
dangerous_locale(void) {
|
||||
|
||||
#ifndef WINDOWS
|
||||
#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");
|
||||
#else /* !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");
|
||||
#endif /* !WINDOWS */
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* $OpenBSD: version.h,v 1.77 2016/07/24 11:45:36 djm Exp $ */
|
||||
/* $OpenBSD: version.h,v 1.78 2016/12/19 04:55:51 djm Exp $ */
|
||||
|
||||
#define SSH_VERSION "OpenSSH_7.3"
|
||||
#define SSH_VERSION "OpenSSH_7.4"
|
||||
|
||||
#define SSH_PORTABLE "p1"
|
||||
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
|
||||
|
Loading…
x
Reference in New Issue
Block a user