Source snapshot from Powershell/openssh-portable:latestw_cwb

This commit is contained in:
Manoj Ampalam 2017-01-03 14:46:33 -08:00
parent 15c6a77338
commit a4b577b5a0
51 changed files with 785 additions and 1373 deletions

2
README
View File

@ -1,4 +1,4 @@
See https://www.openssh.com/releasenotes.html#7.3p1 for the release notes.
See https://www.openssh.com/releasenotes.html#7.4p1 for the release notes.
Please read https://www.openssh.com/report.html for bug reporting
instructions and note that we do not use Github for bug reporting or

View File

@ -1,10 +1,10 @@
version: 0.0.4.0.{build}
version: 0.0.6.0.{build}
image: Visual Studio 2015
branches:
only:
- V_7_3w
- latestw_cwb
- latestw_all
- latestw_all_openssl
init:
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

8
auth.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.118 2016/11/08 22:04:34 djm Exp $ */
/* $OpenBSD: auth.c,v 1.119 2016/12/15 21:29:05 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -192,7 +192,7 @@ allowed_user(struct passwd * pw)
/* Return false if user is listed in DenyUsers */
if (options.num_deny_users > 0) {
for (i = 0; i < options.num_deny_users; i++)
for (i = 0; i < options.num_deny_users; i++) {
r = match_user(pw->pw_name, hostname, ipaddr,
options.deny_users[i]);
if (r < 0) {
@ -204,6 +204,7 @@ allowed_user(struct passwd * pw)
pw->pw_name, hostname);
return 0;
}
}
}
/* Return false if AllowUsers isn't empty and user isn't listed there */
if (options.num_allow_users > 0) {
@ -576,7 +577,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
struct stat st;
int fd;
FILE *f;
#ifdef WINDOWS
/* Windows POSIX adpater does not support fdopen() on open(file)*/
if ((f = fopen(file, "r")) == NULL) {
@ -616,6 +617,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
return NULL;
}
#endif /* !WINDOWS */
return f;
}

View File

@ -245,10 +245,11 @@ userauth_pubkey(Authctxt *authctxt)
* if a user is not allowed to login. is this an
* issue? -markus
*/
#ifndef WINDOWS
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0)))
#endif /* !WINDOWS */
#ifdef WINDOWS /* key validation in done in agent for Windows */
{
#else /* !WINDOWS */
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
#endif /* !WINDOWS */
packet_start(SSH2_MSG_USERAUTH_PK_OK);
packet_put_string(pkalg, alen);
packet_put_string(pkblob, blen);

View File

@ -2049,6 +2049,7 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
c->notbefore = monotime() + 1;
return;
}
#ifndef WINDOWS /*TODO - implement user check for Windows*/
if (getpeereid(newsock, &euid, &egid) < 0) {
error("%s getpeereid failed: %s", __func__,

View File

@ -1273,6 +1273,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
}
continue;
#endif /* !WINDOWS */
case '?':
print_escape_help(berr, escape_char, compat20,
(c && c->ctl_chan != -1),

View File

@ -1,4 +1,4 @@
%define ver 7.3p1
%define ver 7.4p1
%define rel 1
# OpenSSH privilege separation requires a user & group ID

View File

@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
Version: 7.3p1
Version: 7.4p1
URL: https://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz

View File

@ -3,6 +3,7 @@ Set-StrictMode -Version Latest
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE
[string] $script:vcPath = $null
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
[System.IO.DirectoryInfo] $script:gitRoot = $null
[bool] $script:Verbose = $false
[string] $script:BuildLogFile = $null
@ -268,6 +269,34 @@ function Start-SSHBootstrap
}
}
function Clone-Win32OpenSSH
{
$win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH"
if (-not (Test-Path -Path $win32OpenSSHPath -PathType Container))
{
Write-BuildMsg -AsInfo -Message "clone repo Win32-OpenSSH"
Push-Location $gitRoot
git clone -q --recursive https://github.com/PowerShell/Win32-OpenSSH.git $win32OpenSSHPath
Pop-Location
}
Write-BuildMsg -AsInfo -Message "pull latest from repo Win32-OpenSSH"
Push-Location $win32OpenSSHPath
git fetch -q origin
git checkout -qf L1-Prod
Pop-Location
}
function Copy-OpenSSLSDK
{
$sourcePath = Join-Path $script:gitRoot "Win32-OpenSSH\contrib\win32\openssh\OpenSSLSDK"
Write-BuildMsg -AsInfo -Message "copying $sourcePath"
Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e
if($e -ne $null)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "Copy OpenSSL from $sourcePath failed "
}
}
function Start-SSHBuild
{
[CmdletBinding(SupportsShouldProcess=$false)]
@ -286,6 +315,8 @@ function Start-SSHBuild
# Get openssh-portable root
$script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName
$script:gitRoot = split-path $script:OpenSSHRoot
if($PSBoundParameters.ContainsKey("Verbose"))
{
@ -302,6 +333,9 @@ function Start-SSHBuild
Write-BuildMsg -AsInfo -Message "Build Log: $($script:BuildLogFile)"
Start-SSHBootstrap
Clone-Win32OpenSSH
Copy-OpenSSLSDK
$msbuildCmd = "msbuild.exe"
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
$cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
@ -380,4 +414,4 @@ function Get-RepositoryRoot
throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository")
}
Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile
Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile, Clone-Win32OpenSSH, Copy-OpenSSLSDK

View File

@ -876,7 +876,7 @@
/* #undef HAVE_SET_ID */
/* Define to 1 if you have the `SHA256_Update' function. */
#define HAVE_SHA256_UPDATE 1
/* #undef HAVE_SHA256_UPDATE */
/* Define to 1 if you have the <sha2.h> header file. */
/* #undef HAVE_SHA2_H */

View File

@ -1,11 +1,15 @@
$scriptpath = $MyInvocation.MyCommand.Path
# @manojampalam - authored initial script
# @friism - Fixed issue with invalid SDDL on Set-Acl
$scriptpath = $MyInvocation.MyCommand.Path
$scriptdir = Split-Path $scriptpath
$sshdpath = Join-Path $scriptdir "sshd.exe"
$sshagentpath = Join-Path $scriptdir "ssh-agent.exe"
$logsdir = Join-Path $scriptdir "logs"
$ntrights = "ntrights.exe -u `"NT SERVICE\SSHD`" +r SeAssignPrimaryTokenPrivilege"
$account = "NT SERVICE\SSHD"
$ntrights = "ntrights.exe -u `"{0}`" +r SeAssignPrimaryTokenPrivilege" -f $account
if (-not (Test-Path $sshdpath)) {
throw "sshd.exe is not present in script path"
@ -27,7 +31,7 @@ New-Service -Name ssh-agent -BinaryPathName $sshagentpath -Description "SSH Agen
cmd.exe /c 'sc.exe sdset ssh-agent D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)'
New-Service -Name sshd -BinaryPathName $sshdpath -Description "SSH Deamon" -StartupType Manual -DependsOn ssh-agent | Out-Null
sc.exe config sshd obj= "NT SERVICE\SSHD"
sc.exe config sshd obj= $account
Push-Location
cd $scriptdir
@ -35,9 +39,9 @@ cmd.exe /c $ntrights
Pop-Location
mkdir $logsdir > $null
$sddl = "O:SYG:DUD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x12019f;;;S-1-5-80-3847866527-469524349-687026318-516638107-1125189541)"
$rights = [System.Security.AccessControl.FileSystemRights]"Read, Write"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($account, $rights, "ContainerInherit,ObjectInherit", "None", "Allow")
$acl = Get-Acl -Path $logsdir
$acl.SetSecurityDescriptorSddlForm($sddl)
$Acl.SetAccessRule($accessRule)
Set-Acl -Path $logsdir -AclObject $acl
Write-Host -ForegroundColor Green "sshd and ssh-agent services successfully installed"

View File

@ -194,7 +194,7 @@
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)digest-libc.c">
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="$(UseOpenSSL)==true">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)dispatch.c" />
<ClCompile Include="$(OpenSSH-Src-Path)dns.c" />
@ -285,7 +285,9 @@
<ClCompile Include="$(OpenSSH-Src-Path)sandbox-pledge.c" />
<ClCompile Include="$(OpenSSH-Src-Path)utf8.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\ttymodes_windows.c" />
<ClCompile Include="..\..\..\digest-openssl.c" />
<ClCompile Include="$(OpenSSH-Src-Path)digest-openssl.c">
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)crypto-wrap.h" />

Binary file not shown.

View File

@ -155,11 +155,11 @@
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_dirent.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\no-ops.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_zlib.c" />
<ClCompile Include="..\win32compat\ansiprsr.c" />
<ClCompile Include="..\win32compat\conio.c" />
<ClCompile Include="..\win32compat\console.c" />
<ClCompile Include="..\win32compat\tncon.c" />
<ClCompile Include="..\win32compat\tnnet.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ansiprsr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\conio.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
@ -198,6 +198,7 @@
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\termios.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\dirent.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\misc_internal.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -117,6 +117,7 @@
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
<ClInclude Include="..\win32compat\misc_internal.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="inc">

View File

@ -199,9 +199,14 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
return -1;
}
cf_flags->dwShareMode = 0;
switch (rwflags) {
case O_RDONLY:
cf_flags->dwDesiredAccess = GENERIC_READ;
/*todo: need to review to make sure all flags are correct*/
if (flags & O_NONBLOCK)
cf_flags->dwShareMode = FILE_SHARE_READ;
break;
case O_WRONLY:
cf_flags->dwDesiredAccess = GENERIC_WRITE;
@ -211,8 +216,6 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
break;
}
cf_flags->dwShareMode = 0;
cf_flags->securityAttributes.lpSecurityDescriptor = NULL;
cf_flags->securityAttributes.bInheritHandle = TRUE;
cf_flags->securityAttributes.nLength = 0;
@ -230,7 +233,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
if (c_s_flags & O_APPEND)
cf_flags->dwDesiredAccess = FILE_APPEND_DATA;
cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION;
cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION | FILE_FLAG_BACKUP_SEMANTICS;
/*TODO - map mode */

View File

@ -159,3 +159,6 @@ explicit_bzero(void *b, size_t len);
#define fopen w32_fopen_utf8
#define popen _popen
#define pclose _pclose
void convertToBackslash(char *str);
void convertToForwardslash(char *str);

View File

@ -36,6 +36,7 @@
#include "inc\sys\time.h"
#include <time.h>
#include <Shlwapi.h>
#include "misc_internal.h"
int usleep(unsigned int useconds)
{
@ -302,11 +303,25 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) {
PROCESS_INFORMATION pi;
STARTUPINFOW si;
BOOL b;
char* abs_cmd;
char *abs_cmd, *t;
wchar_t * cmd_utf16;
int add_module_path = 0;
/* relative ? if so, add current module path to start */
if (!(cmd && cmd[0] != '\0' && (cmd[1] == ':' || cmd[0] == '\\' || cmd[0] == '.'))) {
/* should module path be added */
do{
if(!cmd)
break;
t = cmd;
if (*t == '\"')
t++;
if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
break;
add_module_path = 1;
} while (0);
/* add current module path to start if needed */
if (add_module_path) {
char* ctr;
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1);
if (abs_cmd == NULL) {
@ -478,8 +493,6 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group) {
return -1;
}
char *realpath_win(const char *path, char resolved[MAX_PATH]);
int
w32_utimes(const char *filename, struct timeval *tvp) {
struct utimbuf ub;
@ -487,10 +500,7 @@ w32_utimes(const char *filename, struct timeval *tvp) {
ub.modtime = tvp[1].tv_sec;
int ret;
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(filename, resolvedPathName);
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename));
if (resolvedPathName_utf16 == NULL) {
errno = ENOMEM;
return -1;
@ -517,16 +527,9 @@ link(const char *oldpath, const char *newpath) {
int
w32_rename(const char *old_name, const char *new_name) {
// Skip the first '/' in the pathname
char resolvedOldPathName[MAX_PATH];
realpath_win(old_name, resolvedOldPathName);
// Skip the first '/' in the pathname
char resolvedNewPathName[MAX_PATH];
realpath_win(new_name, resolvedNewPathName);
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(resolvedOldPathName);
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(resolvedNewPathName);
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(sanitized_path(old_name));
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(sanitized_path(new_name));
if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) {
errno = ENOMEM;
return -1;
@ -541,11 +544,8 @@ w32_rename(const char *old_name, const char *new_name) {
int
w32_unlink(const char *path) {
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(path, resolvedPathName);
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
if (NULL == resolvedPathName_utf16) {
errno = ENOMEM;
return -1;
@ -559,11 +559,7 @@ w32_unlink(const char *path) {
int
w32_rmdir(const char *path) {
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(path, resolvedPathName);
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
if (NULL == resolvedPathName_utf16) {
errno = ENOMEM;
return -1;
@ -606,11 +602,8 @@ w32_getcwd(char *buffer, int maxlen) {
int
w32_mkdir(const char *path_utf8, unsigned short mode) {
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(path_utf8, resolvedPathName);
wchar_t *path_utf16 = utf8_to_utf16(resolvedPathName);
wchar_t *path_utf16 = utf8_to_utf16(sanitized_path(path_utf8));
if (path_utf16 == NULL) {
errno = ENOMEM;
return -1;
@ -621,86 +614,62 @@ w32_mkdir(const char *path_utf8, unsigned short mode) {
return returnStatus;
}
void
getrnd(u_char *s, size_t len) {
HCRYPTPROV hProvider;
if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT) == FALSE ||
CryptGenRandom(hProvider, len, s) == FALSE ||
CryptReleaseContext(hProvider, 0) == FALSE)
DebugBreak();
}
int
w32_stat(const char *path, struct w32_stat *buf) {
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(path, resolvedPathName);
return fileio_stat(resolvedPathName, (struct _stat64*)buf);
return fileio_stat(sanitized_path(path), (struct _stat64*)buf);
}
// if file is symbolic link, copy its link into "link" .
int
readlink(const char *path, char *link, int linklen)
{
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(path, resolvedPathName);
strcpy_s(link, linklen, resolvedPathName);
strcpy_s(link, linklen, sanitized_path(path));
return 0;
}
// convert forward slash to back slash
void
convertToBackslash(char *str) {
while (*str) {
if (*str == '/')
*str = '\\';
str++;
}
}
// convert back slash to forward slash
void
convertToForwardslash(char *str) {
while (*str) {
if (*str == '\\')
*str = '/';
str++;
}
}
/*
* This method will expands all symbolic links and resolves references to /./,
* /../ and extra '/' characters in the null-terminated string named by
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
* path to produce a canonicalized absolute pathname.
*/
char *
realpath(const char *path, char resolved[MAX_PATH])
{
realpath(const char *path, char resolved[MAX_PATH]) {
char tempPath[MAX_PATH];
if ((0 == strcmp(path, "./")) || (0 == strcmp(path, "."))) {
tempPath[0] = '/';
_getcwd(&tempPath[1], sizeof(tempPath) - 1);
slashconvert(tempPath);
strncpy(resolved, tempPath, strlen(tempPath) + 1);
return resolved;
}
if (path[0] != '/')
strlcpy(resolved, path, sizeof(tempPath));
if (*path == '/' && *(path + 2) == ':')
strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
else
strlcpy(resolved, path + 1, sizeof(tempPath));
strncpy(resolved, path, strlen(path) + 1);
backslashconvert(resolved);
PathCanonicalizeA(tempPath, resolved);
slashconvert(tempPath);
// Store terminating slash in 'X:/' on Windows.
if (tempPath[1] == ':' && tempPath[2] == 0) {
tempPath[2] = '/';
tempPath[3] = 0;
}
if (_fullpath(tempPath, resolved, MAX_PATH) == NULL)
return NULL;
convertToForwardslash(tempPath);
resolved[0] = '/'; // will be our first slash in /x:/users/test1 format
strncpy(resolved + 1, tempPath, sizeof(tempPath) - 1);
return resolved;
}
// like realpathWin32() but takes out the first slash so that windows systems can work on the actual file or directory
char *
realpath_win(const char *path, char resolved[MAX_PATH])
{
char tempPath[MAX_PATH];
realpath(path, tempPath);
strncpy(resolved, &tempPath[1], sizeof(tempPath) - 1);
return resolved;
}
// Maximum reparse buffer info size. The max user defined reparse
// data is 16KB, plus there's a header.
#define MAX_REPARSE_SIZE 17000
@ -737,8 +706,7 @@ typedef struct _REPARSE_DATA_BUFFER {
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
BOOL
ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags)
{
ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) {
HANDLE fileHandle;
BYTE reparseBuffer[MAX_REPARSE_SIZE];
PBYTE reparseData;

View 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))

View File

@ -231,32 +231,6 @@ char *user_from_uid(uid_t uid, int nouser) {
return "-";
}
/* TODO - this is moved from realpath.c in openbsdcompat. Review and finalize its position*/
#include <Shlwapi.h>
void backslashconvert(char *str)
{
while (*str) {
if (*str == '/')
*str = '\\'; // convert forward slash to back slash
str++;
}
}
// convert back slash to forward slash
void slashconvert(char *str)
{
while (*str) {
if (*str == '\\')
*str = '/'; // convert back slash to forward slash
str++;
}
}
uid_t
getuid(void) {
return 0;

View File

@ -40,6 +40,7 @@
#include <winioctl.h>
#include "Shlwapi.h"
#include <sys\utime.h>
#include "misc_internal.h"
/* internal table that stores the fd to w32_io mapping*/
struct w32fd_table {
@ -347,7 +348,7 @@ w32_pipe(int *pfds) {
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
return 0;
}
char *realpath_win(const char *path, char resolved[MAX_PATH]);
int
w32_open(const char *pathname, int flags, ...) {
int min_index = fd_table_get_min_index();
@ -357,18 +358,14 @@ w32_open(const char *pathname, int flags, ...) {
if (min_index == -1)
return -1;
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(pathname, resolvedPathName);
pio = fileio_open(resolvedPathName, flags, 0);
pio = fileio_open(sanitized_path(pathname), flags, 0);
if (pio == NULL)
return -1;
pio->type = NONSOCK_FD;
fd_table_set(pio, min_index);
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
debug3("open - path:%s", resolvedPathName);
debug3("open - path:%s", pathname);
return min_index;
}

View File

@ -11,6 +11,7 @@
#include "inc\dirent.h"
#include "inc\libgen.h"
#include "misc_internal.h"
struct DIR_ {
@ -19,8 +20,6 @@ struct DIR_ {
int first;
};
char * realpath_win(const char *path, char resolved[MAX_PATH]);
/* Open a directory stream on NAME.
Return a DIR stream on the directory, or NULL if it could not be opened. */
DIR * opendir(const char *name)
@ -32,11 +31,7 @@ DIR * opendir(const char *name)
wchar_t* wname = NULL;
int needed;
// Skip the first '/' in the pathname
char resolvedPathName[MAX_PATH];
realpath_win(name, resolvedPathName);
if ((wname = utf8_to_utf16(resolvedPathName)) == NULL) {
if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) {
errno = ENOMEM;
return NULL;
}

4
dh.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: dh.c,v 1.61 2016/09/12 01:22:38 deraadt Exp $ */
/* $OpenBSD: dh.c,v 1.62 2016/12/15 21:20:41 dtucker Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
@ -152,7 +152,7 @@ choose_dh(int min, int wantbits, int max)
struct dhgroup dhg;
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
logit("WARNING: could open open %s (%s), using fixed modulus",
logit("WARNING: could not open %s (%s), using fixed modulus",
_PATH_DH_MODULI, strerror(errno));
return (dh_new_group_fallback(max));
}

1
log.c
View File

@ -446,7 +446,6 @@ do_log(LogLevel level, const char *fmt, va_list args)
}
strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
if (log_handler != NULL) {
/* Avoid recursion */
tmp_handler = log_handler;

2
misc.c
View File

@ -432,7 +432,6 @@ char *
colon(char *cp)
{
int flag = 0;
int len = 0;
if (*cp == ':') /* Leading colon is part of file name. */
return NULL;
@ -627,6 +626,7 @@ tilde_expand_filename(const char *filename, uid_t uid)
if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
fatal("tilde_expand_filename: Path too long");
return (ret);
}

View File

@ -78,6 +78,18 @@ _rs_init(u_char *buf, size_t n)
}
#ifndef WITH_OPENSSL
#ifdef WINDOWS
#include <Wincrypt.h>
static void
getrnd(u_char *s, size_t len) {
HCRYPTPROV hProvider;
if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT) == FALSE ||
CryptGenRandom(hProvider, len, s) == FALSE ||
CryptReleaseContext(hProvider, 0) == FALSE)
DebugBreak();
}
#else /* !WINDOWS */
#define SSH_RANDOM_DEV "/dev/urandom"
/* XXX use getrandom() if supported on Linux */
static void
@ -101,6 +113,7 @@ getrnd(u_char *s, size_t len)
}
close(fd);
}
#endif /* !WINDOWS */
#endif
static void

View File

@ -469,6 +469,7 @@ default_ssh_port(void)
static int
execute_in_shell(const char *cmd)
{
char *shell;
#ifdef WINDOWS
fatal("LocalCommand execution is not supported on Windows yet");
return 0;
@ -1725,6 +1726,7 @@ read_config_file_depth(const char *filename, struct passwd *pw,
fatal("Bad owner or permissions on %s", filename);
}
#endif /* !WINDOWS */
debug("Reading configuration data %.200s", filename);
/*

View File

@ -145,6 +145,8 @@ read_passphrase(const char *prompt, int flags)
/* prompt user */
wchar_t* wtmp = utf8_to_utf16(prompt);
if (wtmp == NULL)
fatal("unable to alloc memory");
_cputws(wtmp);
free(wtmp);
@ -158,28 +160,28 @@ read_passphrase(const char *prompt, int flags)
buf[len] = (unsigned char)_getch();
if (buf[len] == '\r') {
if (_kbhit())
_getch(); // read linefeed if its there
if (_kbhit()) /* read linefeed if its there */
_getch();
break;
}
else if (buf[len] == '\n') {
break;
}
else if (buf[len] == '\b') { // backspace
else if (buf[len] == '\b') { /* backspace */
if (len > 0)
len--; // overwrite last character
len--; /* overwrite last character */
}
else if (buf[len] == '\003') {
/* exit on Ctrl+C */
fatal("");
}
else {
len++; // keep reading in the loop
len++; /* keep reading in the loop */
}
}
buf[len] = '\0'; // get rid of the cr/lf
_cputs("\n"); // show a newline as we do not echo password or the line
buf[len] = '\0'; /* get rid of the cr/lf */
_cputs("\n"); /*show a newline as we do not echo password or the line */
ret = xstrdup(buf);
@ -188,7 +190,6 @@ read_passphrase(const char *prompt, int flags)
return ret;
#else /* !WINDOWS */
char *askpass = NULL, *ret, buf[1024];
int rppflags, use_askpass = 0, ttyfd;
@ -235,9 +236,7 @@ read_passphrase(const char *prompt, int flags)
ret = xstrdup(buf);
explicit_bzero(buf, sizeof(buf));
return ret;
#endif /* !WINDOWS */
}
int

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.93 2016/11/01 13:43:27 tb Exp $
# $OpenBSD: Makefile,v 1.94 2016/12/16 03:51:19 dtucker Exp $
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
tests: prep $(REGRESS_TARGETS)
@ -78,7 +78,8 @@ LTESTS= connect \
hostkey-rotate \
principals-command \
cert-file \
cfginclude
cfginclude \
allow-deny-users
# dhgex \

View 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"

View File

@ -1,4 +1,4 @@
# $OpenBSD: cert-file.sh,v 1.2 2015/09/24 07:15:39 djm Exp $
# $OpenBSD: cert-file.sh,v 1.4 2016/12/16 02:48:55 djm Exp $
# Placed in the Public Domain.
tid="ssh with certificates"

View File

@ -1,4 +1,4 @@
# $OpenBSD: login-timeout.sh,v 1.7 2014/03/13 20:44:49 djm Exp $
# $OpenBSD: login-timeout.sh,v 1.8 2016/12/16 01:06:27 dtucker Exp $
# Placed in the Public Domain.
tid="connect after login grace timeout"
@ -17,7 +17,7 @@ if [ $? -ne 0 ]; then
fail "ssh connect after login grace timeout failed with privsep"
fi
$SUDO kill `$SUDO cat $PIDFILE`
stop_sshd
trace "test login grace without privsep"
echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config

View File

@ -26,13 +26,12 @@ Describe "Tests for scp command" -Tags "CI" {
$client.SetupClient($server)
$server.SetupServer($client)
$testData = @(
<# known issue 340
$testData = @(
@{
Title = 'Simple copy local file to local file'
Source = $SourceFilePath
Destination = $DestinationFilePath
},#>
},
@{
Title = 'Simple copy local file to remote file'
Source = $SourceFilePath
@ -42,13 +41,12 @@ Describe "Tests for scp command" -Tags "CI" {
Title = 'Simple copy remote file to local file'
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
Destination = $DestinationFilePath
},
<# known issue 340
},
@{
Title = 'Simple copy local file to local dir'
Source = $SourceFilePath
Destination = $DestinationDir
},#>
},
@{
Title = 'simple copy local file to remote dir'
Source = $SourceFilePath
@ -66,7 +64,7 @@ Describe "Tests for scp command" -Tags "CI" {
Title = 'copy from local dir to remote dir'
Source = $sourceDir
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir"
},
},
@{
Title = 'copy from local dir to local dir'
Source = $sourceDir
@ -84,16 +82,16 @@ Describe "Tests for scp command" -Tags "CI" {
$client.CleanupClient()
$server.CleanupServer()
Get-Item $SourceDir | Remove-Item -Recurse -Force -ea silentlycontinue
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ea silentlycontinue
Get-Item $SourceDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
BeforeEach {
BeforeAll {
$null = New-Item $DestinationDir -ItemType directory -Force
}
AfterEach {
Get-ChildItem $DestinationDir -Recurse -Directory | Remove-Item -Recurse -Force -ea silentlycontinue
Get-ChildItem $DestinationDir -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
<#Context "SCP usage" {
@ -121,7 +119,7 @@ Describe "Tests for scp command" -Tags "CI" {
$equal | Should Be $true
}
<#It 'Directory recursive Copy with -i option: <Title> ' -TestCases:$testData1 {
It 'Directory recursive Copy with -i option: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -r -i $identifyFile $Source $Destination
@ -129,10 +127,10 @@ Describe "Tests for scp command" -Tags "CI" {
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
#known issue 364
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
#$equal | Should Be $true
}#>
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
}
#this context only run on windows
@ -149,37 +147,34 @@ Describe "Tests for scp command" -Tags "CI" {
#cleanup single signon
.\ssh-add.exe -D
}
}
It 'File Copy with -S option (positive)' {
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
#validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 #todo: add LastWriteTime in comparison when issue is fixed
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
<#It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData {
It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination)
.\scp -p -c aes128-ctr -C $Source $Destination #Todo: add -v after it is supported.
.\scp -p -c aes128-ctr -v -C $Source $Destination
#validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 #todo: add LastWriteTime in comparison when issue is fixed
$equal | Should Be $true
}#>
<# known issue 369
It 'Directory recursive Copy with -v option: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -r -p $Source $Destination
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
It 'Directory recursive Copy with -r -p -v option: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -r -p -c aes128-ctr -v $Source $Destination
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime).Length -eq 0
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
#known issue 364
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime).Length -eq 0
#$equal | Should Be $true
}#>
}
}
Context "Key based authentication with -i -C -q options. host keys are not secured on server" {
@ -192,23 +187,20 @@ Describe "Tests for scp command" -Tags "CI" {
.\scp -i $identifyFile -C -q $Source $Destination
#validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 # need to validate LastWriteTime after issue 356 is fixed.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
<#It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile -r -q $Source $Destination
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
#known issue 364
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
#$equal | Should Be $true
}#>
}
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
}
}

View File

@ -1,4 +1,4 @@
# $OpenBSD: reexec.sh,v 1.8 2015/03/03 22:35:19 markus Exp $
# $OpenBSD: reexec.sh,v 1.10 2016/12/16 01:06:27 dtucker Exp $
# Placed in the Public Domain.
tid="reexec tests"
@ -39,8 +39,7 @@ echo "InvalidXXX=no" >> $OBJ/sshd_config
copy_tests
$SUDO kill `$SUDO cat $PIDFILE`
rm -f $PIDFILE
stop_sshd
cp $OBJ/sshd_config.orig $OBJ/sshd_config
@ -54,8 +53,7 @@ rm -f $SSHD_COPY
copy_tests
$SUDO kill `$SUDO cat $PIDFILE`
rm -f $PIDFILE
stop_sshd
verbose "test reexec fallback without privsep"
@ -67,7 +65,6 @@ rm -f $SSHD_COPY
copy_tests
$SUDO kill `$SUDO cat $PIDFILE`
rm -f $PIDFILE
stop_sshd
fi

View File

@ -1,4 +1,4 @@
# $OpenBSD: test-exec.sh,v 1.57 2016/11/25 03:02:01 dtucker Exp $
# $OpenBSD: test-exec.sh,v 1.58 2016/12/16 01:06:27 dtucker Exp $
# Placed in the Public Domain.
#SUDO=sudo
@ -293,16 +293,8 @@ md5 () {
}
# End of portable specific functions
# helper
cleanup ()
stop_sshd ()
{
if [ "x$SSH_PID" != "x" ]; then
if [ $SSH_PID -lt 2 ]; then
echo bad pid for ssh: $SSH_PID
else
kill $SSH_PID
fi
fi
if [ -f $PIDFILE ]; then
pid=`$SUDO cat $PIDFILE`
if [ "X$pid" = "X" ]; then
@ -325,6 +317,19 @@ cleanup ()
fi
}
# helper
cleanup ()
{
if [ "x$SSH_PID" != "x" ]; then
if [ $SSH_PID -lt 2 ]; then
echo bad pid for ssh: $SSH_PID
else
kill $SSH_PID
fi
fi
stop_sshd
}
start_debug_log ()
{
echo "trace: $@" >$TEST_REGRESS_LOGFILE

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tests.c,v 1.2 2016/05/30 12:05:56 schwarze Exp $ */
/* $OpenBSD: tests.c,v 1.3 2016/12/19 04:55:18 djm Exp $ */
/*
* Regress test for the utf8.h *mprintf() API
*
@ -69,7 +69,6 @@ tests(void)
TEST_DONE();
badarg();
one("null", NULL, 8, 6, 6, "(null)");
one("empty", "", 2, 0, 0, "");
one("ascii", "x", -2, -2, -2, "x");
one("newline", "a\nb", -2, -2, -2, "a\nb");

View File

@ -31,6 +31,7 @@
#include "log.h"
#include "sandbox.h"
#include "monitor.h"
#include "xmalloc.h"
/* Darwin/OS X sandbox */

120
scp.c
View File

@ -214,7 +214,7 @@ do_local_cmd(arglist *a)
return 0;
}
#else
#else /* !WINDOWS */
if ((pid = fork()) == -1)
fatal("do_local_cmd: fork: %s", strerror(errno));
@ -239,7 +239,7 @@ do_local_cmd(arglist *a)
return (-1);
return (0);
#endif
#endif /* !WINDOWS */
}
/*
@ -282,6 +282,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
/* Fork a child to execute the command on the remote host using ssh. */
#ifdef WINDOWS
/* generate command line and spawn_child */
replacearg(&args, 0, "%s", ssh_program);
if (remuser != NULL) {
addargs(&args, "-l");
@ -314,11 +315,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
do_cmd_pid = spawn_child(full_cmd, pin[0], pout[1], STDERR_FILENO, 0);
free(full_cmd);
}
#else
#else /* !WINDOWS */
do_cmd_pid = fork();
#endif
#endif /* !WINDOWS */
if (do_cmd_pid == 0) {
/* Child. */
close(pin[1]);
@ -373,6 +372,7 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
/* Fork a child to execute the command on the remote host using ssh. */
#ifdef WINDOWS
/* generate command line and spawn_child */
replacearg(&args, 0, "%s", ssh_program);
if (remuser != NULL) {
addargs(&args, "-l");
@ -403,10 +403,10 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
pid = spawn_child(full_cmd, fdin, fdout, STDERR_FILENO, 0);
free(full_cmd);
}
#else
}
#else /* !WINDOWS */
pid = fork();
#endif
#endif /* !WINDOWS */
if (pid == 0) {
dup2(fdin, 0);
dup2(fdout, 1);
@ -592,6 +592,18 @@ main(int argc, char **argv)
remin = STDIN_FILENO;
remout = STDOUT_FILENO;
#ifdef WINDOWS
/*
* To support both Windows and Unix style paths
* convert '\\' to '/' in rest of arguments
*/
{
int i;
for (i = 0; i < argc; i++)
convertToForwardslash(argv[i]);
}
#endif /* WINDOWS */
if (fflag) {
/* Follow "protocol", send data. */
(void) response();
@ -807,6 +819,41 @@ tolocal(int argc, char **argv)
for (i = 0; i < argc - 1; i++) {
if (!(src = colon(argv[i]))) { /* Local to local. */
freeargs(&alist);
#ifdef WINDOWS
#define _PATH_XCOPY "xcopy"
#define _PATH_COPY "copy"
/* local to local on windows - need to use local native copy command */
struct stat stb;
int exists;
char *last;
exists = stat(argv[i], &stb) == 0;
/* convert '/' to '\\' */
convertToBackslash(argv[i]);
convertToBackslash(argv[argc - 1]);
if (exists && (S_ISDIR(stb.st_mode))) {
addargs(&alist, "%s", _PATH_XCOPY);
if (iamrecursive)
addargs(&alist, "/S /E /H");
if (pflag)
addargs(&alist, "/K /X");
addargs(&alist, "/Y /F /I");
addargs(&alist, "%s", argv[i]);
if ((last = strrchr(argv[i], '\\')) == NULL)
last = argv[i];
else
++last;
addargs(&alist, "%s%s%s", argv[argc - 1],
strcmp(argv[argc - 1], "\\") ? "\\" : "", last);
} else {
addargs(&alist, "%s", _PATH_COPY);
addargs(&alist, "/Y");
addargs(&alist, "%s", argv[i]);
addargs(&alist, "%s", argv[argc - 1]);
}
#else /* !WINDOWS */
addargs(&alist, "%s", _PATH_CP);
if (iamrecursive)
addargs(&alist, "-r");
@ -815,6 +862,7 @@ tolocal(int argc, char **argv)
addargs(&alist, "--");
addargs(&alist, "%s", argv[i]);
addargs(&alist, "%s", argv[argc-1]);
#endif /* !WINDOWS */
if (do_local_cmd(&alist))
++errs;
continue;
@ -892,26 +940,10 @@ syserr: run_err("%s: %s", name, strerror(errno));
run_err("%s: not a regular file", name);
goto next;
}
#ifdef WINDOWS
/* account for both slashes on Windows */
{
char *lastf = NULL, *lastr = NULL;
if ((lastf = strrchr(name, '/')) == NULL && (lastr = strrchr(name, '\\')) == NULL)
last = name;
else {
if (lastf)
last = lastf;
if (lastr)
last = lastr;
++last;
}
}
#else
if ((last = strrchr(name, '/')) == NULL)
last = name;
else
++last;
#endif
curfile = last;
if (pflag) {
if (do_times(remout, verbose_mode, &stb) < 0)
@ -1000,16 +1032,16 @@ rsource(char *name, struct stat *statp)
(u_int) (statp->st_mode & FILEMODEMASK), 0, last);
if (verbose_mode)
#ifdef WINDOWS
/* TODO - make fmprintf work for Windows */
{
printf("Entering directory: ");
wchar_t* wtmp = utf8_to_utf16(path);
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
free(wtmp);
}
#else
/* TODO - make fmprintf work for Windows */
{
printf("Entering directory: ");
wchar_t* wtmp = utf8_to_utf16(path);
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
free(wtmp);
}
#else /* !WINDOWS */
fmprintf(stderr, "Entering directory: %s", path);
#endif
#endif /* !WINDOWS */
(void) atomicio(vwrite, remout, path, strlen(path));
if (response() < 0) {
closedir(dirp);
@ -1085,16 +1117,17 @@ sink(int argc, char **argv)
*cp = 0;
if (verbose_mode)
#ifdef WINDOWS
/* TODO - make fmprintf work for Windows */
{
printf("Sink: ");
wchar_t* wtmp = utf8_to_utf16(buf);
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
free(wtmp);
}
#else
/* TODO - make fmprintf work for Windows */
{
printf("Sink: ");
wchar_t* wtmp = utf8_to_utf16(buf);
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
free(wtmp);
}
#else /* !WINDOWS */
fmprintf(stderr, "Sink: %s", buf);
#endif
#endif /* !WINDOWS */
if (buf[0] == '\01' || buf[0] == '\02') {
if (iamremote == 0) {
(void) snmprintf(visbuf, sizeof(visbuf),
@ -1496,3 +1529,4 @@ lostconn(int signo)
else
exit(1);
}

View File

@ -606,7 +606,7 @@ derelativise_path(const char *path)
expanded = tilde_expand_filename(path, getuid());
#ifdef WINDOWS
/* Windows absolute paths have a drive letter followed by :*/
if (expanded[1] == ':')
if (*expanded != '\0' && expanded[1] == ':')
#else /* !WINDOWS */
if (*expanded == '/')
#endif /* !WINDOWS */

552
session.c
View File

@ -183,8 +183,8 @@ static int
auth_input_request_forwarding(struct passwd * pw)
{
#ifdef WINDOWS
packet_send_debug("Agent forwarding not supported yet in Windows");
return 0;
packet_send_debug("Agent forwarding not supported yet in Windows");
return 0;
#else /* !WINDOWS */
Channel *nc;
int sock = -1;
@ -296,7 +296,7 @@ xauth_valid_string(const char *s)
* do_exec* on Windows
* - Read and set user environment variables from registry
* - Build subsystem cmdline path
* - Interative shell/commands are executed using ssh-shellhost.exe
* - Interactive shell/commands are executed using ssh-shellhost.exe
* - ssh-shellhost.exe implements server-side PTY for Windows
*/
#include <Shlobj.h>
@ -312,360 +312,336 @@ xauth_valid_string(const char *s)
void setup_session_vars(Session* s)
{
wchar_t* pw_dir_w;
wchar_t* tmp;
char buf[128];
char* laddr;
wchar_t* pw_dir_w;
wchar_t* tmp;
char buf[128];
char* laddr;
struct ssh *ssh = active_state; /* XXX */
struct ssh *ssh = active_state; /* XXX */
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
fatal("%s: out of memory");
if ((tmp = utf8_to_utf16(s->pw->pw_name)) == NULL)
fatal("%s, out of memory");
SetEnvironmentVariableW(L"USERNAME", tmp);
free(tmp);
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
fatal("%s: out of memory");
if (s->display)
SetEnvironmentVariableA("DISPLAY", s->display);
if ((tmp = utf8_to_utf16(s->pw->pw_name)) == NULL)
fatal("%s, out of memory");
SetEnvironmentVariableW(L"USERNAME", tmp);
free(tmp);
if (s->display)
SetEnvironmentVariableA("DISPLAY", s->display);
SetEnvironmentVariableW(L"HOMEPATH", pw_dir_w);
SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w);
SetEnvironmentVariableW(L"HOMEPATH", pw_dir_w);
SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w);
if (pw_dir_w[1] == L':') {
wchar_t wc = pw_dir_w[2];
pw_dir_w[2] = L'\0';
SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w);
pw_dir_w[2] = wc;
}
if (pw_dir_w[1] == L':') {
wchar_t wc = pw_dir_w[2];
pw_dir_w[2] = L'\0';
SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w);
pw_dir_w[2] = wc;
}
snprintf(buf, sizeof buf, "%.50s %d %d",
ssh->remote_ipaddr, ssh->remote_port, ssh->local_port);
snprintf(buf, sizeof buf, "%.50s %d %d",
ssh->remote_ipaddr, ssh->remote_port, ssh->local_port);
SetEnvironmentVariableA("SSH_CLIENT", buf);
SetEnvironmentVariableA("SSH_CLIENT", buf);
laddr = get_local_ipaddr(packet_get_connection_in());
laddr = get_local_ipaddr(packet_get_connection_in());
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
ssh->remote_ipaddr, ssh->remote_port, laddr, ssh->local_port);
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
ssh->remote_ipaddr, ssh->remote_port, laddr, ssh->local_port);
free(laddr);
free(laddr);
SetEnvironmentVariableA("SSH_CONNECTION", buf);
SetEnvironmentVariableA("SSH_CONNECTION", buf);
if (original_command)
SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command);
if (original_command)
SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command);
if ((s->term) && (s->term[0]))
SetEnvironmentVariable("TERM", s->term);
if ((s->term) && (s->term[0]))
SetEnvironmentVariable("TERM", s->term);
if (!s->is_subsystem) {
snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME"));
SetEnvironmentVariableA("PROMPT", buf);
}
if (!s->is_subsystem) {
snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME"));
SetEnvironmentVariableA("PROMPT", buf);
}
/*set user environment variables*/
{
UCHAR InfoBuffer[1000];
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
DWORD dwInfoBufferSize, tmp_len;
LPWSTR sid_str = NULL;
wchar_t reg_path[MAX_PATH];
HKEY reg_key = 0;
HANDLE token = s->authctxt->methoddata;
tmp_len = MAX_PATH;
if (GetTokenInformation(token, TokenUser, InfoBuffer,
1000, &dwInfoBufferSize) == FALSE ||
ConvertSidToStringSidW(pTokenUser->User.Sid, &sid_str) == FALSE ||
swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_str) == MAX_PATH ||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)pw_dir_w, &tmp_len) != 0) {
/* one of the above failed */
debug("cannot retirve profile path - perhaps user profile is not created yet");
}
/*set user environment variables*/
{
UCHAR InfoBuffer[1000];
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
DWORD dwInfoBufferSize, tmp_len;
LPWSTR sid_str = NULL;
wchar_t reg_path[MAX_PATH];
HKEY reg_key = 0;
HANDLE token = s->authctxt->methoddata;
tmp_len = MAX_PATH;
if (GetTokenInformation(token, TokenUser, InfoBuffer,
1000, &dwInfoBufferSize) == FALSE ||
ConvertSidToStringSidW(pTokenUser->User.Sid, &sid_str) == FALSE ||
swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_str) == MAX_PATH ||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)pw_dir_w, &tmp_len) != 0) {
/* one of the above failed */
debug("cannot retirve profile path - perhaps user profile is not created yet");
}
if (sid_str)
LocalFree(sid_str);
if (sid_str)
LocalFree(sid_str);
if (reg_key)
RegCloseKey(reg_key);
{ /* retrieve and set env variables. */
/* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/
if (reg_key)
RegCloseKey(reg_key);
/* retrieve and set env variables. */
{
#define MAX_VALUE_LEN 1000
#define MAX_DATA_LEN 2000
#define MAX_EXPANDED_DATA_LEN 5000
wchar_t *path;
wchar_t value_name[MAX_VALUE_LEN];
wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply;
DWORD value_type, name_len, data_len;
int i;
LONG ret;
/* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/
wchar_t *path;
wchar_t value_name[MAX_VALUE_LEN];
wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply;
DWORD value_type, name_len, data_len;
int i;
LONG ret;
if (ImpersonateLoggedOnUser(token) == FALSE)
debug("Failed to impersonate user token, %d", GetLastError());
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
reg_key = 0;
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS) {
i = 0;
while (1) {
name_len = MAX_VALUE_LEN * 2;
data_len = MAX_DATA_LEN * 2;
to_apply = NULL;
if (RegEnumValueW(reg_key, i++, value_name, &name_len, 0, &value_type, (LPBYTE)&value_data, &data_len) != ERROR_SUCCESS)
break;
if (value_type == REG_SZ)
to_apply = value_data;
else if (value_type == REG_EXPAND_SZ) {
ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN);
to_apply = value_data_expanded;
}
if (ImpersonateLoggedOnUser(token) == FALSE)
debug("Failed to impersonate user token, %d", GetLastError());
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
reg_key = 0;
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS) {
i = 0;
while (1) {
name_len = MAX_VALUE_LEN * 2;
data_len = MAX_DATA_LEN * 2;
to_apply = NULL;
if (RegEnumValueW(reg_key, i++, value_name, &name_len, 0, &value_type, (LPBYTE)&value_data, &data_len) != ERROR_SUCCESS)
break;
if (value_type == REG_SZ)
to_apply = value_data;
else if (value_type == REG_EXPAND_SZ) {
ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN);
to_apply = value_data_expanded;
}
if (wcsicmp(value_name, L"PATH") == 0) {
DWORD size;
if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) {
memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2);
GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN);
value_data_expanded[size - 1] = L';';
to_apply = value_data_expanded;
}
if (wcsicmp(value_name, L"PATH") == 0) {
DWORD size;
if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) {
memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2);
GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN);
value_data_expanded[size - 1] = L';';
to_apply = value_data_expanded;
}
}
if (to_apply)
SetEnvironmentVariableW(value_name, to_apply);
}
if (to_apply)
SetEnvironmentVariableW(value_name, to_apply);
}
RegCloseKey(reg_key);
}
RevertToSelf();
}
}
}
RegCloseKey(reg_key);
}
RevertToSelf();
}
}
free(pw_dir_w);
free(pw_dir_w);
}
int do_exec_windows(Session *s, const char *command, int pty) {
int pipein[2], pipeout[2], pipeerr[2], r;
char *exec_command = NULL, *progdir = w32_programdir();
wchar_t *exec_command_w = NULL, *pw_dir_w;
int pipein[2], pipeout[2], pipeerr[2], r;
char *exec_command = NULL, *progdir = w32_programdir();
wchar_t *exec_command_w = NULL, *pw_dir_w;
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR)
{
error("sub system not supported, exiting\n");
fflush(NULL);
exit(1);
}
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR) {
error("sub system not supported, exiting\n");
fflush(NULL);
exit(1);
}
/* Create three pipes for stdin, stdout and stderr */
if (pipe(pipein) == -1 || pipe(pipeout) == -1 || pipe(pipeerr) == -1)
fatal("%s: cannot create pipe: %.100s", __func__, strerror(errno));
/* Create three pipes for stdin, stdout and stderr */
if (pipe(pipein) == -1 || pipe(pipeout) == -1 || pipe(pipeerr) == -1)
fatal("%s: cannot create pipe: %.100s", __func__, strerror(errno));
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
fatal("%s: out of memory");
if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL)
fatal("%s: out of memory");
set_nonblock(pipein[0]);
set_nonblock(pipein[1]);
set_nonblock(pipeout[0]);
set_nonblock(pipeout[1]);
set_nonblock(pipeerr[0]);
set_nonblock(pipeerr[1]);
set_nonblock(pipein[0]);
set_nonblock(pipein[1]);
set_nonblock(pipeout[0]);
set_nonblock(pipeout[1]);
set_nonblock(pipeerr[0]);
set_nonblock(pipeerr[1]);
fcntl(pipein[1], F_SETFD, FD_CLOEXEC);
fcntl(pipeout[0], F_SETFD, FD_CLOEXEC);
fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC);
fcntl(pipein[1], F_SETFD, FD_CLOEXEC);
fcntl(pipeout[0], F_SETFD, FD_CLOEXEC);
fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC);
/* prepare exec - path used with CreateProcess() */
if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) {
/* relative or absolute */
if (command == NULL || command[0] == '\0')
fatal("expecting command for a subsystem");
/* prepare exec - path used with CreateProcess() */
if (s->is_subsystem || (command && memcmp(command, "scp", 3) == 0)) {
/* relative or absolute */
if (command == NULL || command[0] == '\0')
fatal("expecting command for a subsystem");
if (command[1] == ':') /* absolute */
exec_command = xstrdup(command);
else {/*relative*/
exec_command = malloc(strlen(progdir) + 1 + strlen(command));
if (exec_command == NULL)
fatal("%s, out of memory");
memcpy(exec_command, progdir, strlen(progdir));
exec_command[strlen(progdir)] = '\\';
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
}
} else {
char *shell_host = pty ? "ssh-shellhost.exe " : "ssh-shellhost.exe -nopty ", *c;
exec_command = malloc(strlen(progdir) + 1 + strlen(shell_host) + (command ? strlen(command) : 0) + 1);
if (exec_command == NULL)
fatal("%s, out of memory");
c = exec_command;
memcpy(c, progdir, strlen(progdir));
c += strlen(progdir);
*c++ = '\\';
memcpy(c, shell_host, strlen(shell_host));
c += strlen(shell_host);
if (command) {
memcpy(c, command, strlen(command));
c += strlen(command);
}
*c = '\0';
}
if (command[1] == ':') /* absolute */
exec_command = xstrdup(command);
else {/*relative*/
exec_command = malloc(strlen(progdir) + 1 + strlen(command));
if (exec_command == NULL)
fatal("%s, out of memory");
memcpy(exec_command, progdir, strlen(progdir));
exec_command[strlen(progdir)] = '\\';
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
}
} else {
char *shell_host = pty ? "ssh-shellhost.exe " : "ssh-shellhost.exe -nopty ", *c;
exec_command = malloc(strlen(progdir) + 1 + strlen(shell_host) + (command ? strlen(command) : 0) + 1);
if (exec_command == NULL)
fatal("%s, out of memory");
c = exec_command;
memcpy(c, progdir, strlen(progdir));
c += strlen(progdir);
*c++ = '\\';
memcpy(c, shell_host, strlen(shell_host));
c += strlen(shell_host);
if (command) {
memcpy(c, command, strlen(command));
c += strlen(command);
}
*c = '\0';
}
/* setup Environment varibles */
setup_session_vars(s);
extern int debug_flag;
/* setup Environment varibles */
setup_session_vars(s);
extern int debug_flag;
PROCESS_INFORMATION pi;
STARTUPINFOW si;
{
PROCESS_INFORMATION pi;
STARTUPINFOW si;
BOOL b;
BOOL b;
HANDLE hToken = INVALID_HANDLE_VALUE;
HANDLE hToken = INVALID_HANDLE_VALUE;
/*
* Assign sockets to StartupInfo
*/
/*
* Assign sockets to StartupInfo
*/
memset(&si, 0, sizeof(STARTUPINFO));
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpReserved = 0;
si.lpTitle = NULL; /* NULL means use exe name as title */
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 5;
si.dwYSize = 5;
si.dwXCountChars = s->col;
si.dwYCountChars = s->row;
si.dwFillAttribute = 0;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
si.wShowWindow = 0; // FALSE ;
si.cbReserved2 = 0;
si.lpReserved2 = 0;
si.cb = sizeof(STARTUPINFO);
si.lpReserved = 0;
si.lpTitle = NULL; /* NULL means use exe name as title */
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 5;
si.dwYSize = 5;
si.dwXCountChars = s->col;
si.dwYCountChars = s->row;
si.dwFillAttribute = 0;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
si.wShowWindow = 0; // FALSE ;
si.cbReserved2 = 0;
si.lpReserved2 = 0;
si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]);
si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]);
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
si.lpDesktop = NULL;
si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]);
si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]);
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
si.lpDesktop = NULL;
hToken = s->authctxt->methoddata;
hToken = s->authctxt->methoddata;
debug("Executing command: %s", exec_command);
debug("Executing command: %s", exec_command);
/* Create the child process */
/* Create the child process */
exec_command_w = utf8_to_utf16(exec_command);
exec_command_w = utf8_to_utf16(exec_command);
if (debug_flag)
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
DETACHED_PROCESS, NULL, pw_dir_w,
&si, &pi);
else
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
DETACHED_PROCESS , NULL, pw_dir_w,
&si, &pi);
if (debug_flag)
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
DETACHED_PROCESS, NULL, pw_dir_w,
&si, &pi);
else
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
DETACHED_PROCESS , NULL, pw_dir_w,
&si, &pi);
if (!b)
{
debug("ERROR. Cannot create process (%u).\n", GetLastError());
free(pw_dir_w);
free(exec_command_w);
CloseHandle(hToken);
if (!b)
{
debug("ERROR. Cannot create process (%u).\n", GetLastError());
free(pw_dir_w);
free(exec_command_w);
CloseHandle(hToken);
exit(1);
}
else if (pty) { /*attach to shell console */
FreeConsole();
if (!debug_flag)
ImpersonateLoggedOnUser(hToken);
Sleep(20);
while (AttachConsole(pi.dwProcessId) == FALSE) {
DWORD exit_code;
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
break;
Sleep(100);
}
if (!debug_flag)
RevertToSelf();
{
/* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the
* attached console agein */
exit(1);
}
else if (pty) { /*attach to shell console */
FreeConsole();
if (!debug_flag)
ImpersonateLoggedOnUser(hToken);
Sleep(20);
while (AttachConsole(pi.dwProcessId) == FALSE) {
DWORD exit_code;
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
break;
Sleep(100);
}
if (!debug_flag)
RevertToSelf();
{
/* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the
* attached console agein */
COORD coord;
coord.X = s->col;
coord.Y = 9999;;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
}
COORD coord;
coord.X = s->col;
coord.Y = 9999;;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
}
s->pid = pi.dwProcessId;
sw_add_child(pi.hProcess, pi.dwProcessId);
CloseHandle(pi.hThread);
s->pid = pi.dwProcessId;
sw_add_child(pi.hProcess, pi.dwProcessId);
}
/*
* Set interactive/non-interactive mode.
*/
packet_set_interactive(s->display != NULL, options.ip_qos_interactive,
options.ip_qos_bulk);
/*
* Set interactive/non-interactive mode.
*/
/* Close the child sides of the socket pairs. */
close(pipein[0]);
close(pipeout[1]);
close(pipeerr[1]);
packet_set_interactive(s->display != NULL, options.ip_qos_interactive,
options.ip_qos_bulk);
/*
* Enter the interactive session. Note: server_loop must be able to
* handle the case that fdin and fdout are the same.
*/
/*
* We are the parent. Close the child sides of the socket pairs.
*/
close(pipein[0]);
close(pipeout[1]);
close(pipeerr[1]);
/*
* Close child thread handles as we do not need it. Process handle we keep so that we can know if it has died o not
*/
CloseHandle(pi.hThread);
// CloseHandle(pi.hProcess);
/*
* Clear loginmsg, since it's the child's responsibility to display
* it to the user, otherwise multiple sessions may accumulate
* multiple copies of the login messages.
*/
buffer_clear(&loginmsg);
/*
* Enter the interactive session. Note: server_loop must be able to
* handle the case that fdin and fdout are the same.
*/
if (s->ttyfd == -1)
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 0);
else
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 1); // tty interactive session
if (s->ttyfd == -1)
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 0);
else
session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 1); // tty interactive session
free(pw_dir_w);
free(exec_command_w);
return 0;
return 0;
}
int
do_exec_no_pty(Session *s, const char *command) {
return do_exec_windows(s, command, 0);
return do_exec_windows(s, command, 0);
}
int
do_exec_pty(Session *s, const char *command) {
return do_exec_windows(s, command, 1);
return do_exec_windows(s, command, 1);
}
#else /* !WINDOWS */

View File

@ -1384,11 +1384,9 @@ do_download(struct sftp_conn *conn, const char *remote_path,
"server reordered requests", local_path);
}
debug("truncating at %llu", (unsigned long long)highwater);
#ifndef WIN32_VS
if (ftruncate(local_fd, highwater) == -1)
error("ftruncate \"%s\": %s", local_path,
strerror(errno));
#endif
}
if (read_error) {
error("Couldn't read from remote file \"%s\" : %s",
@ -1428,7 +1426,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
if (fsync(local_fd) == -1)
error("Couldn't sync file \"%s\": %s",
local_path, strerror(errno));
}
}
}
close(local_fd);
sshbuf_free(msg);

View File

@ -222,7 +222,7 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
strmode(st->st_mode, mode);
if (!remote) {
user = user_from_uid(st->st_uid, 0);
user = user_from_uid(st->st_uid, 0);
} else {
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
user = ubuf;
@ -233,7 +233,6 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
group = gbuf;
}
if (ltime != NULL) {
now = time(NULL);
if (now - (365*24*60*60)/2 < st->st_mtime &&

View File

@ -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

View File

@ -67,7 +67,6 @@ fudge_readdir(struct SFTP_OPENDIR *od)
/* Solaris needs sizeof(dirent) + path length (see below) */
static char buf[sizeof(struct dirent) + MAXPATHLEN];
struct dirent *ret = (struct dirent *)buf;
#ifdef __GNU_LIBRARY__
static int inum = 1;
#endif /* __GNU_LIBRARY__ */

View File

@ -688,7 +688,6 @@ process_open(u_int32_t id)
debug3("request %u: open flags %d", id, pflags);
flags = flags_from_portable(pflags);
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
if (readonly &&
@ -821,15 +820,13 @@ process_do_stat(u_int32_t id, int do_lstat)
struct stat st;
char *name;
int r, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
r = do_lstat ? lstat(name, &st) : stat(name, &st);
debug3("request %u: %sstat", id, do_lstat ? "l" : "");
verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
r = do_lstat ? lstat(name, &st) : stat(name, &st);
if (r < 0) {
status = errno_to_portable(errno);
} else {
@ -899,9 +896,8 @@ process_setstat(u_int32_t id)
char *name;
int r, status = SSH2_FX_OK;
// sshbuf_get_cstring() is called twice.. is this correct?
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
(r = decode_attrib(iqueue, &a)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
debug("request %u: setstat name \"%s\"", id, name);
@ -936,7 +932,6 @@ process_setstat(u_int32_t id)
if (r == -1)
status = errno_to_portable(errno);
}
send_status(id, status);
free(name);
}
@ -962,7 +957,6 @@ process_fsetstat(u_int32_t id)
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
logit("set \"%s\" size %llu",
name, (unsigned long long)a.size);
r = ftruncate(fd, a.size);
if (r == -1)
status = errno_to_portable(errno);
@ -995,7 +989,6 @@ process_fsetstat(u_int32_t id)
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
logit("set \"%s\" owner %lu group %lu", name,
(u_long)a.uid, (u_long)a.gid);
#ifdef HAVE_FCHOWN
r = fchown(fd, a.uid, a.gid);
#else
@ -1018,11 +1011,9 @@ process_opendir(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
dirp = opendir(path);
debug3("request %u: opendir", id);
logit("opendir \"%s\"", path);
dirp = opendir(path);
if (dirp == NULL) {
status = errno_to_portable(errno);
} else {
@ -1064,7 +1055,6 @@ process_readdir(u_int32_t id)
int nstats = 10, count = 0, i;
stats = xcalloc(nstats, sizeof(Stat));
while ((dp = readdir(dirp)) != NULL) {
if (count >= nstats) {
nstats *= 2;
@ -1078,7 +1068,7 @@ process_readdir(u_int32_t id)
stat_to_attrib(&st, &(stats[count].attrib));
stats[count].name = xstrdup(dp->d_name);
stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
count++;
count++;
/* send up to 100 entries in one message */
/* XXX check packet size instead */
if (count == 100)
@ -1108,7 +1098,6 @@ process_remove(u_int32_t id)
debug3("request %u: remove", id);
logit("remove name \"%s\"", name);
r = unlink(name);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
@ -1130,8 +1119,6 @@ process_mkdir(u_int32_t id)
a.perm & 07777 : 0777;
debug3("request %u: mkdir", id);
logit("mkdir name \"%s\" mode 0%o", name, mode);
r = mkdir(name, mode);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
@ -1149,7 +1136,6 @@ process_rmdir(u_int32_t id)
debug3("request %u: rmdir", id);
logit("rmdir name \"%s\"", name);
r = rmdir(name);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
@ -1170,7 +1156,6 @@ process_realpath(u_int32_t id)
free(path);
path = xstrdup(".");
}
debug3("request %u: realpath", id);
verbose("realpath \"%s\"", path);
if (realpath(path, resolvedname) == NULL) {
@ -1233,8 +1218,7 @@ process_rename(u_int32_t id)
unlink(newpath);
} else
status = SSH2_FX_OK;
}
else if (stat(newpath, &sb) == -1) {
} else if (stat(newpath, &sb) == -1) {
if (rename(oldpath, newpath) == -1)
status = errno_to_portable(errno);
else
@ -1257,7 +1241,6 @@ process_readlink(u_int32_t id)
debug3("request %u: readlink", id);
verbose("readlink \"%s\"", path);
if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
send_status(id, errno_to_portable(errno));
else {
@ -1275,7 +1258,7 @@ static void
process_symlink(u_int32_t id)
{
char *oldpath, *newpath;
int r, status= SSH2_FX_OP_UNSUPPORTED;
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
@ -1283,12 +1266,10 @@ process_symlink(u_int32_t id)
debug3("request %u: symlink", id);
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
/* this will fail if 'newpath' exists */
r = symlink(oldpath, newpath);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(oldpath);
free(newpath);
}
@ -1317,7 +1298,6 @@ process_extended_statvfs(u_int32_t id)
{
char *path;
struct statvfs st;
int r;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
@ -1346,19 +1326,17 @@ process_extended_fstatvfs(u_int32_t id)
send_status(id, SSH2_FX_FAILURE);
return;
}
if (statvfs(handle_to_name(handle), &st) != 0)
if (fstatvfs(fd, &st) != 0)
send_status(id, errno_to_portable(errno));
else
send_statvfs(id, &st);
if (fstatvfs(fd, &st) != 0)
send_status(id, errno_to_portable(errno));
else
send_statvfs(id, &st);
}
static void
process_extended_hardlink(u_int32_t id)
{
char *oldpath, *newpath;
int r, status = SSH2_FX_OP_UNSUPPORTED;
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
@ -1366,10 +1344,8 @@ process_extended_hardlink(u_int32_t id)
debug3("request %u: hardlink", id);
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
r = link(oldpath, newpath);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(oldpath);
free(newpath);
@ -1429,11 +1405,10 @@ process(void)
const u_char *cp;
int i, r;
u_int32_t id;
buf_len = sshbuf_len(iqueue);
if (buf_len < 5) {
if (buf_len < 5)
return; /* Incomplete message. */
}
cp = sshbuf_ptr(iqueue);
msg_len = get_u32(cp);
if (msg_len > SFTP_MAX_MSG_LENGTH) {
@ -1441,9 +1416,8 @@ process(void)
client_addr, pw->pw_name);
sftp_server_cleanup_exit(11);
}
if (buf_len < msg_len + 4) {
if (buf_len < msg_len + 4)
return;
}
if ((r = sshbuf_consume(iqueue, 4)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
buf_len -= 4;
@ -1529,8 +1503,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0;
ssize_t len, olen, set_size;
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
char *cp, *homedir = NULL, buf[4*4096];
char *cp, *homedir = NULL, buf[4*4096];
long mask;
extern char *optarg;
@ -1608,7 +1581,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
sftp_server_usage();
}
}
log_init(__progname, log_level, log_facility, log_stderr);
/*
@ -1732,6 +1705,4 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
fatal("%s: sshbuf_check_reserve: %s",
__func__, ssh_err(r));
}
//#endif /* else WIN32 */
}

246
sftp.c
View File

@ -73,7 +73,6 @@ typedef void EditLine;
#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
#define MAX_COMMAND_LINE 2048
/* File to read commands from */
FILE* infile;
@ -295,6 +294,7 @@ help(void)
#ifdef WINDOWS
/* printf version to account for utf-8 input */
/* TODO - merge this with vfmprint */
static void printf_utf8(char *fmt, ... ) {
/* TODO - is 1024 sufficient */
char buf[1024];
@ -311,6 +311,8 @@ static void printf_utf8(char *fmt, ... ) {
free(wtmp);
}
/* override mprintf */
#define mprintf(a,...) printf_utf8((a), __VA_ARGS__)
#define printf(a,...) printf_utf8((a), __VA_ARGS__)
#endif /* WINDOWS */
@ -324,7 +326,7 @@ local_do_shell(const char *args)
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
}
system(args); // execute the shell or cmd given
#else
#else /* !WINDOWS */
int status;
char *shell;
pid_t pid;
@ -358,7 +360,7 @@ local_do_shell(const char *args)
error("Shell exited abnormally");
else if (WEXITSTATUS(status))
error("Shell exited with status %d", WEXITSTATUS(status));
#endif
#endif /* !WINDOWS */
}
static void
@ -418,11 +420,7 @@ make_absolute(char *p, const char *pwd)
}
/* convert '\\' tp '/' */
s1 = p;
while ((s2 = strchr(s1, '\\')) != NULL) {
*s2 = '/';
s1 = s2 + 1;
}
convertToForwardslash(p);
/* Append "/" if needed to the absolute windows path */
if (p && p[0] != '\0' && p[1] == ':') {
@ -431,13 +429,14 @@ make_absolute(char *p, const char *pwd)
p = s1;
}
#else
#else /* !WINDOWS */
if (p && p[0] != '/') {
abs_str = path_append(pwd, p);
free(p);
return(abs_str);
}
#endif
} else
return(p);
#endif /* !WINDOWS */
return(p);
}
@ -672,7 +671,6 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
abs_src = xstrdup(src);
abs_src = make_absolute(abs_src, pwd);
memset(&g, 0, sizeof(g));
debug3("Looking up %s", abs_src);
@ -712,7 +710,7 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
} else {
abs_dst = xstrdup(dst);
}
} else if (dst) {
} else if (dst) {
abs_dst = path_append(dst, filename);
} else {
abs_dst = xstrdup(filename);
@ -720,10 +718,12 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
free(tmp);
resume |= global_aflag;
if (!quiet && resume)
printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst);
else if (!quiet && !resume)
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
if (!quiet && resume)
mprintf("Resuming %s to %s\n",
g.gl_pathv[i], abs_dst);
else if (!quiet && !resume)
mprintf("Fetching %s to %s\n",
g.gl_pathv[i], abs_dst);
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, 1, resume,
@ -771,10 +771,8 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
}
/* If we aren't fetching to pwd then stash this status for later */
if (tmp_dst != NULL) {
if (tmp_dst != NULL)
dst_is_dir = remote_is_dir(conn, tmp_dst);
}
/* If multiple matches, dst may be directory or unspecified */
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
@ -805,7 +803,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
abs_dst = path_append(tmp_dst, filename);
else
abs_dst = xstrdup(tmp_dst);
} else if (tmp_dst) {
} else if (tmp_dst) {
abs_dst = path_append(tmp_dst, filename);
} else {
abs_dst = make_absolute(xstrdup(filename), pwd);
@ -814,10 +812,11 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
resume |= global_aflag;
if (!quiet && resume)
printf("Resuming upload of %s to %s\n", g.gl_pathv[i],
abs_dst);
mprintf("Resuming upload of %s to %s\n",
g.gl_pathv[i], abs_dst);
else if (!quiet && !resume)
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
mprintf("Uploading %s to %s\n",
g.gl_pathv[i], abs_dst);
if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
@ -887,6 +886,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
columns = width / (m + 2);
columns = MAXIMUM(columns, 1);
colspace = width / columns;
@ -919,24 +919,21 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
attrib_to_stat(&d[n]->a, &sb);
lname = ls_file(fname, &sb, 1,
(lflag & LS_SI_UNITS));
printf("%s\n", lname);
mprintf("%s\n", lname);
free(lname);
}
else {
printf("%s\n", d[n]->longname);
}
}
else {
} else
mprintf("%s\n", d[n]->longname);
} else {
#ifdef WINDOWS
/* cannot use printf_utf8 becuase of width specification */
/* printf_utf8 does not account for utf-16 based argument widths */
wchar_t buf[1024];
wchar_t* wtmp = utf8_to_utf16(fname);
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
free(wtmp);
/* cannot use printf_utf8 becuase of width specification */
/* printf_utf8 does not account for utf-16 based argument widths */
wchar_t buf[1024];
wchar_t* wtmp = utf8_to_utf16(fname);
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
free(wtmp);
#else
printf("%-*s", colspace, fname);
mprintf("%-*s", colspace, fname);
#endif
if (c >= columns) {
printf("\n");
@ -995,7 +992,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
globfree(&g);
return err;
}
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
@ -1018,21 +1015,21 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
}
lname = ls_file(fname, g.gl_statv[i], 1,
(lflag & LS_SI_UNITS));
printf("%s\n", lname);
free(lname);
mprintf("%s\n", lname);
free(lname);
} else {
#ifdef WINDOWS
/* cannot use printf_utf8 becuase of width specification */
/* printf_utf8 does not account for utf-16 based argument widths */
wchar_t buf[1024];
wchar_t* wtmp = utf8_to_utf16(fname);
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
free(wtmp);
/* cannot use printf_utf8 becuase of width specification */
/* printf_utf8 does not account for utf-16 based argument widths */
wchar_t buf[1024];
wchar_t* wtmp = utf8_to_utf16(fname);
swprintf(buf, 1024, L"%-*s", colspace, wtmp);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buf, wcslen(buf), 0, 0);
free(wtmp);
#else
printf("%-*s", colspace, fname);
mprintf("%-*s", colspace, fname);
#endif
if (c >= columns) {
if (c >= columns) {
printf("\n");
c = 1;
} else
@ -1513,23 +1510,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
path1 = path2 = NULL;
#ifdef WINDOWS
/*
* convert '/' to '\' in Windows styled paths.
* convert '\\' to '/' in Windows styled paths.
* else they get treated as escape sequence in makeargv
*/
{
char *s1 = cmd, *s2;
while ((s2 = strchr(s1, '\\')) != NULL) {
*s2 = '/';
s1 = s2 + 1;
}
}
convertToForwardslash(cmd);
#endif
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
if (ignore_errors != 0)
err_abort = 0;
memset(&g, 0, sizeof(g));
memset(&g, 0, sizeof(g));
/* Perform command */
switch (cmdnum) {
@ -1570,10 +1561,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
case I_RM:
path1 = make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
printf("Removing %s\n", g.gl_pathv[i]);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Removing %s\n", g.gl_pathv[i]);
err = do_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
@ -1673,7 +1663,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
printf("Changing mode on %s\n", g.gl_pathv[i]);
mprintf("Changing mode on %s\n",
g.gl_pathv[i]);
err = do_setstat(conn, g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
@ -1703,13 +1694,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
if (cmdnum == I_CHOWN) {
if (!quiet)
printf("Changing owner on %s\n",
g.gl_pathv[i]);
mprintf("Changing owner on %s\n",
g.gl_pathv[i]);
aa->uid = n_arg;
} else {
if (!quiet)
printf("Changing group on %s\n",
g.gl_pathv[i]);
mprintf("Changing group on %s\n",
g.gl_pathv[i]);
aa->gid = n_arg;
}
err = do_setstat(conn, g.gl_pathv[i], aa);
@ -1718,7 +1709,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
}
break;
case I_PWD:
printf("Remote working directory: %s\n", *pwd);
mprintf("Remote working directory: %s\n", *pwd);
break;
case I_LPWD:
if (!getcwd(path_buf, sizeof(path_buf))) {
@ -1726,7 +1717,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
err = -1;
break;
}
printf("Local working directory: %s\n", path_buf);
mprintf("Local working directory: %s\n", path_buf);
break;
case I_QUIT:
/* Processed below */
@ -2129,7 +2120,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
{
char *remote_path;
char *dir = NULL;
char cmd[MAX_COMMAND_LINE];
char cmd[2048];
int err, interactive;
EditLine *el = NULL;
#ifdef USE_LIBEDIT
@ -2179,7 +2170,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
if (remote_is_dir(conn, dir) && file2 == NULL) {
if (!quiet)
printf("Changing to: %s\n", dir);
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
if (parse_dispatch_command(conn, cmd,
&remote_path, 1) != 0) {
@ -2205,13 +2196,13 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
}
#ifdef WINDOWS
/* Min buffer size allowed in Windows is 2*/
setvbuf(stdout, NULL, _IOLBF, 2);
setvbuf(infile, NULL, _IOLBF, 2);
#else
setvbuf(stdout, NULL, _IOLBF, 0);
/* Min buffer size allowed in Windows is 2*/
setvbuf(stdout, NULL, _IOLBF, 2);
setvbuf(infile, NULL, _IOLBF, 2);
#else /* !WINDOWS */
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
#endif
#endif /* !WINDOWS */
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
@ -2222,35 +2213,32 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
if (el == NULL) {
#ifdef WINDOWS
if (interactive) {
wchar_t wcmd[MAX_COMMAND_LINE];
printf("sftp> ");
if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
printf("\n");
break;
}
else {
char *pcmd = NULL;
if ((pcmd = utf16_to_utf8(wcmd)) == NULL)
fatal("failed to convert input arguments");
strcpy(cmd, pcmd);
free(pcmd);
}
}
else {
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
break;
}
}
#else
if (interactive) {
printf("sftp> ");
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
if (interactive)
printf("\n");
break;
}
#endif
/* fgets on Windows does not support Unicode input*/
if (interactive) {
wchar_t wcmd[2048];
printf("sftp> ");
if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
printf("\n");
break;
}
else {
char *pcmd = NULL;
if ((pcmd = utf16_to_utf8(wcmd)) == NULL)
fatal("failed to convert input arguments");
strcpy(cmd, pcmd);
free(pcmd);
}
} else if (fgets(cmd, sizeof(cmd), infile) == NULL)
break;
#else /* !WINDOWS */
if (interactive)
printf("sftp> ");
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
if (interactive)
printf("\n");
break;
}
#endif/* !WINDOWS */
if (!interactive) { /* Echo command */
mprintf("sftp> %s", cmd);
if (strlen(cmd) > 0 &&
@ -2324,6 +2312,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
#endif /* USE_PIPES */
#ifdef WINDOWS
/* fork replacement on Windows */
{
size_t cmdlen = 0;
int i = 0;
@ -2331,14 +2320,15 @@ connect_to_server(char *path, char **args, int *in, int *out)
cmdlen = strlen(path) + 1;
for (i = 1; args[i]; i++)
cmdlen += strlen(args[i]) + 1;
cmdlen += strlen(args[i]) + 1 + 2;
full_cmd = xmalloc(cmdlen);
full_cmd[0] = '\0';
strcat(full_cmd, path);
for (i = 1; args[i]; i++) {
strcat(full_cmd, " ");
strcat(full_cmd, " \"");
strcat(full_cmd, args[i]);
strcat(full_cmd, "\"");
}
/* disable inheritance on local pipe ends*/
@ -2350,9 +2340,9 @@ connect_to_server(char *path, char **args, int *in, int *out)
}
if (sshpid == -1)
#else
#else /* !WINDOWS */
if ((sshpid = fork()) == -1)
#endif
#endif /* !WINDOWS */
fatal("fork: %s", strerror(errno));
else if (sshpid == 0) {
if ((dup2(c_in, STDIN_FILENO) == -1) ||
@ -2426,11 +2416,7 @@ main(int argc, char **argv)
size_t num_requests = DEFAULT_NUM_REQUESTS;
long long limit_kbps = 0;
#ifdef WINDOWS
/*TODO - is this really needed ???*/
setvbuf(stdout, NULL, _IONBF, 0);
#endif
ssh_malloc_init(); /* must be called before any mallocs */
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
msetlocale();
@ -2439,17 +2425,18 @@ main(int argc, char **argv)
memset(&args, '\0', sizeof(args));
args.list = NULL;
addargs(&args, "%s", ssh_program);
addargs(&args, "\"-oForwardX11 no\"");
addargs(&args, "\"-oForwardAgent no\"");
addargs(&args, "\"-oPermitLocalCommand no\"");
addargs(&args, "\"-oClearAllForwardings yes\"");
addargs(&args, "-oForwardX11 no");
addargs(&args, "-oForwardAgent no");
addargs(&args, "-oPermitLocalCommand no");
addargs(&args, "-oClearAllForwardings yes");
ll = SYSLOG_LEVEL_INFO;
#ifdef WINDOWS
_setmode(_fileno(stdin), O_U16TEXT);
/* prepare for Unicode input */
_setmode(_fileno(stdin), O_U16TEXT);
#endif
infile = stdin;
infile = stdin;
while ((ch = getopt(argc, argv,
"1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
@ -2475,8 +2462,8 @@ main(int argc, char **argv)
addargs(&args, "-%c", ch);
break;
case 'P':
addargs(&args, "\"-oPort %s\"", optarg);
break;
addargs(&args, "-oPort %s", optarg);
break;
case 'v':
if (debug_level < 3) {
addargs(&args, "-v");
@ -2510,8 +2497,8 @@ main(int argc, char **argv)
fatal("%s (%s).", strerror(errno), optarg);
showprogress = 0;
quiet = batchmode = 1;
addargs(&args, "\"-obatchmode yes\"");
break;
addargs(&args, "-obatchmode yes");
break;
case 'f':
global_fflag = 1;
break;
@ -2584,7 +2571,8 @@ main(int argc, char **argv)
fprintf(stderr, "Missing hostname\n");
usage();
}
addargs(&args, "\"-oProtocol %d\"", sshver);
addargs(&args, "-oProtocol %d", sshver);
/* no subsystem if the server-spec contains a '/' */
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)

2
ssh.c
View File

@ -1475,7 +1475,7 @@ control_persist_detach(void)
*/
fatal("ControlMaster is not supported in Windows yet");
#else /* !WINDOWS */
pid_t pid;
pid_t pid;
int devnull, keep_stderr;
debug("%s: backgrounding master process", __func__);

82
sshd.c
View File

@ -164,11 +164,11 @@ int saved_argc;
/* re-exec */
int rexeced_flag = 0;
#ifdef WINDOWS
/* rexec is not supported in Windows */
/* rexec is not applicable in Windows */
int rexec_flag = 0;
#else
#else /* !WINDOWS */
int rexec_flag = 1;
#endif
#endif /* !WINDOWS */
int rexec_argc = 0;
char **rexec_argv;
@ -254,59 +254,6 @@ void destroy_sensitive_data(void);
void demote_sensitive_data(void);
static void do_ssh2_kex(void);
/*
* Retrieve path to current running module.
*
* path - buffer, where to store path (OUT).
* pathSize - size of path buffer in bytes (IN).
*
* RETURNS: 0 if OK.
*/
int GetCurrentModulePath(char *path, int pathSize)
{
int exitCode = -1;
#ifdef WINDOWS
char* dir = w32_programdir();
if (strnlen(dir, pathSize) == pathSize)
error("program directory path size exceeded provided pathSize %d", pathSize);
else {
memcpy(path, dir, strnlen(dir, pathSize) + 1);
exitCode = 0;
}
#endif
//
// Linux.
//
#ifdef __linux__
if (readlink ("/proc/self/exe", path, pathSize) != -1)
{
dirname(path);
strcat(path, "/");
exitCode = 0;
}
#endif
//
// MacOS.
//
#ifdef __APPLE__
#endif
return exitCode;
}
/*
* Close all listening sockets
*/
@ -591,7 +538,7 @@ reseed_prngs(void)
/*
* No-OP defs for preauth routines for Windows
* these should go away once the privilege separation
* related is refactored to be invoked only when applicable
* related code is refactored to be invoked only when applicable
*/
static void
privsep_preauth_child(void) {
@ -608,7 +555,7 @@ privsep_postauth(Authctxt *authctxt) {
return;
}
#else
#else /* !WINDOWS */
/* Unix privilege separation routines */
static void
privsep_preauth_child(void)
@ -645,6 +592,7 @@ privsep_preauth_child(void)
if (setgroups(1, gidset) < 0)
fatal("setgroups: %.100s", strerror(errno));
permanently_set_uid(privsep_pw);
}
}
static int
@ -768,7 +716,7 @@ privsep_postauth(Authctxt *authctxt)
packet_set_authenticated();
}
#endif
#endif /* !WINDOWS */
static char *
list_hostkey_types(void)
@ -1143,7 +1091,7 @@ server_listen(void)
close(listen_sock);
continue;
}
#endif
#endif /* WINDOWS */
/*
* Set socket options.
* Allow local port reuse in TIME_WAIT.
@ -1370,7 +1318,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
free(path_utf8);
close(*newsock);
}
#else
#else /* !WINDOWS */
if ((pid = fork()) == 0) {
/*
@ -1395,7 +1343,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
close(config_s[0]);
break;
}
#endif
#endif /* !WINDOWS */
/* Parent. Stay in the loop. */
platform_post_fork_parent(pid);
if (pid < 0)
@ -1764,7 +1712,7 @@ main(int ac, char **av)
#endif
);
#ifndef WINDOWS
#ifndef WINDOWS /* not applicable in Windows */
/* Store privilege separation user for later use if required. */
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
if (use_privsep || options.kerberos_authentication)
@ -1778,7 +1726,7 @@ main(int ac, char **av)
privsep_pw->pw_passwd = xstrdup("*");
}
endpwent();
#endif
#endif /* !WINDOWS */
/* load host keys */
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
@ -1796,7 +1744,7 @@ main(int ac, char **av)
error("Could not connect to agent \"%s\": %s",
options.host_key_agent, ssh_err(r));
}
#ifdef WIN32_FIXME
#ifdef WINDOWS /* Windows version always needs and has agent running */
have_agent = 1;
#endif
for (i = 0; i < options.num_host_key_files; i++) {
@ -1977,7 +1925,7 @@ main(int ac, char **av)
#ifdef WINDOWS
/* For Windows child sshd, skip listener */
if (is_child == 0)
#endif
#endif /* WINDOWS */
server_listen();
signal(SIGHUP, sighup_handler);
@ -2020,7 +1968,7 @@ main(int ac, char **av)
fcntl(startup_pipe, F_SETFD, FD_CLOEXEC);
}
else /* Windows and Unix sshd parent */
#endif
#endif /* WINDOWS */
/* Accept a connection and return in a forked child */
server_accept_loop(&sock_in, &sock_out,

View File

@ -74,9 +74,7 @@ void
enter_raw_mode(int quiet) {
ConInit(STD_OUTPUT_HANDLE, TRUE);
}
#else /* !WINDOWS */
struct termios *
get_saved_tio(void)
{
@ -124,7 +122,4 @@ enter_raw_mode(int quiet)
} else
_in_raw_mode = 1;
}
#endif /* !WINDOWS */
#endif /* !WINDOWS */

11
utf8.c
View File

@ -57,16 +57,15 @@ static int vasnmprintf(char **, size_t, int *, const char *, va_list);
static int
dangerous_locale(void) {
#ifndef WINDOWS
#ifdef WINDOWS
wchar_t loc[LOCALE_NAME_MAX_LENGTH];
GetSystemDefaultLocaleName(loc, LOCALE_NAME_MAX_LENGTH);
return wcscmp(loc, L"US-ASCII") && wcscmp(loc, L"UTF-8");
#else /* !WINDOWS */
char *loc;
loc = nl_langinfo(CODESET);
return strcmp(loc, "US-ASCII") && strcmp(loc, "UTF-8");
#else /* !WINDOWS */
wchar_t loc[LOCALE_NAME_MAX_LENGTH];
GetSystemDefaultLocaleName(loc, LOCALE_NAME_MAX_LENGTH);
return wcscmp(loc, L"US-ASCII") && wcscmp(loc, L"UTF-8");
#endif /* !WINDOWS */
}

View File

@ -1,6 +1,6 @@
/* $OpenBSD: version.h,v 1.77 2016/07/24 11:45:36 djm Exp $ */
/* $OpenBSD: version.h,v 1.78 2016/12/19 04:55:51 djm Exp $ */
#define SSH_VERSION "OpenSSH_7.3"
#define SSH_VERSION "OpenSSH_7.4"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE