mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-22 05:24:43 +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
|
Please read https://www.openssh.com/report.html for bug reporting
|
||||||
instructions and note that we do not use Github for bug reporting or
|
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
|
image: Visual Studio 2015
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- V_7_3w
|
- latestw_all
|
||||||
- latestw_cwb
|
- latestw_all_openssl
|
||||||
|
|
||||||
init:
|
init:
|
||||||
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
- 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.
|
* 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 */
|
/* Return false if user is listed in DenyUsers */
|
||||||
if (options.num_deny_users > 0) {
|
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,
|
r = match_user(pw->pw_name, hostname, ipaddr,
|
||||||
options.deny_users[i]);
|
options.deny_users[i]);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -204,6 +204,7 @@ allowed_user(struct passwd * pw)
|
|||||||
pw->pw_name, hostname);
|
pw->pw_name, hostname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Return false if AllowUsers isn't empty and user isn't listed there */
|
/* Return false if AllowUsers isn't empty and user isn't listed there */
|
||||||
if (options.num_allow_users > 0) {
|
if (options.num_allow_users > 0) {
|
||||||
@ -576,7 +577,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
int fd;
|
int fd;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* Windows POSIX adpater does not support fdopen() on open(file)*/
|
/* Windows POSIX adpater does not support fdopen() on open(file)*/
|
||||||
if ((f = fopen(file, "r")) == NULL) {
|
if ((f = fopen(file, "r")) == NULL) {
|
||||||
@ -616,6 +617,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif /* !WINDOWS */
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +245,11 @@ userauth_pubkey(Authctxt *authctxt)
|
|||||||
* if a user is not allowed to login. is this an
|
* if a user is not allowed to login. is this an
|
||||||
* issue? -markus
|
* issue? -markus
|
||||||
*/
|
*/
|
||||||
#ifndef WINDOWS
|
#ifdef WINDOWS /* key validation in done in agent for Windows */
|
||||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0)))
|
|
||||||
#endif /* !WINDOWS */
|
|
||||||
{
|
{
|
||||||
|
#else /* !WINDOWS */
|
||||||
|
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
|
||||||
|
#endif /* !WINDOWS */
|
||||||
packet_start(SSH2_MSG_USERAUTH_PK_OK);
|
packet_start(SSH2_MSG_USERAUTH_PK_OK);
|
||||||
packet_put_string(pkalg, alen);
|
packet_put_string(pkalg, alen);
|
||||||
packet_put_string(pkblob, blen);
|
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;
|
c->notbefore = monotime() + 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WINDOWS /*TODO - implement user check for Windows*/
|
#ifndef WINDOWS /*TODO - implement user check for Windows*/
|
||||||
if (getpeereid(newsock, &euid, &egid) < 0) {
|
if (getpeereid(newsock, &euid, &egid) < 0) {
|
||||||
error("%s getpeereid failed: %s", __func__,
|
error("%s getpeereid failed: %s", __func__,
|
||||||
|
@ -1273,6 +1273,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
#endif /* !WINDOWS */
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
print_escape_help(berr, escape_char, compat20,
|
print_escape_help(berr, escape_char, compat20,
|
||||||
(c && c->ctl_chan != -1),
|
(c && c->ctl_chan != -1),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
%define ver 7.3p1
|
%define ver 7.4p1
|
||||||
%define rel 1
|
%define rel 1
|
||||||
|
|
||||||
# OpenSSH privilege separation requires a user & group ID
|
# OpenSSH privilege separation requires a user & group ID
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
||||||
Name: openssh
|
Name: openssh
|
||||||
Version: 7.3p1
|
Version: 7.4p1
|
||||||
URL: https://www.openssh.com/
|
URL: https://www.openssh.com/
|
||||||
Release: 1
|
Release: 1
|
||||||
Source0: openssh-%{version}.tar.gz
|
Source0: openssh-%{version}.tar.gz
|
||||||
|
@ -3,6 +3,7 @@ Set-StrictMode -Version Latest
|
|||||||
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE
|
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE
|
||||||
[string] $script:vcPath = $null
|
[string] $script:vcPath = $null
|
||||||
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
|
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
|
||||||
|
[System.IO.DirectoryInfo] $script:gitRoot = $null
|
||||||
[bool] $script:Verbose = $false
|
[bool] $script:Verbose = $false
|
||||||
[string] $script:BuildLogFile = $null
|
[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
|
function Start-SSHBuild
|
||||||
{
|
{
|
||||||
[CmdletBinding(SupportsShouldProcess=$false)]
|
[CmdletBinding(SupportsShouldProcess=$false)]
|
||||||
@ -286,6 +315,8 @@ function Start-SSHBuild
|
|||||||
|
|
||||||
# Get openssh-portable root
|
# Get openssh-portable root
|
||||||
$script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName
|
$script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName
|
||||||
|
$script:gitRoot = split-path $script:OpenSSHRoot
|
||||||
|
|
||||||
|
|
||||||
if($PSBoundParameters.ContainsKey("Verbose"))
|
if($PSBoundParameters.ContainsKey("Verbose"))
|
||||||
{
|
{
|
||||||
@ -302,6 +333,9 @@ function Start-SSHBuild
|
|||||||
Write-BuildMsg -AsInfo -Message "Build Log: $($script:BuildLogFile)"
|
Write-BuildMsg -AsInfo -Message "Build Log: $($script:BuildLogFile)"
|
||||||
|
|
||||||
Start-SSHBootstrap
|
Start-SSHBootstrap
|
||||||
|
|
||||||
|
Clone-Win32OpenSSH
|
||||||
|
Copy-OpenSSLSDK
|
||||||
$msbuildCmd = "msbuild.exe"
|
$msbuildCmd = "msbuild.exe"
|
||||||
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
|
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
|
||||||
$cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
|
$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")
|
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 */
|
/* #undef HAVE_SET_ID */
|
||||||
|
|
||||||
/* Define to 1 if you have the `SHA256_Update' function. */
|
/* 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. */
|
/* Define to 1 if you have the <sha2.h> header file. */
|
||||||
/* #undef HAVE_SHA2_H */
|
/* #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
|
$scriptdir = Split-Path $scriptpath
|
||||||
|
|
||||||
$sshdpath = Join-Path $scriptdir "sshd.exe"
|
$sshdpath = Join-Path $scriptdir "sshd.exe"
|
||||||
$sshagentpath = Join-Path $scriptdir "ssh-agent.exe"
|
$sshagentpath = Join-Path $scriptdir "ssh-agent.exe"
|
||||||
$logsdir = Join-Path $scriptdir "logs"
|
$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)) {
|
if (-not (Test-Path $sshdpath)) {
|
||||||
throw "sshd.exe is not present in script path"
|
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)'
|
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
|
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
|
Push-Location
|
||||||
cd $scriptdir
|
cd $scriptdir
|
||||||
@ -35,9 +39,9 @@ cmd.exe /c $ntrights
|
|||||||
Pop-Location
|
Pop-Location
|
||||||
|
|
||||||
mkdir $logsdir > $null
|
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 = Get-Acl -Path $logsdir
|
||||||
$acl.SetSecurityDescriptorSddlForm($sddl)
|
$Acl.SetAccessRule($accessRule)
|
||||||
Set-Acl -Path $logsdir -AclObject $acl
|
Set-Acl -Path $logsdir -AclObject $acl
|
||||||
Write-Host -ForegroundColor Green "sshd and ssh-agent services successfully installed"
|
Write-Host -ForegroundColor Green "sshd and ssh-agent services successfully installed"
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@
|
|||||||
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)digest-libc.c">
|
<ClCompile Include="$(OpenSSH-Src-Path)digest-libc.c">
|
||||||
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="$(UseOpenSSL)==true">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)dispatch.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)dispatch.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)dns.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)sandbox-pledge.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)utf8.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)utf8.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\ttymodes_windows.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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)crypto-wrap.h" />
|
<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\win32_dirent.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\no-ops.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="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_zlib.c" />
|
||||||
<ClCompile Include="..\win32compat\ansiprsr.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ansiprsr.c" />
|
||||||
<ClCompile Include="..\win32compat\conio.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\conio.c" />
|
||||||
<ClCompile Include="..\win32compat\console.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.c" />
|
||||||
<ClCompile Include="..\win32compat\tncon.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
|
||||||
<ClCompile Include="..\win32compat\tnnet.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
|
<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\termios.h" />
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\dirent.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\inc\pwd.h" />
|
||||||
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\misc_internal.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -117,6 +117,7 @@
|
|||||||
<Filter>inc</Filter>
|
<Filter>inc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
||||||
|
<ClInclude Include="..\win32compat\misc_internal.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="inc">
|
<Filter Include="inc">
|
||||||
|
@ -199,9 +199,14 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cf_flags->dwShareMode = 0;
|
||||||
|
|
||||||
switch (rwflags) {
|
switch (rwflags) {
|
||||||
case O_RDONLY:
|
case O_RDONLY:
|
||||||
cf_flags->dwDesiredAccess = GENERIC_READ;
|
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;
|
break;
|
||||||
case O_WRONLY:
|
case O_WRONLY:
|
||||||
cf_flags->dwDesiredAccess = GENERIC_WRITE;
|
cf_flags->dwDesiredAccess = GENERIC_WRITE;
|
||||||
@ -211,8 +216,6 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cf_flags->dwShareMode = 0;
|
|
||||||
|
|
||||||
cf_flags->securityAttributes.lpSecurityDescriptor = NULL;
|
cf_flags->securityAttributes.lpSecurityDescriptor = NULL;
|
||||||
cf_flags->securityAttributes.bInheritHandle = TRUE;
|
cf_flags->securityAttributes.bInheritHandle = TRUE;
|
||||||
cf_flags->securityAttributes.nLength = 0;
|
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)
|
if (c_s_flags & O_APPEND)
|
||||||
cf_flags->dwDesiredAccess = FILE_APPEND_DATA;
|
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 */
|
/*TODO - map mode */
|
||||||
|
|
||||||
|
@ -159,3 +159,6 @@ explicit_bzero(void *b, size_t len);
|
|||||||
#define fopen w32_fopen_utf8
|
#define fopen w32_fopen_utf8
|
||||||
#define popen _popen
|
#define popen _popen
|
||||||
#define pclose _pclose
|
#define pclose _pclose
|
||||||
|
|
||||||
|
void convertToBackslash(char *str);
|
||||||
|
void convertToForwardslash(char *str);
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "inc\sys\time.h"
|
#include "inc\sys\time.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
int usleep(unsigned int useconds)
|
int usleep(unsigned int useconds)
|
||||||
{
|
{
|
||||||
@ -302,11 +303,25 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) {
|
|||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
STARTUPINFOW si;
|
STARTUPINFOW si;
|
||||||
BOOL b;
|
BOOL b;
|
||||||
char* abs_cmd;
|
char *abs_cmd, *t;
|
||||||
wchar_t * cmd_utf16;
|
wchar_t * cmd_utf16;
|
||||||
|
int add_module_path = 0;
|
||||||
|
|
||||||
/* relative ? if so, add current module path to start */
|
/* should module path be added */
|
||||||
if (!(cmd && cmd[0] != '\0' && (cmd[1] == ':' || cmd[0] == '\\' || cmd[0] == '.'))) {
|
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;
|
char* ctr;
|
||||||
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1);
|
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1);
|
||||||
if (abs_cmd == NULL) {
|
if (abs_cmd == NULL) {
|
||||||
@ -478,8 +493,6 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *realpath_win(const char *path, char resolved[MAX_PATH]);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
w32_utimes(const char *filename, struct timeval *tvp) {
|
w32_utimes(const char *filename, struct timeval *tvp) {
|
||||||
struct utimbuf ub;
|
struct utimbuf ub;
|
||||||
@ -487,10 +500,7 @@ w32_utimes(const char *filename, struct timeval *tvp) {
|
|||||||
ub.modtime = tvp[1].tv_sec;
|
ub.modtime = tvp[1].tv_sec;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename));
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(filename, resolvedPathName);
|
|
||||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
|
||||||
if (resolvedPathName_utf16 == NULL) {
|
if (resolvedPathName_utf16 == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -517,16 +527,9 @@ link(const char *oldpath, const char *newpath) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_rename(const char *old_name, const char *new_name) {
|
w32_rename(const char *old_name, const char *new_name) {
|
||||||
// Skip the first '/' in the pathname
|
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(sanitized_path(old_name));
|
||||||
char resolvedOldPathName[MAX_PATH];
|
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(sanitized_path(new_name));
|
||||||
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);
|
|
||||||
if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) {
|
if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -541,11 +544,8 @@ w32_rename(const char *old_name, const char *new_name) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_unlink(const char *path) {
|
w32_unlink(const char *path) {
|
||||||
// Skip the first '/' in the pathname
|
|
||||||
char resolvedPathName[MAX_PATH];
|
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
|
||||||
if (NULL == resolvedPathName_utf16) {
|
if (NULL == resolvedPathName_utf16) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -559,11 +559,7 @@ w32_unlink(const char *path) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_rmdir(const char *path) {
|
w32_rmdir(const char *path) {
|
||||||
// Skip the first '/' in the pathname
|
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
|
||||||
if (NULL == resolvedPathName_utf16) {
|
if (NULL == resolvedPathName_utf16) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -606,11 +602,8 @@ w32_getcwd(char *buffer, int maxlen) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_mkdir(const char *path_utf8, unsigned short mode) {
|
w32_mkdir(const char *path_utf8, unsigned short mode) {
|
||||||
// Skip the first '/' in the pathname
|
|
||||||
char resolvedPathName[MAX_PATH];
|
wchar_t *path_utf16 = utf8_to_utf16(sanitized_path(path_utf8));
|
||||||
realpath_win(path_utf8, resolvedPathName);
|
|
||||||
|
|
||||||
wchar_t *path_utf16 = utf8_to_utf16(resolvedPathName);
|
|
||||||
if (path_utf16 == NULL) {
|
if (path_utf16 == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -621,86 +614,62 @@ w32_mkdir(const char *path_utf8, unsigned short mode) {
|
|||||||
return returnStatus;
|
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
|
int
|
||||||
w32_stat(const char *path, struct w32_stat *buf) {
|
w32_stat(const char *path, struct w32_stat *buf) {
|
||||||
// Skip the first '/' in the pathname
|
return fileio_stat(sanitized_path(path), (struct _stat64*)buf);
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
return fileio_stat(resolvedPathName, (struct _stat64*)buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if file is symbolic link, copy its link into "link" .
|
// if file is symbolic link, copy its link into "link" .
|
||||||
int
|
int
|
||||||
readlink(const char *path, char *link, int linklen)
|
readlink(const char *path, char *link, int linklen)
|
||||||
{
|
{
|
||||||
// Skip the first '/' in the pathname
|
strcpy_s(link, linklen, sanitized_path(path));
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
strcpy_s(link, linklen, resolvedPathName);
|
|
||||||
return 0;
|
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 /./,
|
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
|
||||||
* /../ and extra '/' characters in the null-terminated string named by
|
|
||||||
* path to produce a canonicalized absolute pathname.
|
* path to produce a canonicalized absolute pathname.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
realpath(const char *path, char resolved[MAX_PATH])
|
realpath(const char *path, char resolved[MAX_PATH]) {
|
||||||
{
|
|
||||||
char tempPath[MAX_PATH];
|
char tempPath[MAX_PATH];
|
||||||
|
|
||||||
if ((0 == strcmp(path, "./")) || (0 == strcmp(path, "."))) {
|
if (*path == '/' && *(path + 2) == ':')
|
||||||
tempPath[0] = '/';
|
strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
|
||||||
_getcwd(&tempPath[1], sizeof(tempPath) - 1);
|
|
||||||
slashconvert(tempPath);
|
|
||||||
|
|
||||||
strncpy(resolved, tempPath, strlen(tempPath) + 1);
|
|
||||||
return resolved;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path[0] != '/')
|
|
||||||
strlcpy(resolved, path, sizeof(tempPath));
|
|
||||||
else
|
else
|
||||||
strlcpy(resolved, path + 1, sizeof(tempPath));
|
strncpy(resolved, path, strlen(path) + 1);
|
||||||
|
|
||||||
backslashconvert(resolved);
|
if (_fullpath(tempPath, resolved, MAX_PATH) == NULL)
|
||||||
PathCanonicalizeA(tempPath, resolved);
|
return NULL;
|
||||||
slashconvert(tempPath);
|
|
||||||
|
convertToForwardslash(tempPath);
|
||||||
// Store terminating slash in 'X:/' on Windows.
|
|
||||||
if (tempPath[1] == ':' && tempPath[2] == 0) {
|
|
||||||
tempPath[2] = '/';
|
|
||||||
tempPath[3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolved[0] = '/'; // will be our first slash in /x:/users/test1 format
|
resolved[0] = '/'; // will be our first slash in /x:/users/test1 format
|
||||||
strncpy(resolved + 1, tempPath, sizeof(tempPath) - 1);
|
strncpy(resolved + 1, tempPath, sizeof(tempPath) - 1);
|
||||||
return resolved;
|
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
|
// Maximum reparse buffer info size. The max user defined reparse
|
||||||
// data is 16KB, plus there's a header.
|
// data is 16KB, plus there's a header.
|
||||||
#define MAX_REPARSE_SIZE 17000
|
#define MAX_REPARSE_SIZE 17000
|
||||||
@ -737,8 +706,7 @@ typedef struct _REPARSE_DATA_BUFFER {
|
|||||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||||
|
|
||||||
BOOL
|
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;
|
HANDLE fileHandle;
|
||||||
BYTE reparseBuffer[MAX_REPARSE_SIZE];
|
BYTE reparseBuffer[MAX_REPARSE_SIZE];
|
||||||
PBYTE reparseData;
|
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 "-";
|
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
|
uid_t
|
||||||
getuid(void) {
|
getuid(void) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
#include "Shlwapi.h"
|
#include "Shlwapi.h"
|
||||||
#include <sys\utime.h>
|
#include <sys\utime.h>
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
/* internal table that stores the fd to w32_io mapping*/
|
/* internal table that stores the fd to w32_io mapping*/
|
||||||
struct w32fd_table {
|
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);
|
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
char *realpath_win(const char *path, char resolved[MAX_PATH]);
|
|
||||||
int
|
int
|
||||||
w32_open(const char *pathname, int flags, ...) {
|
w32_open(const char *pathname, int flags, ...) {
|
||||||
int min_index = fd_table_get_min_index();
|
int min_index = fd_table_get_min_index();
|
||||||
@ -357,18 +358,14 @@ w32_open(const char *pathname, int flags, ...) {
|
|||||||
if (min_index == -1)
|
if (min_index == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
pio = fileio_open(sanitized_path(pathname), flags, 0);
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(pathname, resolvedPathName);
|
|
||||||
|
|
||||||
pio = fileio_open(resolvedPathName, flags, 0);
|
|
||||||
if (pio == NULL)
|
if (pio == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pio->type = NONSOCK_FD;
|
pio->type = NONSOCK_FD;
|
||||||
fd_table_set(pio, min_index);
|
fd_table_set(pio, min_index);
|
||||||
debug("open - handle:%p, io:%p, fd:%d", pio->handle, 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;
|
return min_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "inc\dirent.h"
|
#include "inc\dirent.h"
|
||||||
#include "inc\libgen.h"
|
#include "inc\libgen.h"
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
|
|
||||||
struct DIR_ {
|
struct DIR_ {
|
||||||
@ -19,8 +20,6 @@ struct DIR_ {
|
|||||||
int first;
|
int first;
|
||||||
};
|
};
|
||||||
|
|
||||||
char * realpath_win(const char *path, char resolved[MAX_PATH]);
|
|
||||||
|
|
||||||
/* Open a directory stream on NAME.
|
/* Open a directory stream on NAME.
|
||||||
Return a DIR stream on the directory, or NULL if it could not be opened. */
|
Return a DIR stream on the directory, or NULL if it could not be opened. */
|
||||||
DIR * opendir(const char *name)
|
DIR * opendir(const char *name)
|
||||||
@ -32,11 +31,7 @@ DIR * opendir(const char *name)
|
|||||||
wchar_t* wname = NULL;
|
wchar_t* wname = NULL;
|
||||||
int needed;
|
int needed;
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) {
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(name, resolvedPathName);
|
|
||||||
|
|
||||||
if ((wname = utf8_to_utf16(resolvedPathName)) == NULL) {
|
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
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.
|
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -152,7 +152,7 @@ choose_dh(int min, int wantbits, int max)
|
|||||||
struct dhgroup dhg;
|
struct dhgroup dhg;
|
||||||
|
|
||||||
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
|
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));
|
_PATH_DH_MODULI, strerror(errno));
|
||||||
return (dh_new_group_fallback(max));
|
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),
|
strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
|
||||||
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
|
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
|
||||||
|
|
||||||
if (log_handler != NULL) {
|
if (log_handler != NULL) {
|
||||||
/* Avoid recursion */
|
/* Avoid recursion */
|
||||||
tmp_handler = log_handler;
|
tmp_handler = log_handler;
|
||||||
|
2
misc.c
2
misc.c
@ -432,7 +432,6 @@ char *
|
|||||||
colon(char *cp)
|
colon(char *cp)
|
||||||
{
|
{
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
if (*cp == ':') /* Leading colon is part of file name. */
|
if (*cp == ':') /* Leading colon is part of file name. */
|
||||||
return NULL;
|
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)
|
if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
|
||||||
fatal("tilde_expand_filename: Path too long");
|
fatal("tilde_expand_filename: Path too long");
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,18 @@ _rs_init(u_char *buf, size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WITH_OPENSSL
|
#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"
|
#define SSH_RANDOM_DEV "/dev/urandom"
|
||||||
/* XXX use getrandom() if supported on Linux */
|
/* XXX use getrandom() if supported on Linux */
|
||||||
static void
|
static void
|
||||||
@ -101,6 +113,7 @@ getrnd(u_char *s, size_t len)
|
|||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
#endif /* !WINDOWS */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -469,6 +469,7 @@ default_ssh_port(void)
|
|||||||
static int
|
static int
|
||||||
execute_in_shell(const char *cmd)
|
execute_in_shell(const char *cmd)
|
||||||
{
|
{
|
||||||
|
char *shell;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
fatal("LocalCommand execution is not supported on Windows yet");
|
fatal("LocalCommand execution is not supported on Windows yet");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1725,6 +1726,7 @@ read_config_file_depth(const char *filename, struct passwd *pw,
|
|||||||
fatal("Bad owner or permissions on %s", filename);
|
fatal("Bad owner or permissions on %s", filename);
|
||||||
}
|
}
|
||||||
#endif /* !WINDOWS */
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
debug("Reading configuration data %.200s", filename);
|
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 */
|
/* prompt user */
|
||||||
wchar_t* wtmp = utf8_to_utf16(prompt);
|
wchar_t* wtmp = utf8_to_utf16(prompt);
|
||||||
|
if (wtmp == NULL)
|
||||||
|
fatal("unable to alloc memory");
|
||||||
_cputws(wtmp);
|
_cputws(wtmp);
|
||||||
free(wtmp);
|
free(wtmp);
|
||||||
|
|
||||||
@ -158,28 +160,28 @@ read_passphrase(const char *prompt, int flags)
|
|||||||
buf[len] = (unsigned char)_getch();
|
buf[len] = (unsigned char)_getch();
|
||||||
|
|
||||||
if (buf[len] == '\r') {
|
if (buf[len] == '\r') {
|
||||||
if (_kbhit())
|
if (_kbhit()) /* read linefeed if its there */
|
||||||
_getch(); // read linefeed if its there
|
_getch();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (buf[len] == '\n') {
|
else if (buf[len] == '\n') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (buf[len] == '\b') { // backspace
|
else if (buf[len] == '\b') { /* backspace */
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
len--; // overwrite last character
|
len--; /* overwrite last character */
|
||||||
}
|
}
|
||||||
else if (buf[len] == '\003') {
|
else if (buf[len] == '\003') {
|
||||||
/* exit on Ctrl+C */
|
/* exit on Ctrl+C */
|
||||||
fatal("");
|
fatal("");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
len++; // keep reading in the loop
|
len++; /* keep reading in the loop */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[len] = '\0'; // get rid of the cr/lf
|
buf[len] = '\0'; /* get rid of the cr/lf */
|
||||||
_cputs("\n"); // show a newline as we do not echo password or the line
|
_cputs("\n"); /*show a newline as we do not echo password or the line */
|
||||||
|
|
||||||
ret = xstrdup(buf);
|
ret = xstrdup(buf);
|
||||||
|
|
||||||
@ -188,7 +190,6 @@ read_passphrase(const char *prompt, int flags)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#else /* !WINDOWS */
|
#else /* !WINDOWS */
|
||||||
|
|
||||||
char *askpass = NULL, *ret, buf[1024];
|
char *askpass = NULL, *ret, buf[1024];
|
||||||
int rppflags, use_askpass = 0, ttyfd;
|
int rppflags, use_askpass = 0, ttyfd;
|
||||||
|
|
||||||
@ -235,9 +236,7 @@ read_passphrase(const char *prompt, int flags)
|
|||||||
ret = xstrdup(buf);
|
ret = xstrdup(buf);
|
||||||
explicit_bzero(buf, sizeof(buf));
|
explicit_bzero(buf, sizeof(buf));
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#endif /* !WINDOWS */
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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
|
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
|
||||||
tests: prep $(REGRESS_TARGETS)
|
tests: prep $(REGRESS_TARGETS)
|
||||||
@ -78,7 +78,8 @@ LTESTS= connect \
|
|||||||
hostkey-rotate \
|
hostkey-rotate \
|
||||||
principals-command \
|
principals-command \
|
||||||
cert-file \
|
cert-file \
|
||||||
cfginclude
|
cfginclude \
|
||||||
|
allow-deny-users
|
||||||
|
|
||||||
|
|
||||||
# dhgex \
|
# 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.
|
# Placed in the Public Domain.
|
||||||
|
|
||||||
tid="ssh with certificates"
|
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.
|
# Placed in the Public Domain.
|
||||||
|
|
||||||
tid="connect after login grace timeout"
|
tid="connect after login grace timeout"
|
||||||
@ -17,7 +17,7 @@ if [ $? -ne 0 ]; then
|
|||||||
fail "ssh connect after login grace timeout failed with privsep"
|
fail "ssh connect after login grace timeout failed with privsep"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$SUDO kill `$SUDO cat $PIDFILE`
|
stop_sshd
|
||||||
|
|
||||||
trace "test login grace without privsep"
|
trace "test login grace without privsep"
|
||||||
echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
|
echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
|
||||||
|
@ -26,13 +26,12 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
$client.SetupClient($server)
|
$client.SetupClient($server)
|
||||||
$server.SetupServer($client)
|
$server.SetupServer($client)
|
||||||
|
|
||||||
$testData = @(
|
$testData = @(
|
||||||
<# known issue 340
|
|
||||||
@{
|
@{
|
||||||
Title = 'Simple copy local file to local file'
|
Title = 'Simple copy local file to local file'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
Destination = $DestinationFilePath
|
Destination = $DestinationFilePath
|
||||||
},#>
|
},
|
||||||
@{
|
@{
|
||||||
Title = 'Simple copy local file to remote file'
|
Title = 'Simple copy local file to remote file'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
@ -42,13 +41,12 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
Title = 'Simple copy remote file to local file'
|
Title = 'Simple copy remote file to local file'
|
||||||
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
|
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
|
||||||
Destination = $DestinationFilePath
|
Destination = $DestinationFilePath
|
||||||
},
|
},
|
||||||
<# known issue 340
|
|
||||||
@{
|
@{
|
||||||
Title = 'Simple copy local file to local dir'
|
Title = 'Simple copy local file to local dir'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
Destination = $DestinationDir
|
Destination = $DestinationDir
|
||||||
},#>
|
},
|
||||||
@{
|
@{
|
||||||
Title = 'simple copy local file to remote dir'
|
Title = 'simple copy local file to remote dir'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
@ -66,7 +64,7 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
Title = 'copy from local dir to remote dir'
|
Title = 'copy from local dir to remote dir'
|
||||||
Source = $sourceDir
|
Source = $sourceDir
|
||||||
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir"
|
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir"
|
||||||
},
|
},
|
||||||
@{
|
@{
|
||||||
Title = 'copy from local dir to local dir'
|
Title = 'copy from local dir to local dir'
|
||||||
Source = $sourceDir
|
Source = $sourceDir
|
||||||
@ -84,16 +82,16 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
$client.CleanupClient()
|
$client.CleanupClient()
|
||||||
$server.CleanupServer()
|
$server.CleanupServer()
|
||||||
|
|
||||||
Get-Item $SourceDir | Remove-Item -Recurse -Force -ea silentlycontinue
|
Get-Item $SourceDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ea silentlycontinue
|
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
BeforeEach {
|
BeforeAll {
|
||||||
$null = New-Item $DestinationDir -ItemType directory -Force
|
$null = New-Item $DestinationDir -ItemType directory -Force
|
||||||
}
|
}
|
||||||
|
|
||||||
AfterEach {
|
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" {
|
<#Context "SCP usage" {
|
||||||
@ -121,7 +119,7 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
$equal | Should Be $true
|
$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)
|
param([string]$Title, $Source, $Destination)
|
||||||
|
|
||||||
.\scp -r -i $identifyFile $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 = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
$equal | Should Be $true
|
$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 = @(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 | Should Be $true
|
||||||
}#>
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#this context only run on windows
|
#this context only run on windows
|
||||||
@ -149,37 +147,34 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
|
|
||||||
#cleanup single signon
|
#cleanup single signon
|
||||||
.\ssh-add.exe -D
|
.\ssh-add.exe -D
|
||||||
}
|
}
|
||||||
|
|
||||||
It 'File Copy with -S option (positive)' {
|
It 'File Copy with -S option (positive)' {
|
||||||
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
|
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
|
||||||
#validate file content. DestPath is the path to the file.
|
#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
|
$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)
|
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.
|
#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, LastWriteTime.DateTime).Length -eq 0
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
}#>
|
}
|
||||||
|
|
||||||
<# known issue 369
|
It 'Directory recursive Copy with -r -p -v option: <Title> ' -TestCases:$testData1 {
|
||||||
It 'Directory recursive Copy with -v option: <Title> ' -TestCases:$testData1 {
|
param([string]$Title, $Source, $Destination)
|
||||||
param([string]$Title, $Source, $Destination)
|
.\scp -r -p -c aes128-ctr -v $Source $Destination
|
||||||
|
|
||||||
.\scp -r -p $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
|
$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" {
|
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
|
.\scp -i $identifyFile -C -q $Source $Destination
|
||||||
#validate file content. DestPath is the path to the file.
|
#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
|
$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)
|
param([string]$Title, $Source, $Destination)
|
||||||
|
|
||||||
.\scp -i $identifyFile -r -q $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 = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
$equal | Should Be $true
|
$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 = @(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 | 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.
|
# Placed in the Public Domain.
|
||||||
|
|
||||||
tid="reexec tests"
|
tid="reexec tests"
|
||||||
@ -39,8 +39,7 @@ echo "InvalidXXX=no" >> $OBJ/sshd_config
|
|||||||
|
|
||||||
copy_tests
|
copy_tests
|
||||||
|
|
||||||
$SUDO kill `$SUDO cat $PIDFILE`
|
stop_sshd
|
||||||
rm -f $PIDFILE
|
|
||||||
|
|
||||||
cp $OBJ/sshd_config.orig $OBJ/sshd_config
|
cp $OBJ/sshd_config.orig $OBJ/sshd_config
|
||||||
|
|
||||||
@ -54,8 +53,7 @@ rm -f $SSHD_COPY
|
|||||||
|
|
||||||
copy_tests
|
copy_tests
|
||||||
|
|
||||||
$SUDO kill `$SUDO cat $PIDFILE`
|
stop_sshd
|
||||||
rm -f $PIDFILE
|
|
||||||
|
|
||||||
verbose "test reexec fallback without privsep"
|
verbose "test reexec fallback without privsep"
|
||||||
|
|
||||||
@ -67,7 +65,6 @@ rm -f $SSHD_COPY
|
|||||||
|
|
||||||
copy_tests
|
copy_tests
|
||||||
|
|
||||||
$SUDO kill `$SUDO cat $PIDFILE`
|
stop_sshd
|
||||||
rm -f $PIDFILE
|
|
||||||
|
|
||||||
fi
|
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.
|
# Placed in the Public Domain.
|
||||||
|
|
||||||
#SUDO=sudo
|
#SUDO=sudo
|
||||||
@ -293,16 +293,8 @@ md5 () {
|
|||||||
}
|
}
|
||||||
# End of portable specific functions
|
# End of portable specific functions
|
||||||
|
|
||||||
# helper
|
stop_sshd ()
|
||||||
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
|
|
||||||
if [ -f $PIDFILE ]; then
|
if [ -f $PIDFILE ]; then
|
||||||
pid=`$SUDO cat $PIDFILE`
|
pid=`$SUDO cat $PIDFILE`
|
||||||
if [ "X$pid" = "X" ]; then
|
if [ "X$pid" = "X" ]; then
|
||||||
@ -325,6 +317,19 @@ cleanup ()
|
|||||||
fi
|
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 ()
|
start_debug_log ()
|
||||||
{
|
{
|
||||||
echo "trace: $@" >$TEST_REGRESS_LOGFILE
|
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
|
* Regress test for the utf8.h *mprintf() API
|
||||||
*
|
*
|
||||||
@ -69,7 +69,6 @@ tests(void)
|
|||||||
TEST_DONE();
|
TEST_DONE();
|
||||||
|
|
||||||
badarg();
|
badarg();
|
||||||
one("null", NULL, 8, 6, 6, "(null)");
|
|
||||||
one("empty", "", 2, 0, 0, "");
|
one("empty", "", 2, 0, 0, "");
|
||||||
one("ascii", "x", -2, -2, -2, "x");
|
one("ascii", "x", -2, -2, -2, "x");
|
||||||
one("newline", "a\nb", -2, -2, -2, "a\nb");
|
one("newline", "a\nb", -2, -2, -2, "a\nb");
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "sandbox.h"
|
#include "sandbox.h"
|
||||||
|
#include "monitor.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* Darwin/OS X sandbox */
|
/* Darwin/OS X sandbox */
|
||||||
|
120
scp.c
120
scp.c
@ -214,7 +214,7 @@ do_local_cmd(arglist *a)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
if ((pid = fork()) == -1)
|
if ((pid = fork()) == -1)
|
||||||
fatal("do_local_cmd: fork: %s", strerror(errno));
|
fatal("do_local_cmd: fork: %s", strerror(errno));
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ do_local_cmd(arglist *a)
|
|||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
return (0);
|
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. */
|
/* Fork a child to execute the command on the remote host using ssh. */
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
/* generate command line and spawn_child */
|
||||||
replacearg(&args, 0, "%s", ssh_program);
|
replacearg(&args, 0, "%s", ssh_program);
|
||||||
if (remuser != NULL) {
|
if (remuser != NULL) {
|
||||||
addargs(&args, "-l");
|
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);
|
do_cmd_pid = spawn_child(full_cmd, pin[0], pout[1], STDERR_FILENO, 0);
|
||||||
free(full_cmd);
|
free(full_cmd);
|
||||||
}
|
}
|
||||||
|
#else /* !WINDOWS */
|
||||||
|
|
||||||
#else
|
|
||||||
do_cmd_pid = fork();
|
do_cmd_pid = fork();
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
if (do_cmd_pid == 0) {
|
if (do_cmd_pid == 0) {
|
||||||
/* Child. */
|
/* Child. */
|
||||||
close(pin[1]);
|
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. */
|
/* Fork a child to execute the command on the remote host using ssh. */
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
/* generate command line and spawn_child */
|
||||||
replacearg(&args, 0, "%s", ssh_program);
|
replacearg(&args, 0, "%s", ssh_program);
|
||||||
if (remuser != NULL) {
|
if (remuser != NULL) {
|
||||||
addargs(&args, "-l");
|
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);
|
pid = spawn_child(full_cmd, fdin, fdout, STDERR_FILENO, 0);
|
||||||
free(full_cmd);
|
free(full_cmd);
|
||||||
}
|
}
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
pid = fork();
|
pid = fork();
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
dup2(fdin, 0);
|
dup2(fdin, 0);
|
||||||
dup2(fdout, 1);
|
dup2(fdout, 1);
|
||||||
@ -592,6 +592,18 @@ main(int argc, char **argv)
|
|||||||
remin = STDIN_FILENO;
|
remin = STDIN_FILENO;
|
||||||
remout = STDOUT_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) {
|
if (fflag) {
|
||||||
/* Follow "protocol", send data. */
|
/* Follow "protocol", send data. */
|
||||||
(void) response();
|
(void) response();
|
||||||
@ -807,6 +819,41 @@ tolocal(int argc, char **argv)
|
|||||||
for (i = 0; i < argc - 1; i++) {
|
for (i = 0; i < argc - 1; i++) {
|
||||||
if (!(src = colon(argv[i]))) { /* Local to local. */
|
if (!(src = colon(argv[i]))) { /* Local to local. */
|
||||||
freeargs(&alist);
|
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);
|
addargs(&alist, "%s", _PATH_CP);
|
||||||
if (iamrecursive)
|
if (iamrecursive)
|
||||||
addargs(&alist, "-r");
|
addargs(&alist, "-r");
|
||||||
@ -815,6 +862,7 @@ tolocal(int argc, char **argv)
|
|||||||
addargs(&alist, "--");
|
addargs(&alist, "--");
|
||||||
addargs(&alist, "%s", argv[i]);
|
addargs(&alist, "%s", argv[i]);
|
||||||
addargs(&alist, "%s", argv[argc-1]);
|
addargs(&alist, "%s", argv[argc-1]);
|
||||||
|
#endif /* !WINDOWS */
|
||||||
if (do_local_cmd(&alist))
|
if (do_local_cmd(&alist))
|
||||||
++errs;
|
++errs;
|
||||||
continue;
|
continue;
|
||||||
@ -892,26 +940,10 @@ syserr: run_err("%s: %s", name, strerror(errno));
|
|||||||
run_err("%s: not a regular file", name);
|
run_err("%s: not a regular file", name);
|
||||||
goto next;
|
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)
|
if ((last = strrchr(name, '/')) == NULL)
|
||||||
last = name;
|
last = name;
|
||||||
else
|
else
|
||||||
++last;
|
++last;
|
||||||
#endif
|
|
||||||
curfile = last;
|
curfile = last;
|
||||||
if (pflag) {
|
if (pflag) {
|
||||||
if (do_times(remout, verbose_mode, &stb) < 0)
|
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);
|
(u_int) (statp->st_mode & FILEMODEMASK), 0, last);
|
||||||
if (verbose_mode)
|
if (verbose_mode)
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* TODO - make fmprintf work for Windows */
|
/* TODO - make fmprintf work for Windows */
|
||||||
{
|
{
|
||||||
printf("Entering directory: ");
|
printf("Entering directory: ");
|
||||||
wchar_t* wtmp = utf8_to_utf16(path);
|
wchar_t* wtmp = utf8_to_utf16(path);
|
||||||
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
|
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
|
||||||
free(wtmp);
|
free(wtmp);
|
||||||
}
|
}
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
fmprintf(stderr, "Entering directory: %s", path);
|
fmprintf(stderr, "Entering directory: %s", path);
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
(void) atomicio(vwrite, remout, path, strlen(path));
|
(void) atomicio(vwrite, remout, path, strlen(path));
|
||||||
if (response() < 0) {
|
if (response() < 0) {
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
@ -1085,16 +1117,17 @@ sink(int argc, char **argv)
|
|||||||
*cp = 0;
|
*cp = 0;
|
||||||
if (verbose_mode)
|
if (verbose_mode)
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* TODO - make fmprintf work for Windows */
|
/* TODO - make fmprintf work for Windows */
|
||||||
{
|
{
|
||||||
printf("Sink: ");
|
printf("Sink: ");
|
||||||
wchar_t* wtmp = utf8_to_utf16(buf);
|
wchar_t* wtmp = utf8_to_utf16(buf);
|
||||||
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
|
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
|
||||||
free(wtmp);
|
free(wtmp);
|
||||||
}
|
}
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
fmprintf(stderr, "Sink: %s", buf);
|
fmprintf(stderr, "Sink: %s", buf);
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
if (buf[0] == '\01' || buf[0] == '\02') {
|
if (buf[0] == '\01' || buf[0] == '\02') {
|
||||||
if (iamremote == 0) {
|
if (iamremote == 0) {
|
||||||
(void) snmprintf(visbuf, sizeof(visbuf),
|
(void) snmprintf(visbuf, sizeof(visbuf),
|
||||||
@ -1496,3 +1529,4 @@ lostconn(int signo)
|
|||||||
else
|
else
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ derelativise_path(const char *path)
|
|||||||
expanded = tilde_expand_filename(path, getuid());
|
expanded = tilde_expand_filename(path, getuid());
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* Windows absolute paths have a drive letter followed by :*/
|
/* Windows absolute paths have a drive letter followed by :*/
|
||||||
if (expanded[1] == ':')
|
if (*expanded != '\0' && expanded[1] == ':')
|
||||||
#else /* !WINDOWS */
|
#else /* !WINDOWS */
|
||||||
if (*expanded == '/')
|
if (*expanded == '/')
|
||||||
#endif /* !WINDOWS */
|
#endif /* !WINDOWS */
|
||||||
|
552
session.c
552
session.c
@ -183,8 +183,8 @@ static int
|
|||||||
auth_input_request_forwarding(struct passwd * pw)
|
auth_input_request_forwarding(struct passwd * pw)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
packet_send_debug("Agent forwarding not supported yet in Windows");
|
packet_send_debug("Agent forwarding not supported yet in Windows");
|
||||||
return 0;
|
return 0;
|
||||||
#else /* !WINDOWS */
|
#else /* !WINDOWS */
|
||||||
Channel *nc;
|
Channel *nc;
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
@ -296,7 +296,7 @@ xauth_valid_string(const char *s)
|
|||||||
* do_exec* on Windows
|
* do_exec* on Windows
|
||||||
* - Read and set user environment variables from registry
|
* - Read and set user environment variables from registry
|
||||||
* - Build subsystem cmdline path
|
* - 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
|
* - ssh-shellhost.exe implements server-side PTY for Windows
|
||||||
*/
|
*/
|
||||||
#include <Shlobj.h>
|
#include <Shlobj.h>
|
||||||
@ -312,360 +312,336 @@ xauth_valid_string(const char *s)
|
|||||||
|
|
||||||
void setup_session_vars(Session* s)
|
void setup_session_vars(Session* s)
|
||||||
{
|
{
|
||||||
wchar_t* pw_dir_w;
|
wchar_t* pw_dir_w;
|
||||||
wchar_t* tmp;
|
wchar_t* tmp;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
char* laddr;
|
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)
|
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
|
||||||
fatal("%s: out of memory");
|
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 (s->display)
|
if ((tmp = utf8_to_utf16(s->pw->pw_name)) == NULL)
|
||||||
SetEnvironmentVariableA("DISPLAY", s->display);
|
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"HOMEPATH", pw_dir_w);
|
||||||
SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w);
|
SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w);
|
||||||
|
|
||||||
if (pw_dir_w[1] == L':') {
|
if (pw_dir_w[1] == L':') {
|
||||||
wchar_t wc = pw_dir_w[2];
|
wchar_t wc = pw_dir_w[2];
|
||||||
pw_dir_w[2] = L'\0';
|
pw_dir_w[2] = L'\0';
|
||||||
SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w);
|
SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w);
|
||||||
pw_dir_w[2] = wc;
|
pw_dir_w[2] = wc;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "%.50s %d %d",
|
snprintf(buf, sizeof buf, "%.50s %d %d",
|
||||||
ssh->remote_ipaddr, ssh->remote_port, ssh->local_port);
|
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",
|
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
|
||||||
ssh->remote_ipaddr, ssh->remote_port, laddr, ssh->local_port);
|
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)
|
if (original_command)
|
||||||
SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command);
|
SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command);
|
||||||
|
|
||||||
|
|
||||||
if ((s->term) && (s->term[0]))
|
if ((s->term) && (s->term[0]))
|
||||||
SetEnvironmentVariable("TERM", s->term);
|
SetEnvironmentVariable("TERM", s->term);
|
||||||
|
|
||||||
if (!s->is_subsystem) {
|
if (!s->is_subsystem) {
|
||||||
snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME"));
|
snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME"));
|
||||||
SetEnvironmentVariableA("PROMPT", buf);
|
SetEnvironmentVariableA("PROMPT", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*set user environment variables*/
|
/*set user environment variables*/
|
||||||
{
|
{
|
||||||
UCHAR InfoBuffer[1000];
|
UCHAR InfoBuffer[1000];
|
||||||
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
|
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
|
||||||
DWORD dwInfoBufferSize, tmp_len;
|
DWORD dwInfoBufferSize, tmp_len;
|
||||||
LPWSTR sid_str = NULL;
|
LPWSTR sid_str = NULL;
|
||||||
wchar_t reg_path[MAX_PATH];
|
wchar_t reg_path[MAX_PATH];
|
||||||
HKEY reg_key = 0;
|
HKEY reg_key = 0;
|
||||||
HANDLE token = s->authctxt->methoddata;
|
HANDLE token = s->authctxt->methoddata;
|
||||||
|
|
||||||
tmp_len = MAX_PATH;
|
tmp_len = MAX_PATH;
|
||||||
if (GetTokenInformation(token, TokenUser, InfoBuffer,
|
if (GetTokenInformation(token, TokenUser, InfoBuffer,
|
||||||
1000, &dwInfoBufferSize) == FALSE ||
|
1000, &dwInfoBufferSize) == FALSE ||
|
||||||
ConvertSidToStringSidW(pTokenUser->User.Sid, &sid_str) == 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 ||
|
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 ||
|
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) {
|
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)pw_dir_w, &tmp_len) != 0) {
|
||||||
/* one of the above failed */
|
/* one of the above failed */
|
||||||
debug("cannot retirve profile path - perhaps user profile is not created yet");
|
debug("cannot retirve profile path - perhaps user profile is not created yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sid_str)
|
if (sid_str)
|
||||||
LocalFree(sid_str);
|
LocalFree(sid_str);
|
||||||
|
|
||||||
if (reg_key)
|
if (reg_key)
|
||||||
RegCloseKey(reg_key);
|
RegCloseKey(reg_key);
|
||||||
|
|
||||||
{ /* retrieve and set env variables. */
|
/* retrieve and set env variables. */
|
||||||
/* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/
|
{
|
||||||
#define MAX_VALUE_LEN 1000
|
#define MAX_VALUE_LEN 1000
|
||||||
#define MAX_DATA_LEN 2000
|
#define MAX_DATA_LEN 2000
|
||||||
#define MAX_EXPANDED_DATA_LEN 5000
|
#define MAX_EXPANDED_DATA_LEN 5000
|
||||||
wchar_t *path;
|
/* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/
|
||||||
wchar_t value_name[MAX_VALUE_LEN];
|
wchar_t *path;
|
||||||
wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply;
|
wchar_t value_name[MAX_VALUE_LEN];
|
||||||
DWORD value_type, name_len, data_len;
|
wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply;
|
||||||
int i;
|
DWORD value_type, name_len, data_len;
|
||||||
LONG ret;
|
int i;
|
||||||
|
LONG ret;
|
||||||
|
|
||||||
if (ImpersonateLoggedOnUser(token) == FALSE)
|
if (ImpersonateLoggedOnUser(token) == FALSE)
|
||||||
debug("Failed to impersonate user token, %d", GetLastError());
|
debug("Failed to impersonate user token, %d", GetLastError());
|
||||||
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
|
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
|
||||||
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
|
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
|
||||||
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
|
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
|
||||||
reg_key = 0;
|
reg_key = 0;
|
||||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS) {
|
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS) {
|
||||||
i = 0;
|
i = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
name_len = MAX_VALUE_LEN * 2;
|
name_len = MAX_VALUE_LEN * 2;
|
||||||
data_len = MAX_DATA_LEN * 2;
|
data_len = MAX_DATA_LEN * 2;
|
||||||
to_apply = NULL;
|
to_apply = NULL;
|
||||||
if (RegEnumValueW(reg_key, i++, value_name, &name_len, 0, &value_type, (LPBYTE)&value_data, &data_len) != ERROR_SUCCESS)
|
if (RegEnumValueW(reg_key, i++, value_name, &name_len, 0, &value_type, (LPBYTE)&value_data, &data_len) != ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
if (value_type == REG_SZ)
|
if (value_type == REG_SZ)
|
||||||
to_apply = value_data;
|
to_apply = value_data;
|
||||||
else if (value_type == REG_EXPAND_SZ) {
|
else if (value_type == REG_EXPAND_SZ) {
|
||||||
ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
||||||
to_apply = value_data_expanded;
|
to_apply = value_data_expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wcsicmp(value_name, L"PATH") == 0) {
|
if (wcsicmp(value_name, L"PATH") == 0) {
|
||||||
DWORD size;
|
DWORD size;
|
||||||
if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) {
|
if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) {
|
||||||
memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2);
|
memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2);
|
||||||
GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN);
|
||||||
value_data_expanded[size - 1] = L';';
|
value_data_expanded[size - 1] = L';';
|
||||||
to_apply = value_data_expanded;
|
to_apply = value_data_expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (to_apply)
|
if (to_apply)
|
||||||
SetEnvironmentVariableW(value_name, to_apply);
|
SetEnvironmentVariableW(value_name, to_apply);
|
||||||
|
}
|
||||||
|
RegCloseKey(reg_key);
|
||||||
|
}
|
||||||
|
RevertToSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pw_dir_w);
|
||||||
}
|
|
||||||
RegCloseKey(reg_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RevertToSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pw_dir_w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_exec_windows(Session *s, const char *command, int pty) {
|
int do_exec_windows(Session *s, const char *command, int pty) {
|
||||||
int pipein[2], pipeout[2], pipeerr[2], r;
|
int pipein[2], pipeout[2], pipeerr[2], r;
|
||||||
char *exec_command = NULL, *progdir = w32_programdir();
|
char *exec_command = NULL, *progdir = w32_programdir();
|
||||||
wchar_t *exec_command_w = NULL, *pw_dir_w;
|
wchar_t *exec_command_w = NULL, *pw_dir_w;
|
||||||
|
|
||||||
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR)
|
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR) {
|
||||||
{
|
error("sub system not supported, exiting\n");
|
||||||
error("sub system not supported, exiting\n");
|
fflush(NULL);
|
||||||
fflush(NULL);
|
exit(1);
|
||||||
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 ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
|
||||||
if (pipe(pipein) == -1 || pipe(pipeout) == -1 || pipe(pipeerr) == -1)
|
fatal("%s: out of memory");
|
||||||
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");
|
|
||||||
|
|
||||||
|
|
||||||
set_nonblock(pipein[0]);
|
set_nonblock(pipein[0]);
|
||||||
set_nonblock(pipein[1]);
|
set_nonblock(pipein[1]);
|
||||||
set_nonblock(pipeout[0]);
|
set_nonblock(pipeout[0]);
|
||||||
set_nonblock(pipeout[1]);
|
set_nonblock(pipeout[1]);
|
||||||
set_nonblock(pipeerr[0]);
|
set_nonblock(pipeerr[0]);
|
||||||
set_nonblock(pipeerr[1]);
|
set_nonblock(pipeerr[1]);
|
||||||
|
|
||||||
fcntl(pipein[1], F_SETFD, FD_CLOEXEC);
|
fcntl(pipein[1], F_SETFD, FD_CLOEXEC);
|
||||||
fcntl(pipeout[0], F_SETFD, FD_CLOEXEC);
|
fcntl(pipeout[0], F_SETFD, FD_CLOEXEC);
|
||||||
fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC);
|
fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
/* prepare exec - path used with CreateProcess() */
|
/* prepare exec - path used with CreateProcess() */
|
||||||
if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) {
|
if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) {
|
||||||
/* relative or absolute */
|
/* relative or absolute */
|
||||||
if (command == NULL || command[0] == '\0')
|
if (command == NULL || command[0] == '\0')
|
||||||
fatal("expecting command for a subsystem");
|
fatal("expecting command for a subsystem");
|
||||||
|
|
||||||
if (command[1] == ':') /* absolute */
|
if (command[1] == ':') /* absolute */
|
||||||
exec_command = xstrdup(command);
|
exec_command = xstrdup(command);
|
||||||
else {/*relative*/
|
else {/*relative*/
|
||||||
exec_command = malloc(strlen(progdir) + 1 + strlen(command));
|
exec_command = malloc(strlen(progdir) + 1 + strlen(command));
|
||||||
if (exec_command == NULL)
|
if (exec_command == NULL)
|
||||||
fatal("%s, out of memory");
|
fatal("%s, out of memory");
|
||||||
memcpy(exec_command, progdir, strlen(progdir));
|
memcpy(exec_command, progdir, strlen(progdir));
|
||||||
exec_command[strlen(progdir)] = '\\';
|
exec_command[strlen(progdir)] = '\\';
|
||||||
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
|
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char *shell_host = pty ? "ssh-shellhost.exe " : "ssh-shellhost.exe -nopty ", *c;
|
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);
|
exec_command = malloc(strlen(progdir) + 1 + strlen(shell_host) + (command ? strlen(command) : 0) + 1);
|
||||||
if (exec_command == NULL)
|
if (exec_command == NULL)
|
||||||
fatal("%s, out of memory");
|
fatal("%s, out of memory");
|
||||||
c = exec_command;
|
c = exec_command;
|
||||||
memcpy(c, progdir, strlen(progdir));
|
memcpy(c, progdir, strlen(progdir));
|
||||||
c += strlen(progdir);
|
c += strlen(progdir);
|
||||||
*c++ = '\\';
|
*c++ = '\\';
|
||||||
memcpy(c, shell_host, strlen(shell_host));
|
memcpy(c, shell_host, strlen(shell_host));
|
||||||
c += strlen(shell_host);
|
c += strlen(shell_host);
|
||||||
if (command) {
|
if (command) {
|
||||||
memcpy(c, command, strlen(command));
|
memcpy(c, command, strlen(command));
|
||||||
c += strlen(command);
|
c += strlen(command);
|
||||||
}
|
}
|
||||||
*c = '\0';
|
*c = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup Environment varibles */
|
/* setup Environment varibles */
|
||||||
setup_session_vars(s);
|
setup_session_vars(s);
|
||||||
|
extern int debug_flag;
|
||||||
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.cb = sizeof(STARTUPINFO);
|
||||||
si.lpReserved = 0;
|
si.lpReserved = 0;
|
||||||
si.lpTitle = NULL; /* NULL means use exe name as title */
|
si.lpTitle = NULL; /* NULL means use exe name as title */
|
||||||
si.dwX = 0;
|
si.dwX = 0;
|
||||||
si.dwY = 0;
|
si.dwY = 0;
|
||||||
si.dwXSize = 5;
|
si.dwXSize = 5;
|
||||||
si.dwYSize = 5;
|
si.dwYSize = 5;
|
||||||
si.dwXCountChars = s->col;
|
si.dwXCountChars = s->col;
|
||||||
si.dwYCountChars = s->row;
|
si.dwYCountChars = s->row;
|
||||||
si.dwFillAttribute = 0;
|
si.dwFillAttribute = 0;
|
||||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
|
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
|
||||||
si.wShowWindow = 0; // FALSE ;
|
si.wShowWindow = 0; // FALSE ;
|
||||||
si.cbReserved2 = 0;
|
si.cbReserved2 = 0;
|
||||||
si.lpReserved2 = 0;
|
si.lpReserved2 = 0;
|
||||||
|
|
||||||
si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]);
|
si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]);
|
||||||
si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]);
|
si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]);
|
||||||
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
|
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
|
||||||
si.lpDesktop = NULL;
|
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)
|
if (debug_flag)
|
||||||
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
|
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
|
||||||
DETACHED_PROCESS, NULL, pw_dir_w,
|
DETACHED_PROCESS, NULL, pw_dir_w,
|
||||||
&si, &pi);
|
&si, &pi);
|
||||||
else
|
else
|
||||||
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
|
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
|
||||||
DETACHED_PROCESS , NULL, pw_dir_w,
|
DETACHED_PROCESS , NULL, pw_dir_w,
|
||||||
&si, &pi);
|
&si, &pi);
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
{
|
{
|
||||||
debug("ERROR. Cannot create process (%u).\n", GetLastError());
|
debug("ERROR. Cannot create process (%u).\n", GetLastError());
|
||||||
free(pw_dir_w);
|
free(pw_dir_w);
|
||||||
free(exec_command_w);
|
free(exec_command_w);
|
||||||
CloseHandle(hToken);
|
CloseHandle(hToken);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else if (pty) { /*attach to shell console */
|
else if (pty) { /*attach to shell console */
|
||||||
FreeConsole();
|
FreeConsole();
|
||||||
if (!debug_flag)
|
if (!debug_flag)
|
||||||
ImpersonateLoggedOnUser(hToken);
|
ImpersonateLoggedOnUser(hToken);
|
||||||
Sleep(20);
|
Sleep(20);
|
||||||
while (AttachConsole(pi.dwProcessId) == FALSE) {
|
while (AttachConsole(pi.dwProcessId) == FALSE) {
|
||||||
DWORD exit_code;
|
DWORD exit_code;
|
||||||
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
|
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
|
||||||
break;
|
break;
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
if (!debug_flag)
|
if (!debug_flag)
|
||||||
RevertToSelf();
|
RevertToSelf();
|
||||||
{
|
{
|
||||||
/* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the
|
/* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the
|
||||||
* attached console agein */
|
* attached console agein */
|
||||||
|
|
||||||
COORD coord;
|
COORD coord;
|
||||||
coord.X = s->col;
|
coord.X = s->col;
|
||||||
coord.Y = 9999;;
|
coord.Y = 9999;;
|
||||||
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->pid = pi.dwProcessId;
|
CloseHandle(pi.hThread);
|
||||||
sw_add_child(pi.hProcess, pi.dwProcessId);
|
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);
|
||||||
|
|
||||||
/*
|
/* Close the child sides of the socket pairs. */
|
||||||
* Set interactive/non-interactive mode.
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
if (s->ttyfd == -1)
|
||||||
* We are the parent. Close the child sides of the socket pairs.
|
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
|
||||||
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
|
|
||||||
|
|
||||||
free(pw_dir_w);
|
free(pw_dir_w);
|
||||||
free(exec_command_w);
|
free(exec_command_w);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
do_exec_no_pty(Session *s, const char *command) {
|
do_exec_no_pty(Session *s, const char *command) {
|
||||||
return do_exec_windows(s, command, 0);
|
return do_exec_windows(s, command, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
do_exec_pty(Session *s, const char *command) {
|
do_exec_pty(Session *s, const char *command) {
|
||||||
return do_exec_windows(s, command, 1);
|
return do_exec_windows(s, command, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !WINDOWS */
|
#else /* !WINDOWS */
|
||||||
|
@ -1384,11 +1384,9 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
|||||||
"server reordered requests", local_path);
|
"server reordered requests", local_path);
|
||||||
}
|
}
|
||||||
debug("truncating at %llu", (unsigned long long)highwater);
|
debug("truncating at %llu", (unsigned long long)highwater);
|
||||||
#ifndef WIN32_VS
|
|
||||||
if (ftruncate(local_fd, highwater) == -1)
|
if (ftruncate(local_fd, highwater) == -1)
|
||||||
error("ftruncate \"%s\": %s", local_path,
|
error("ftruncate \"%s\": %s", local_path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (read_error) {
|
if (read_error) {
|
||||||
error("Couldn't read from remote file \"%s\" : %s",
|
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)
|
if (fsync(local_fd) == -1)
|
||||||
error("Couldn't sync file \"%s\": %s",
|
error("Couldn't sync file \"%s\": %s",
|
||||||
local_path, strerror(errno));
|
local_path, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
sshbuf_free(msg);
|
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);
|
strmode(st->st_mode, mode);
|
||||||
if (!remote) {
|
if (!remote) {
|
||||||
user = user_from_uid(st->st_uid, 0);
|
user = user_from_uid(st->st_uid, 0);
|
||||||
} else {
|
} else {
|
||||||
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
|
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
|
||||||
user = ubuf;
|
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);
|
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
|
||||||
group = gbuf;
|
group = gbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ltime != NULL) {
|
if (ltime != NULL) {
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if (now - (365*24*60*60)/2 < st->st_mtime &&
|
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) */
|
/* Solaris needs sizeof(dirent) + path length (see below) */
|
||||||
static char buf[sizeof(struct dirent) + MAXPATHLEN];
|
static char buf[sizeof(struct dirent) + MAXPATHLEN];
|
||||||
struct dirent *ret = (struct dirent *)buf;
|
struct dirent *ret = (struct dirent *)buf;
|
||||||
|
|
||||||
#ifdef __GNU_LIBRARY__
|
#ifdef __GNU_LIBRARY__
|
||||||
static int inum = 1;
|
static int inum = 1;
|
||||||
#endif /* __GNU_LIBRARY__ */
|
#endif /* __GNU_LIBRARY__ */
|
||||||
|
@ -688,7 +688,6 @@ process_open(u_int32_t id)
|
|||||||
debug3("request %u: open flags %d", id, pflags);
|
debug3("request %u: open flags %d", id, pflags);
|
||||||
flags = flags_from_portable(pflags);
|
flags = flags_from_portable(pflags);
|
||||||
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
|
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
|
||||||
|
|
||||||
logit("open \"%s\" flags %s mode 0%o",
|
logit("open \"%s\" flags %s mode 0%o",
|
||||||
name, string_from_portable(pflags), mode);
|
name, string_from_portable(pflags), mode);
|
||||||
if (readonly &&
|
if (readonly &&
|
||||||
@ -821,15 +820,13 @@ process_do_stat(u_int32_t id, int do_lstat)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
char *name;
|
char *name;
|
||||||
int r, status = SSH2_FX_FAILURE;
|
int r, status = SSH2_FX_FAILURE;
|
||||||
|
|
||||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
|
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
|
||||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
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" : "");
|
debug3("request %u: %sstat", id, do_lstat ? "l" : "");
|
||||||
verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
|
verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
|
||||||
|
r = do_lstat ? lstat(name, &st) : stat(name, &st);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
} else {
|
} else {
|
||||||
@ -899,9 +896,8 @@ process_setstat(u_int32_t id)
|
|||||||
char *name;
|
char *name;
|
||||||
int r, status = SSH2_FX_OK;
|
int r, status = SSH2_FX_OK;
|
||||||
|
|
||||||
// sshbuf_get_cstring() is called twice.. is this correct?
|
|
||||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
|
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));
|
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||||
|
|
||||||
debug("request %u: setstat name \"%s\"", id, name);
|
debug("request %u: setstat name \"%s\"", id, name);
|
||||||
@ -936,7 +932,6 @@ process_setstat(u_int32_t id)
|
|||||||
if (r == -1)
|
if (r == -1)
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
@ -962,7 +957,6 @@ process_fsetstat(u_int32_t id)
|
|||||||
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
|
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
|
||||||
logit("set \"%s\" size %llu",
|
logit("set \"%s\" size %llu",
|
||||||
name, (unsigned long long)a.size);
|
name, (unsigned long long)a.size);
|
||||||
|
|
||||||
r = ftruncate(fd, a.size);
|
r = ftruncate(fd, a.size);
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
@ -995,7 +989,6 @@ process_fsetstat(u_int32_t id)
|
|||||||
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
||||||
logit("set \"%s\" owner %lu group %lu", name,
|
logit("set \"%s\" owner %lu group %lu", name,
|
||||||
(u_long)a.uid, (u_long)a.gid);
|
(u_long)a.uid, (u_long)a.gid);
|
||||||
|
|
||||||
#ifdef HAVE_FCHOWN
|
#ifdef HAVE_FCHOWN
|
||||||
r = fchown(fd, a.uid, a.gid);
|
r = fchown(fd, a.uid, a.gid);
|
||||||
#else
|
#else
|
||||||
@ -1018,11 +1011,9 @@ process_opendir(u_int32_t id)
|
|||||||
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
|
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
|
||||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||||
|
|
||||||
dirp = opendir(path);
|
|
||||||
|
|
||||||
debug3("request %u: opendir", id);
|
debug3("request %u: opendir", id);
|
||||||
logit("opendir \"%s\"", path);
|
logit("opendir \"%s\"", path);
|
||||||
|
dirp = opendir(path);
|
||||||
if (dirp == NULL) {
|
if (dirp == NULL) {
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
} else {
|
} else {
|
||||||
@ -1064,7 +1055,6 @@ process_readdir(u_int32_t id)
|
|||||||
int nstats = 10, count = 0, i;
|
int nstats = 10, count = 0, i;
|
||||||
|
|
||||||
stats = xcalloc(nstats, sizeof(Stat));
|
stats = xcalloc(nstats, sizeof(Stat));
|
||||||
|
|
||||||
while ((dp = readdir(dirp)) != NULL) {
|
while ((dp = readdir(dirp)) != NULL) {
|
||||||
if (count >= nstats) {
|
if (count >= nstats) {
|
||||||
nstats *= 2;
|
nstats *= 2;
|
||||||
@ -1078,7 +1068,7 @@ process_readdir(u_int32_t id)
|
|||||||
stat_to_attrib(&st, &(stats[count].attrib));
|
stat_to_attrib(&st, &(stats[count].attrib));
|
||||||
stats[count].name = xstrdup(dp->d_name);
|
stats[count].name = xstrdup(dp->d_name);
|
||||||
stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
|
stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
|
||||||
count++;
|
count++;
|
||||||
/* send up to 100 entries in one message */
|
/* send up to 100 entries in one message */
|
||||||
/* XXX check packet size instead */
|
/* XXX check packet size instead */
|
||||||
if (count == 100)
|
if (count == 100)
|
||||||
@ -1108,7 +1098,6 @@ process_remove(u_int32_t id)
|
|||||||
|
|
||||||
debug3("request %u: remove", id);
|
debug3("request %u: remove", id);
|
||||||
logit("remove name \"%s\"", name);
|
logit("remove name \"%s\"", name);
|
||||||
|
|
||||||
r = unlink(name);
|
r = unlink(name);
|
||||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
@ -1130,8 +1119,6 @@ process_mkdir(u_int32_t id)
|
|||||||
a.perm & 07777 : 0777;
|
a.perm & 07777 : 0777;
|
||||||
debug3("request %u: mkdir", id);
|
debug3("request %u: mkdir", id);
|
||||||
logit("mkdir name \"%s\" mode 0%o", name, mode);
|
logit("mkdir name \"%s\" mode 0%o", name, mode);
|
||||||
|
|
||||||
|
|
||||||
r = mkdir(name, mode);
|
r = mkdir(name, mode);
|
||||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
@ -1149,7 +1136,6 @@ process_rmdir(u_int32_t id)
|
|||||||
|
|
||||||
debug3("request %u: rmdir", id);
|
debug3("request %u: rmdir", id);
|
||||||
logit("rmdir name \"%s\"", name);
|
logit("rmdir name \"%s\"", name);
|
||||||
|
|
||||||
r = rmdir(name);
|
r = rmdir(name);
|
||||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
@ -1170,7 +1156,6 @@ process_realpath(u_int32_t id)
|
|||||||
free(path);
|
free(path);
|
||||||
path = xstrdup(".");
|
path = xstrdup(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
debug3("request %u: realpath", id);
|
debug3("request %u: realpath", id);
|
||||||
verbose("realpath \"%s\"", path);
|
verbose("realpath \"%s\"", path);
|
||||||
if (realpath(path, resolvedname) == NULL) {
|
if (realpath(path, resolvedname) == NULL) {
|
||||||
@ -1233,8 +1218,7 @@ process_rename(u_int32_t id)
|
|||||||
unlink(newpath);
|
unlink(newpath);
|
||||||
} else
|
} else
|
||||||
status = SSH2_FX_OK;
|
status = SSH2_FX_OK;
|
||||||
}
|
} else if (stat(newpath, &sb) == -1) {
|
||||||
else if (stat(newpath, &sb) == -1) {
|
|
||||||
if (rename(oldpath, newpath) == -1)
|
if (rename(oldpath, newpath) == -1)
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
else
|
else
|
||||||
@ -1257,7 +1241,6 @@ process_readlink(u_int32_t id)
|
|||||||
|
|
||||||
debug3("request %u: readlink", id);
|
debug3("request %u: readlink", id);
|
||||||
verbose("readlink \"%s\"", path);
|
verbose("readlink \"%s\"", path);
|
||||||
|
|
||||||
if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
|
if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
|
||||||
send_status(id, errno_to_portable(errno));
|
send_status(id, errno_to_portable(errno));
|
||||||
else {
|
else {
|
||||||
@ -1275,7 +1258,7 @@ static void
|
|||||||
process_symlink(u_int32_t id)
|
process_symlink(u_int32_t id)
|
||||||
{
|
{
|
||||||
char *oldpath, *newpath;
|
char *oldpath, *newpath;
|
||||||
int r, status= SSH2_FX_OP_UNSUPPORTED;
|
int r, status;
|
||||||
|
|
||||||
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
|
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
|
||||||
(r = sshbuf_get_cstring(iqueue, &newpath, 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);
|
debug3("request %u: symlink", id);
|
||||||
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
|
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
|
||||||
|
|
||||||
/* this will fail if 'newpath' exists */
|
/* this will fail if 'newpath' exists */
|
||||||
r = symlink(oldpath, newpath);
|
r = symlink(oldpath, newpath);
|
||||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
|
|
||||||
free(oldpath);
|
free(oldpath);
|
||||||
free(newpath);
|
free(newpath);
|
||||||
}
|
}
|
||||||
@ -1317,7 +1298,6 @@ process_extended_statvfs(u_int32_t id)
|
|||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
struct statvfs st;
|
struct statvfs st;
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
|
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);
|
send_status(id, SSH2_FX_FAILURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (fstatvfs(fd, &st) != 0)
|
||||||
if (statvfs(handle_to_name(handle), &st) != 0)
|
send_status(id, errno_to_portable(errno));
|
||||||
if (fstatvfs(fd, &st) != 0)
|
else
|
||||||
send_status(id, errno_to_portable(errno));
|
send_statvfs(id, &st);
|
||||||
else
|
|
||||||
send_statvfs(id, &st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_extended_hardlink(u_int32_t id)
|
process_extended_hardlink(u_int32_t id)
|
||||||
{
|
{
|
||||||
char *oldpath, *newpath;
|
char *oldpath, *newpath;
|
||||||
int r, status = SSH2_FX_OP_UNSUPPORTED;
|
int r, status;
|
||||||
|
|
||||||
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
|
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
|
||||||
(r = sshbuf_get_cstring(iqueue, &newpath, 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);
|
debug3("request %u: hardlink", id);
|
||||||
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
|
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
|
||||||
|
|
||||||
r = link(oldpath, newpath);
|
r = link(oldpath, newpath);
|
||||||
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||||
|
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
free(oldpath);
|
free(oldpath);
|
||||||
free(newpath);
|
free(newpath);
|
||||||
@ -1429,11 +1405,10 @@ process(void)
|
|||||||
const u_char *cp;
|
const u_char *cp;
|
||||||
int i, r;
|
int i, r;
|
||||||
u_int32_t id;
|
u_int32_t id;
|
||||||
|
|
||||||
buf_len = sshbuf_len(iqueue);
|
buf_len = sshbuf_len(iqueue);
|
||||||
if (buf_len < 5) {
|
if (buf_len < 5)
|
||||||
return; /* Incomplete message. */
|
return; /* Incomplete message. */
|
||||||
}
|
|
||||||
cp = sshbuf_ptr(iqueue);
|
cp = sshbuf_ptr(iqueue);
|
||||||
msg_len = get_u32(cp);
|
msg_len = get_u32(cp);
|
||||||
if (msg_len > SFTP_MAX_MSG_LENGTH) {
|
if (msg_len > SFTP_MAX_MSG_LENGTH) {
|
||||||
@ -1441,9 +1416,8 @@ process(void)
|
|||||||
client_addr, pw->pw_name);
|
client_addr, pw->pw_name);
|
||||||
sftp_server_cleanup_exit(11);
|
sftp_server_cleanup_exit(11);
|
||||||
}
|
}
|
||||||
if (buf_len < msg_len + 4) {
|
if (buf_len < msg_len + 4)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if ((r = sshbuf_consume(iqueue, 4)) != 0)
|
if ((r = sshbuf_consume(iqueue, 4)) != 0)
|
||||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||||
buf_len -= 4;
|
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;
|
int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0;
|
||||||
ssize_t len, olen, set_size;
|
ssize_t len, olen, set_size;
|
||||||
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
|
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
|
||||||
|
char *cp, *homedir = NULL, buf[4*4096];
|
||||||
char *cp, *homedir = NULL, buf[4*4096];
|
|
||||||
long mask;
|
long mask;
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
@ -1608,7 +1581,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||||||
sftp_server_usage();
|
sftp_server_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_init(__progname, log_level, log_facility, log_stderr);
|
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",
|
fatal("%s: sshbuf_check_reserve: %s",
|
||||||
__func__, ssh_err(r));
|
__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_COPY_BUFLEN 32768 /* Size of buffer for up/download */
|
||||||
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
|
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
|
||||||
#define MAX_COMMAND_LINE 2048
|
|
||||||
|
|
||||||
/* File to read commands from */
|
/* File to read commands from */
|
||||||
FILE* infile;
|
FILE* infile;
|
||||||
@ -295,6 +294,7 @@ help(void)
|
|||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* printf version to account for utf-8 input */
|
/* printf version to account for utf-8 input */
|
||||||
|
/* TODO - merge this with vfmprint */
|
||||||
static void printf_utf8(char *fmt, ... ) {
|
static void printf_utf8(char *fmt, ... ) {
|
||||||
/* TODO - is 1024 sufficient */
|
/* TODO - is 1024 sufficient */
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@ -311,6 +311,8 @@ static void printf_utf8(char *fmt, ... ) {
|
|||||||
free(wtmp);
|
free(wtmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* override mprintf */
|
||||||
|
#define mprintf(a,...) printf_utf8((a), __VA_ARGS__)
|
||||||
#define printf(a,...) printf_utf8((a), __VA_ARGS__)
|
#define printf(a,...) printf_utf8((a), __VA_ARGS__)
|
||||||
#endif /* WINDOWS */
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
@ -324,7 +326,7 @@ local_do_shell(const char *args)
|
|||||||
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
|
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
|
||||||
}
|
}
|
||||||
system(args); // execute the shell or cmd given
|
system(args); // execute the shell or cmd given
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
int status;
|
int status;
|
||||||
char *shell;
|
char *shell;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -358,7 +360,7 @@ local_do_shell(const char *args)
|
|||||||
error("Shell exited abnormally");
|
error("Shell exited abnormally");
|
||||||
else if (WEXITSTATUS(status))
|
else if (WEXITSTATUS(status))
|
||||||
error("Shell exited with status %d", WEXITSTATUS(status));
|
error("Shell exited with status %d", WEXITSTATUS(status));
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -418,11 +420,7 @@ make_absolute(char *p, const char *pwd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* convert '\\' tp '/' */
|
/* convert '\\' tp '/' */
|
||||||
s1 = p;
|
convertToForwardslash(p);
|
||||||
while ((s2 = strchr(s1, '\\')) != NULL) {
|
|
||||||
*s2 = '/';
|
|
||||||
s1 = s2 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Append "/" if needed to the absolute windows path */
|
/* Append "/" if needed to the absolute windows path */
|
||||||
if (p && p[0] != '\0' && p[1] == ':') {
|
if (p && p[0] != '\0' && p[1] == ':') {
|
||||||
@ -431,13 +429,14 @@ make_absolute(char *p, const char *pwd)
|
|||||||
p = s1;
|
p = s1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
if (p && p[0] != '/') {
|
if (p && p[0] != '/') {
|
||||||
abs_str = path_append(pwd, p);
|
abs_str = path_append(pwd, p);
|
||||||
free(p);
|
free(p);
|
||||||
return(abs_str);
|
return(abs_str);
|
||||||
}
|
} else
|
||||||
#endif
|
return(p);
|
||||||
|
#endif /* !WINDOWS */
|
||||||
return(p);
|
return(p);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -672,7 +671,6 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
|
|||||||
|
|
||||||
abs_src = xstrdup(src);
|
abs_src = xstrdup(src);
|
||||||
abs_src = make_absolute(abs_src, pwd);
|
abs_src = make_absolute(abs_src, pwd);
|
||||||
|
|
||||||
memset(&g, 0, sizeof(g));
|
memset(&g, 0, sizeof(g));
|
||||||
|
|
||||||
debug3("Looking up %s", abs_src);
|
debug3("Looking up %s", abs_src);
|
||||||
@ -712,7 +710,7 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
|
|||||||
} else {
|
} else {
|
||||||
abs_dst = xstrdup(dst);
|
abs_dst = xstrdup(dst);
|
||||||
}
|
}
|
||||||
} else if (dst) {
|
} else if (dst) {
|
||||||
abs_dst = path_append(dst, filename);
|
abs_dst = path_append(dst, filename);
|
||||||
} else {
|
} else {
|
||||||
abs_dst = xstrdup(filename);
|
abs_dst = xstrdup(filename);
|
||||||
@ -720,10 +718,12 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
resume |= global_aflag;
|
resume |= global_aflag;
|
||||||
if (!quiet && resume)
|
if (!quiet && resume)
|
||||||
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst);
|
mprintf("Resuming %s to %s\n",
|
||||||
else if (!quiet && !resume)
|
g.gl_pathv[i], abs_dst);
|
||||||
printf("Fetching %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 (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
|
||||||
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
|
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
|
||||||
pflag || global_pflag, 1, resume,
|
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 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);
|
dst_is_dir = remote_is_dir(conn, tmp_dst);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If multiple matches, dst may be directory or unspecified */
|
/* If multiple matches, dst may be directory or unspecified */
|
||||||
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
|
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);
|
abs_dst = path_append(tmp_dst, filename);
|
||||||
else
|
else
|
||||||
abs_dst = xstrdup(tmp_dst);
|
abs_dst = xstrdup(tmp_dst);
|
||||||
} else if (tmp_dst) {
|
} else if (tmp_dst) {
|
||||||
abs_dst = path_append(tmp_dst, filename);
|
abs_dst = path_append(tmp_dst, filename);
|
||||||
} else {
|
} else {
|
||||||
abs_dst = make_absolute(xstrdup(filename), pwd);
|
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;
|
resume |= global_aflag;
|
||||||
if (!quiet && resume)
|
if (!quiet && resume)
|
||||||
printf("Resuming upload of %s to %s\n", g.gl_pathv[i],
|
mprintf("Resuming upload of %s to %s\n",
|
||||||
abs_dst);
|
g.gl_pathv[i], abs_dst);
|
||||||
else if (!quiet && !resume)
|
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 (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
|
||||||
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
|
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
|
||||||
pflag || global_pflag, 1, resume,
|
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)
|
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
||||||
width = ws.ws_col;
|
width = ws.ws_col;
|
||||||
|
|
||||||
columns = width / (m + 2);
|
columns = width / (m + 2);
|
||||||
columns = MAXIMUM(columns, 1);
|
columns = MAXIMUM(columns, 1);
|
||||||
colspace = width / columns;
|
colspace = width / columns;
|
||||||
@ -919,24 +919,21 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
|
|||||||
attrib_to_stat(&d[n]->a, &sb);
|
attrib_to_stat(&d[n]->a, &sb);
|
||||||
lname = ls_file(fname, &sb, 1,
|
lname = ls_file(fname, &sb, 1,
|
||||||
(lflag & LS_SI_UNITS));
|
(lflag & LS_SI_UNITS));
|
||||||
printf("%s\n", lname);
|
mprintf("%s\n", lname);
|
||||||
free(lname);
|
free(lname);
|
||||||
}
|
} else
|
||||||
else {
|
mprintf("%s\n", d[n]->longname);
|
||||||
printf("%s\n", d[n]->longname);
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* cannot use printf_utf8 becuase of width specification */
|
/* cannot use printf_utf8 becuase of width specification */
|
||||||
/* printf_utf8 does not account for utf-16 based argument widths */
|
/* printf_utf8 does not account for utf-16 based argument widths */
|
||||||
wchar_t buf[1024];
|
wchar_t buf[1024];
|
||||||
wchar_t* wtmp = utf8_to_utf16(fname);
|
wchar_t* wtmp = utf8_to_utf16(fname);
|
||||||
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
||||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
||||||
free(wtmp);
|
free(wtmp);
|
||||||
#else
|
#else
|
||||||
printf("%-*s", colspace, fname);
|
mprintf("%-*s", colspace, fname);
|
||||||
#endif
|
#endif
|
||||||
if (c >= columns) {
|
if (c >= columns) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -995,7 +992,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
|
|||||||
globfree(&g);
|
globfree(&g);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
||||||
width = ws.ws_col;
|
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,
|
lname = ls_file(fname, g.gl_statv[i], 1,
|
||||||
(lflag & LS_SI_UNITS));
|
(lflag & LS_SI_UNITS));
|
||||||
printf("%s\n", lname);
|
mprintf("%s\n", lname);
|
||||||
free(lname);
|
free(lname);
|
||||||
} else {
|
} else {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* cannot use printf_utf8 becuase of width specification */
|
/* cannot use printf_utf8 becuase of width specification */
|
||||||
/* printf_utf8 does not account for utf-16 based argument widths */
|
/* printf_utf8 does not account for utf-16 based argument widths */
|
||||||
wchar_t buf[1024];
|
wchar_t buf[1024];
|
||||||
wchar_t* wtmp = utf8_to_utf16(fname);
|
wchar_t* wtmp = utf8_to_utf16(fname);
|
||||||
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
|
||||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
|
||||||
free(wtmp);
|
free(wtmp);
|
||||||
#else
|
#else
|
||||||
printf("%-*s", colspace, fname);
|
mprintf("%-*s", colspace, fname);
|
||||||
#endif
|
#endif
|
||||||
if (c >= columns) {
|
if (c >= columns) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
c = 1;
|
c = 1;
|
||||||
} else
|
} else
|
||||||
@ -1513,23 +1510,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
|||||||
path1 = path2 = NULL;
|
path1 = path2 = NULL;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/*
|
/*
|
||||||
* convert '/' to '\' in Windows styled paths.
|
* convert '\\' to '/' in Windows styled paths.
|
||||||
* else they get treated as escape sequence in makeargv
|
* else they get treated as escape sequence in makeargv
|
||||||
*/
|
*/
|
||||||
{
|
convertToForwardslash(cmd);
|
||||||
char *s1 = cmd, *s2;
|
|
||||||
while ((s2 = strchr(s1, '\\')) != NULL) {
|
|
||||||
*s2 = '/';
|
|
||||||
s1 = s2 + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
|
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
|
||||||
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
|
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
|
||||||
if (ignore_errors != 0)
|
if (ignore_errors != 0)
|
||||||
err_abort = 0;
|
err_abort = 0;
|
||||||
|
|
||||||
memset(&g, 0, sizeof(g));
|
memset(&g, 0, sizeof(g));
|
||||||
|
|
||||||
/* Perform command */
|
/* Perform command */
|
||||||
switch (cmdnum) {
|
switch (cmdnum) {
|
||||||
@ -1570,10 +1561,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
|||||||
case I_RM:
|
case I_RM:
|
||||||
path1 = make_absolute(path1, *pwd);
|
path1 = make_absolute(path1, *pwd);
|
||||||
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
|
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
|
||||||
|
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
||||||
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
if (!quiet)
|
||||||
if (!quiet)
|
mprintf("Removing %s\n", g.gl_pathv[i]);
|
||||||
printf("Removing %s\n", g.gl_pathv[i]);
|
|
||||||
err = do_rm(conn, g.gl_pathv[i]);
|
err = do_rm(conn, g.gl_pathv[i]);
|
||||||
if (err != 0 && err_abort)
|
if (err != 0 && err_abort)
|
||||||
break;
|
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);
|
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
|
||||||
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
|
||||||
if (!quiet)
|
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);
|
err = do_setstat(conn, g.gl_pathv[i], &a);
|
||||||
if (err != 0 && err_abort)
|
if (err != 0 && err_abort)
|
||||||
break;
|
break;
|
||||||
@ -1703,13 +1694,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
|||||||
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||||
if (cmdnum == I_CHOWN) {
|
if (cmdnum == I_CHOWN) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("Changing owner on %s\n",
|
mprintf("Changing owner on %s\n",
|
||||||
g.gl_pathv[i]);
|
g.gl_pathv[i]);
|
||||||
aa->uid = n_arg;
|
aa->uid = n_arg;
|
||||||
} else {
|
} else {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("Changing group on %s\n",
|
mprintf("Changing group on %s\n",
|
||||||
g.gl_pathv[i]);
|
g.gl_pathv[i]);
|
||||||
aa->gid = n_arg;
|
aa->gid = n_arg;
|
||||||
}
|
}
|
||||||
err = do_setstat(conn, g.gl_pathv[i], aa);
|
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;
|
break;
|
||||||
case I_PWD:
|
case I_PWD:
|
||||||
printf("Remote working directory: %s\n", *pwd);
|
mprintf("Remote working directory: %s\n", *pwd);
|
||||||
break;
|
break;
|
||||||
case I_LPWD:
|
case I_LPWD:
|
||||||
if (!getcwd(path_buf, sizeof(path_buf))) {
|
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;
|
err = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("Local working directory: %s\n", path_buf);
|
mprintf("Local working directory: %s\n", path_buf);
|
||||||
break;
|
break;
|
||||||
case I_QUIT:
|
case I_QUIT:
|
||||||
/* Processed below */
|
/* Processed below */
|
||||||
@ -2129,7 +2120,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||||||
{
|
{
|
||||||
char *remote_path;
|
char *remote_path;
|
||||||
char *dir = NULL;
|
char *dir = NULL;
|
||||||
char cmd[MAX_COMMAND_LINE];
|
char cmd[2048];
|
||||||
int err, interactive;
|
int err, interactive;
|
||||||
EditLine *el = NULL;
|
EditLine *el = NULL;
|
||||||
#ifdef USE_LIBEDIT
|
#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 (remote_is_dir(conn, dir) && file2 == NULL) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("Changing to: %s\n", dir);
|
mprintf("Changing to: %s\n", dir);
|
||||||
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
|
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
|
||||||
if (parse_dispatch_command(conn, cmd,
|
if (parse_dispatch_command(conn, cmd,
|
||||||
&remote_path, 1) != 0) {
|
&remote_path, 1) != 0) {
|
||||||
@ -2205,13 +2196,13 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* Min buffer size allowed in Windows is 2*/
|
/* Min buffer size allowed in Windows is 2*/
|
||||||
setvbuf(stdout, NULL, _IOLBF, 2);
|
setvbuf(stdout, NULL, _IOLBF, 2);
|
||||||
setvbuf(infile, NULL, _IOLBF, 2);
|
setvbuf(infile, NULL, _IOLBF, 2);
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
setvbuf(infile, NULL, _IOLBF, 0);
|
setvbuf(infile, NULL, _IOLBF, 0);
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
interactive = !batchmode && isatty(STDIN_FILENO);
|
interactive = !batchmode && isatty(STDIN_FILENO);
|
||||||
err = 0;
|
err = 0;
|
||||||
@ -2222,35 +2213,32 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||||||
|
|
||||||
if (el == NULL) {
|
if (el == NULL) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (interactive) {
|
/* fgets on Windows does not support Unicode input*/
|
||||||
wchar_t wcmd[MAX_COMMAND_LINE];
|
if (interactive) {
|
||||||
printf("sftp> ");
|
wchar_t wcmd[2048];
|
||||||
if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
|
printf("sftp> ");
|
||||||
printf("\n");
|
if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
|
||||||
break;
|
printf("\n");
|
||||||
}
|
break;
|
||||||
else {
|
}
|
||||||
char *pcmd = NULL;
|
else {
|
||||||
if ((pcmd = utf16_to_utf8(wcmd)) == NULL)
|
char *pcmd = NULL;
|
||||||
fatal("failed to convert input arguments");
|
if ((pcmd = utf16_to_utf8(wcmd)) == NULL)
|
||||||
strcpy(cmd, pcmd);
|
fatal("failed to convert input arguments");
|
||||||
free(pcmd);
|
strcpy(cmd, pcmd);
|
||||||
}
|
free(pcmd);
|
||||||
}
|
}
|
||||||
else {
|
} else if (fgets(cmd, sizeof(cmd), infile) == NULL)
|
||||||
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
|
break;
|
||||||
break;
|
#else /* !WINDOWS */
|
||||||
}
|
if (interactive)
|
||||||
}
|
printf("sftp> ");
|
||||||
#else
|
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
|
||||||
if (interactive) {
|
if (interactive)
|
||||||
printf("sftp> ");
|
printf("\n");
|
||||||
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
|
break;
|
||||||
if (interactive)
|
}
|
||||||
printf("\n");
|
#endif/* !WINDOWS */
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!interactive) { /* Echo command */
|
if (!interactive) { /* Echo command */
|
||||||
mprintf("sftp> %s", cmd);
|
mprintf("sftp> %s", cmd);
|
||||||
if (strlen(cmd) > 0 &&
|
if (strlen(cmd) > 0 &&
|
||||||
@ -2324,6 +2312,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
|
|||||||
#endif /* USE_PIPES */
|
#endif /* USE_PIPES */
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
/* fork replacement on Windows */
|
||||||
{
|
{
|
||||||
size_t cmdlen = 0;
|
size_t cmdlen = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -2331,14 +2320,15 @@ connect_to_server(char *path, char **args, int *in, int *out)
|
|||||||
|
|
||||||
cmdlen = strlen(path) + 1;
|
cmdlen = strlen(path) + 1;
|
||||||
for (i = 1; args[i]; i++)
|
for (i = 1; args[i]; i++)
|
||||||
cmdlen += strlen(args[i]) + 1;
|
cmdlen += strlen(args[i]) + 1 + 2;
|
||||||
|
|
||||||
full_cmd = xmalloc(cmdlen);
|
full_cmd = xmalloc(cmdlen);
|
||||||
full_cmd[0] = '\0';
|
full_cmd[0] = '\0';
|
||||||
strcat(full_cmd, path);
|
strcat(full_cmd, path);
|
||||||
for (i = 1; args[i]; i++) {
|
for (i = 1; args[i]; i++) {
|
||||||
strcat(full_cmd, " ");
|
strcat(full_cmd, " \"");
|
||||||
strcat(full_cmd, args[i]);
|
strcat(full_cmd, args[i]);
|
||||||
|
strcat(full_cmd, "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disable inheritance on local pipe ends*/
|
/* disable inheritance on local pipe ends*/
|
||||||
@ -2350,9 +2340,9 @@ connect_to_server(char *path, char **args, int *in, int *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sshpid == -1)
|
if (sshpid == -1)
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
if ((sshpid = fork()) == -1)
|
if ((sshpid = fork()) == -1)
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
fatal("fork: %s", strerror(errno));
|
fatal("fork: %s", strerror(errno));
|
||||||
else if (sshpid == 0) {
|
else if (sshpid == 0) {
|
||||||
if ((dup2(c_in, STDIN_FILENO) == -1) ||
|
if ((dup2(c_in, STDIN_FILENO) == -1) ||
|
||||||
@ -2426,11 +2416,7 @@ main(int argc, char **argv)
|
|||||||
size_t num_requests = DEFAULT_NUM_REQUESTS;
|
size_t num_requests = DEFAULT_NUM_REQUESTS;
|
||||||
long long limit_kbps = 0;
|
long long limit_kbps = 0;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
ssh_malloc_init(); /* must be called before any mallocs */
|
||||||
/*TODO - is this really needed ???*/
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||||
sanitise_stdfd();
|
sanitise_stdfd();
|
||||||
msetlocale();
|
msetlocale();
|
||||||
@ -2439,17 +2425,18 @@ main(int argc, char **argv)
|
|||||||
memset(&args, '\0', sizeof(args));
|
memset(&args, '\0', sizeof(args));
|
||||||
args.list = NULL;
|
args.list = NULL;
|
||||||
addargs(&args, "%s", ssh_program);
|
addargs(&args, "%s", ssh_program);
|
||||||
|
addargs(&args, "-oForwardX11 no");
|
||||||
addargs(&args, "\"-oForwardX11 no\"");
|
addargs(&args, "-oForwardAgent no");
|
||||||
addargs(&args, "\"-oForwardAgent no\"");
|
addargs(&args, "-oPermitLocalCommand no");
|
||||||
addargs(&args, "\"-oPermitLocalCommand no\"");
|
addargs(&args, "-oClearAllForwardings yes");
|
||||||
addargs(&args, "\"-oClearAllForwardings yes\"");
|
|
||||||
|
|
||||||
ll = SYSLOG_LEVEL_INFO;
|
ll = SYSLOG_LEVEL_INFO;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
_setmode(_fileno(stdin), O_U16TEXT);
|
/* prepare for Unicode input */
|
||||||
|
_setmode(_fileno(stdin), O_U16TEXT);
|
||||||
#endif
|
#endif
|
||||||
infile = stdin;
|
infile = stdin;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv,
|
while ((ch = getopt(argc, argv,
|
||||||
"1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
|
"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);
|
addargs(&args, "-%c", ch);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
addargs(&args, "\"-oPort %s\"", optarg);
|
addargs(&args, "-oPort %s", optarg);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
if (debug_level < 3) {
|
if (debug_level < 3) {
|
||||||
addargs(&args, "-v");
|
addargs(&args, "-v");
|
||||||
@ -2510,8 +2497,8 @@ main(int argc, char **argv)
|
|||||||
fatal("%s (%s).", strerror(errno), optarg);
|
fatal("%s (%s).", strerror(errno), optarg);
|
||||||
showprogress = 0;
|
showprogress = 0;
|
||||||
quiet = batchmode = 1;
|
quiet = batchmode = 1;
|
||||||
addargs(&args, "\"-obatchmode yes\"");
|
addargs(&args, "-obatchmode yes");
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
global_fflag = 1;
|
global_fflag = 1;
|
||||||
break;
|
break;
|
||||||
@ -2584,7 +2571,8 @@ main(int argc, char **argv)
|
|||||||
fprintf(stderr, "Missing hostname\n");
|
fprintf(stderr, "Missing hostname\n");
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
addargs(&args, "\"-oProtocol %d\"", sshver);
|
|
||||||
|
addargs(&args, "-oProtocol %d", sshver);
|
||||||
|
|
||||||
/* no subsystem if the server-spec contains a '/' */
|
/* no subsystem if the server-spec contains a '/' */
|
||||||
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
|
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");
|
fatal("ControlMaster is not supported in Windows yet");
|
||||||
#else /* !WINDOWS */
|
#else /* !WINDOWS */
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int devnull, keep_stderr;
|
int devnull, keep_stderr;
|
||||||
|
|
||||||
debug("%s: backgrounding master process", __func__);
|
debug("%s: backgrounding master process", __func__);
|
||||||
|
82
sshd.c
82
sshd.c
@ -164,11 +164,11 @@ int saved_argc;
|
|||||||
/* re-exec */
|
/* re-exec */
|
||||||
int rexeced_flag = 0;
|
int rexeced_flag = 0;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* rexec is not supported in Windows */
|
/* rexec is not applicable in Windows */
|
||||||
int rexec_flag = 0;
|
int rexec_flag = 0;
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
int rexec_flag = 1;
|
int rexec_flag = 1;
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
int rexec_argc = 0;
|
int rexec_argc = 0;
|
||||||
char **rexec_argv;
|
char **rexec_argv;
|
||||||
|
|
||||||
@ -254,59 +254,6 @@ void destroy_sensitive_data(void);
|
|||||||
void demote_sensitive_data(void);
|
void demote_sensitive_data(void);
|
||||||
static void do_ssh2_kex(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
|
* Close all listening sockets
|
||||||
*/
|
*/
|
||||||
@ -591,7 +538,7 @@ reseed_prngs(void)
|
|||||||
/*
|
/*
|
||||||
* No-OP defs for preauth routines for Windows
|
* No-OP defs for preauth routines for Windows
|
||||||
* these should go away once the privilege separation
|
* 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
|
static void
|
||||||
privsep_preauth_child(void) {
|
privsep_preauth_child(void) {
|
||||||
@ -608,7 +555,7 @@ privsep_postauth(Authctxt *authctxt) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
/* Unix privilege separation routines */
|
/* Unix privilege separation routines */
|
||||||
static void
|
static void
|
||||||
privsep_preauth_child(void)
|
privsep_preauth_child(void)
|
||||||
@ -645,6 +592,7 @@ privsep_preauth_child(void)
|
|||||||
if (setgroups(1, gidset) < 0)
|
if (setgroups(1, gidset) < 0)
|
||||||
fatal("setgroups: %.100s", strerror(errno));
|
fatal("setgroups: %.100s", strerror(errno));
|
||||||
permanently_set_uid(privsep_pw);
|
permanently_set_uid(privsep_pw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -768,7 +716,7 @@ privsep_postauth(Authctxt *authctxt)
|
|||||||
packet_set_authenticated();
|
packet_set_authenticated();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
list_hostkey_types(void)
|
list_hostkey_types(void)
|
||||||
@ -1143,7 +1091,7 @@ server_listen(void)
|
|||||||
close(listen_sock);
|
close(listen_sock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* WINDOWS */
|
||||||
/*
|
/*
|
||||||
* Set socket options.
|
* Set socket options.
|
||||||
* Allow local port reuse in TIME_WAIT.
|
* 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);
|
free(path_utf8);
|
||||||
close(*newsock);
|
close(*newsock);
|
||||||
}
|
}
|
||||||
#else
|
#else /* !WINDOWS */
|
||||||
|
|
||||||
if ((pid = fork()) == 0) {
|
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]);
|
close(config_s[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
/* Parent. Stay in the loop. */
|
/* Parent. Stay in the loop. */
|
||||||
platform_post_fork_parent(pid);
|
platform_post_fork_parent(pid);
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
@ -1764,7 +1712,7 @@ main(int ac, char **av)
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS /* not applicable in Windows */
|
||||||
/* Store privilege separation user for later use if required. */
|
/* Store privilege separation user for later use if required. */
|
||||||
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
|
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
|
||||||
if (use_privsep || options.kerberos_authentication)
|
if (use_privsep || options.kerberos_authentication)
|
||||||
@ -1778,7 +1726,7 @@ main(int ac, char **av)
|
|||||||
privsep_pw->pw_passwd = xstrdup("*");
|
privsep_pw->pw_passwd = xstrdup("*");
|
||||||
}
|
}
|
||||||
endpwent();
|
endpwent();
|
||||||
#endif
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
/* load host keys */
|
/* load host keys */
|
||||||
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
|
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",
|
error("Could not connect to agent \"%s\": %s",
|
||||||
options.host_key_agent, ssh_err(r));
|
options.host_key_agent, ssh_err(r));
|
||||||
}
|
}
|
||||||
#ifdef WIN32_FIXME
|
#ifdef WINDOWS /* Windows version always needs and has agent running */
|
||||||
have_agent = 1;
|
have_agent = 1;
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < options.num_host_key_files; i++) {
|
for (i = 0; i < options.num_host_key_files; i++) {
|
||||||
@ -1977,7 +1925,7 @@ main(int ac, char **av)
|
|||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* For Windows child sshd, skip listener */
|
/* For Windows child sshd, skip listener */
|
||||||
if (is_child == 0)
|
if (is_child == 0)
|
||||||
#endif
|
#endif /* WINDOWS */
|
||||||
server_listen();
|
server_listen();
|
||||||
|
|
||||||
signal(SIGHUP, sighup_handler);
|
signal(SIGHUP, sighup_handler);
|
||||||
@ -2020,7 +1968,7 @@ main(int ac, char **av)
|
|||||||
fcntl(startup_pipe, F_SETFD, FD_CLOEXEC);
|
fcntl(startup_pipe, F_SETFD, FD_CLOEXEC);
|
||||||
}
|
}
|
||||||
else /* Windows and Unix sshd parent */
|
else /* Windows and Unix sshd parent */
|
||||||
#endif
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
/* Accept a connection and return in a forked child */
|
/* Accept a connection and return in a forked child */
|
||||||
server_accept_loop(&sock_in, &sock_out,
|
server_accept_loop(&sock_in, &sock_out,
|
||||||
|
7
sshtty.c
7
sshtty.c
@ -74,9 +74,7 @@ void
|
|||||||
enter_raw_mode(int quiet) {
|
enter_raw_mode(int quiet) {
|
||||||
ConInit(STD_OUTPUT_HANDLE, TRUE);
|
ConInit(STD_OUTPUT_HANDLE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !WINDOWS */
|
#else /* !WINDOWS */
|
||||||
|
|
||||||
struct termios *
|
struct termios *
|
||||||
get_saved_tio(void)
|
get_saved_tio(void)
|
||||||
{
|
{
|
||||||
@ -124,7 +122,4 @@ enter_raw_mode(int quiet)
|
|||||||
} else
|
} else
|
||||||
_in_raw_mode = 1;
|
_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
|
static int
|
||||||
dangerous_locale(void) {
|
dangerous_locale(void) {
|
||||||
|
#ifdef WINDOWS
|
||||||
#ifndef 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;
|
char *loc;
|
||||||
|
|
||||||
loc = nl_langinfo(CODESET);
|
loc = nl_langinfo(CODESET);
|
||||||
return strcmp(loc, "US-ASCII") && strcmp(loc, "UTF-8");
|
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 */
|
#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_PORTABLE "p1"
|
||||||
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
|
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user