PowerShell/Win32-OpenSSH#648 PowerShell/Win32-OpenSSH#718
This commit is contained in:
parent
79662b9a6f
commit
afc6ca91f7
|
@ -339,7 +339,7 @@ function Package-OpenSSH
|
|||
|
||||
if ($DestinationPath -ne "") {
|
||||
if (Test-Path $DestinationPath) {
|
||||
Remove-Item $DestinationPath\* -Force -Recurse
|
||||
Remove-Item $DestinationPath\* -Force -Recurse -ErrorAction SilentlyContinue
|
||||
}
|
||||
else {
|
||||
New-Item -ItemType Directory $DestinationPath -Force | Out-Null
|
||||
|
@ -542,18 +542,22 @@ function UnInstall-OpenSSH
|
|||
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
|
||||
)
|
||||
|
||||
if (-not (Test-Path $OpenSSHDir))
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
Push-Location $OpenSSHDir
|
||||
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
|
||||
Stop-Service ssh-agent -Force
|
||||
}
|
||||
&( "$OpenSSHDir\uninstall-sshd.ps1")
|
||||
&( "$OpenSSHDir\uninstall-sshlsa.ps1")
|
||||
|
||||
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
|
||||
$newMachineEnvironmentPath = $machinePath
|
||||
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
|
||||
{
|
||||
$newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
|
||||
$newMachineEnvironmentPath = $newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
|
||||
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <io.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <direct.h>
|
||||
|
||||
#include "w32fd.h"
|
||||
#include "inc\utf.h"
|
||||
|
@ -638,22 +639,53 @@ int
|
|||
fileio_stat(const char *path, struct _stat64 *buf)
|
||||
{
|
||||
wchar_t* wpath = NULL;
|
||||
int r = -1;
|
||||
WIN32_FILE_ATTRIBUTE_DATA attributes = { 0 };
|
||||
int ret = -1, len = 0;
|
||||
if ((wpath = utf8_to_utf16(path)) == NULL) {
|
||||
errno = errno_from_Win32LastError();
|
||||
debug3("utf8_to_utf16 failed for file:%s error:%d", path, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, sizeof(struct _stat64));
|
||||
|
||||
if ((wpath = utf8_to_utf16(path)) == NULL)
|
||||
fatal("failed to covert input arguments");
|
||||
if (GetFileAttributesExW(wpath, GetFileExInfoStandard, &attributes) == FALSE) {
|
||||
errno = errno_from_Win32LastError();
|
||||
debug3("GetFileAttributesExW with last error %d", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
len = wcslen(wpath);
|
||||
|
||||
r = _wstat64(wpath, buf);
|
||||
|
||||
/*
|
||||
* If we doesn't have sufficient permissions then _wstat64() is returning "file not found"
|
||||
* TODO - Replace the above call with GetFileAttributesEx
|
||||
*/
|
||||
buf->st_ino = 0; /* Has no meaning in the FAT, HPFS, or NTFS file systems*/
|
||||
buf->st_gid = 0; /* UNIX - specific; has no meaning on windows */
|
||||
buf->st_uid = 0; /* UNIX - specific; has no meaning on windows */
|
||||
buf->st_nlink = 1; /* number of hard links. Always 1 on non - NTFS file systems.*/
|
||||
buf->st_mode |= file_attr_to_st_mode(wpath, attributes.dwFileAttributes);
|
||||
buf->st_size = attributes.nFileSizeLow | (((off_t)attributes.nFileSizeHigh) << 32);
|
||||
if (len > 1 && __ascii_iswalpha(*wpath) && (*(wpath + 1) == ':'))
|
||||
buf->st_dev = buf->st_rdev = towupper(*wpath) - L'A'; /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
file_time_to_unix_time(&(attributes.ftLastAccessTime), &(buf->st_atime));
|
||||
file_time_to_unix_time(&(attributes.ftLastWriteTime), &(buf->st_mtime));
|
||||
file_time_to_unix_time(&(attributes.ftCreationTime), &(buf->st_ctime));
|
||||
|
||||
if (attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
WIN32_FIND_DATAW findbuf = { 0 };
|
||||
HANDLE handle = FindFirstFileW(wpath, &findbuf);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
|
||||
buf->st_mode |= S_IFLNK;
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
cleanup:
|
||||
if (wpath)
|
||||
free(wpath);
|
||||
return r;
|
||||
free(wpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
#define utimes w32_utimes
|
||||
|
||||
int usleep(unsigned int);
|
||||
int gettimeofday(struct timeval *tv, void *tz);
|
||||
int nanosleep(const struct timespec *req, struct timespec *rem);
|
||||
int w32_utimes(const char *filename, struct timeval *tvp);
|
||||
int gettimeofday(struct timeval *, void *);
|
||||
int nanosleep(const struct timespec *, struct timespec *);
|
||||
int w32_utimes(const char *, struct timeval *);
|
|
@ -59,6 +59,10 @@ static char* s_programdir = NULL;
|
|||
#define IO_REPARSE_TAG_SIS (0x80000007L) /* winnt ntifs */
|
||||
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
|
||||
|
||||
/* Difference in us between UNIX Epoch and Win32 Epoch */
|
||||
#define EPOCH_DELTA_US 116444736000000000ULL
|
||||
#define RATE_DIFF 10000000ULL /* 1000 nsecs */
|
||||
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
|
@ -174,9 +178,6 @@ nanosleep(const struct timespec *req, struct timespec *rem)
|
|||
}
|
||||
}
|
||||
|
||||
/* Difference in us between UNIX Epoch and Win32 Epoch */
|
||||
#define EPOCH_DELTA_US 11644473600000000ULL
|
||||
|
||||
/* This routine is contributed by * Author: NoMachine <developers@nomachine.com>
|
||||
* Copyright (c) 2009, 2010 NoMachine
|
||||
* All rights reserved
|
||||
|
@ -191,17 +192,14 @@ gettimeofday(struct timeval *tv, void *tz)
|
|||
unsigned long long us;
|
||||
|
||||
/* Fetch time since Jan 1, 1601 in 100ns increments */
|
||||
GetSystemTimeAsFileTime(&timehelper.ft);
|
||||
|
||||
/* Convert to microseconds from 100 ns units */
|
||||
us = timehelper.ns / 10;
|
||||
GetSystemTimeAsFileTime(&timehelper.ft);
|
||||
|
||||
/* Remove the epoch difference */
|
||||
us -= EPOCH_DELTA_US;
|
||||
us = timehelper.ns - EPOCH_DELTA_US;
|
||||
|
||||
/* Stuff result into the timeval */
|
||||
tv->tv_sec = (long)(us / 1000000ULL);
|
||||
tv->tv_usec = (long)(us % 1000000ULL);
|
||||
tv->tv_sec = (long)(us / RATE_DIFF);
|
||||
tv->tv_usec = (long)(us % RATE_DIFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -550,16 +548,83 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
/* Convert a UNIX time into a Windows file time */
|
||||
void
|
||||
unix_time_to_file_time(ULONG t, LPFILETIME pft)
|
||||
{
|
||||
ULONGLONG ull;
|
||||
ull = UInt32x32To64(t, 10000000) + 116444736000000000;
|
||||
ull = UInt32x32To64(t, RATE_DIFF) + EPOCH_DELTA_US;
|
||||
|
||||
pft->dwLowDateTime = (DWORD)ull;
|
||||
pft->dwHighDateTime = (DWORD)(ull >> 32);
|
||||
}
|
||||
|
||||
/* Convert a Windows file time into a UNIX time_t */
|
||||
void
|
||||
file_time_to_unix_time(const LPFILETIME pft, time_t * winTime)
|
||||
{
|
||||
*winTime = ((long long)pft->dwHighDateTime << 32) + pft->dwLowDateTime;
|
||||
*winTime -= EPOCH_DELTA_US;
|
||||
*winTime /= RATE_DIFF; /* Nano to seconds resolution */
|
||||
}
|
||||
|
||||
static BOOL
|
||||
is_root_or_empty(wchar_t * path)
|
||||
{
|
||||
wchar_t * path_start;
|
||||
BOOL has_drive_letter_and_colon;
|
||||
int len;
|
||||
if (!path)
|
||||
return FALSE;
|
||||
len = wcslen(path);
|
||||
if((len > 1) && __ascii_iswalpha(path[0]) && path[1] == L':')
|
||||
path_start = path + 2;
|
||||
else
|
||||
path_start = path;
|
||||
/*path like c:\, /, \ are root directory*/
|
||||
if ((*path_start == L'\0') || ((*path_start == L'\\' || *path_start == L'/' ) && path_start[1] == L'\0'))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
has_executable_extension(wchar_t * path)
|
||||
{
|
||||
wchar_t * last_dot;
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
last_dot = wcsrchr(path, L'.');
|
||||
if (!last_dot)
|
||||
return FALSE;
|
||||
if (_wcsnicmp(last_dot, L".exe", 4) != 0 && _wcsnicmp(last_dot, L".cmd", 4) != 0 &&
|
||||
_wcsnicmp(last_dot, L".bat", 4) != 0 && _wcsnicmp(last_dot, L".com", 4) != 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
file_attr_to_st_mode(wchar_t * path, DWORD attributes)
|
||||
{
|
||||
int mode = S_IREAD;
|
||||
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 || is_root_or_empty(path))
|
||||
mode |= S_IFDIR | _S_IEXEC;
|
||||
else {
|
||||
mode |= S_IFREG;
|
||||
/* See if file appears to be an executable by checking its extension */
|
||||
if (has_executable_extension(path))
|
||||
mode |= _S_IEXEC;
|
||||
|
||||
}
|
||||
if (!(attributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= S_IWRITE;
|
||||
|
||||
// propagate owner read/write/execute bits to group/other fields.
|
||||
mode |= (mode & 0700) >> 3;
|
||||
mode |= (mode & 0700) >> 6;
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int
|
||||
settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime)
|
||||
{
|
||||
|
|
|
@ -14,3 +14,6 @@ char* w32_programdir();
|
|||
|
||||
void convertToBackslash(char *str);
|
||||
void convertToForwardslash(char *str);
|
||||
|
||||
void unix_time_to_file_time(ULONG, LPFILETIME);
|
||||
void file_time_unix_time(const LPFILETIME, time_t *);
|
||||
|
|
|
@ -63,6 +63,15 @@ Describe "Tests for host keys file permission" -Tags "Scenario" {
|
|||
Remove-Item -Path $filePath -Force -ErrorAction ignore
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
if(Test-path $hostKeyFilePath -PathType Leaf){
|
||||
Set-SecureFileACL -filepath $hostKeyFilePath
|
||||
}
|
||||
if(Test-path "$hostKeyFilePath.pub" -PathType Leaf){
|
||||
Set-SecureFileACL -filepath "$hostKeyFilePath.pub"
|
||||
}
|
||||
}
|
||||
|
||||
It 'Host keys -- positive (Secured private key and sshd can access to public key file)' {
|
||||
#setup to have current user as owner and grant it full control
|
||||
Set-SecureFileACL -filepath $hostKeyFilePath
|
||||
|
|
|
@ -102,8 +102,49 @@ void file_simple_fileio()
|
|||
ASSERT_INT_EQ(ret, 0);
|
||||
close(f);
|
||||
TEST_DONE();
|
||||
}
|
||||
|
||||
void file_simple_fileio_mode()
|
||||
{
|
||||
char * small_write_buf = "sample payload", *c, small_read_buf[SMALL_RECV_BUF_SIZE];
|
||||
int ret;
|
||||
FILE* f;
|
||||
struct stat st;
|
||||
|
||||
TEST_START("file mode");
|
||||
f = fopen("tmp.txt", "w");
|
||||
ASSERT_PTR_NE(f, NULL);
|
||||
fclose(f);
|
||||
f = fopen("tmp.txt", "r");
|
||||
ASSERT_PTR_NE(f, NULL);
|
||||
c = fgets(small_read_buf, sizeof(small_read_buf), f);
|
||||
ASSERT_PTR_EQ(c, NULL);
|
||||
fclose(f);
|
||||
|
||||
ret = stat("tmp.txt", &st);
|
||||
ASSERT_INT_EQ(ret, 0);
|
||||
ASSERT_INT_EQ(st.st_size, 0);
|
||||
|
||||
f = fopen("tmp.txt", "w");
|
||||
ASSERT_PTR_NE(f, NULL);
|
||||
ret = fputs(small_write_buf, f);
|
||||
ASSERT_INT_EQ(ret, 0);
|
||||
fclose(f);
|
||||
|
||||
ret = stat("tmp.txt", &st);
|
||||
ASSERT_INT_EQ(ret, 0);
|
||||
ASSERT_INT_EQ(st.st_size, strlen(small_write_buf));
|
||||
|
||||
f = fopen("tmp.txt", "r");
|
||||
ASSERT_PTR_NE(f, NULL);
|
||||
c = fgets(small_read_buf, sizeof(small_read_buf), f);
|
||||
ASSERT_PTR_NE(c, NULL);
|
||||
ASSERT_STRING_EQ(small_write_buf, small_read_buf);
|
||||
|
||||
c = fgets(small_read_buf, sizeof(small_read_buf), f);
|
||||
ASSERT_PTR_EQ(c, NULL);
|
||||
fclose(f);
|
||||
TEST_DONE();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -240,7 +281,8 @@ void
|
|||
file_tests()
|
||||
{
|
||||
//console_io_test();
|
||||
//file_simple_fileio();
|
||||
file_simple_fileio();
|
||||
file_simple_fileio_mode();
|
||||
file_blocking_io_tests();
|
||||
file_nonblocking_io_tests();
|
||||
file_select_tests();
|
||||
|
|
Loading…
Reference in New Issue