Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contrib/win32/openssh/win32iocompat.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\signal_wait.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_pty.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\gss-sspi.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\lxss.c" />
<ClCompile Include="sshTelemetry.c" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions contrib/win32/openssh/win32iocompat.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_usertoken_utils.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\gss-sspi.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_pty.c" />
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\lxss.c" />
<ClCompile Include="sshTelemetry.c" />
</ItemGroup>
<ItemGroup>
Expand Down
71 changes: 71 additions & 0 deletions contrib/win32/win32compat/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,77 @@ errno_from_Win32Error(int win32_error)
}
}

/* return 1 if the file is native a unix socket, 0 otherwise
detail = 1: AF_UNIX
detail = 2: PIPE - this may fail, so treat any value other than 1 and 3 as PIPE
detail = 3: FILE
*/
int fileio_is_afunix_socket(const char* name, int* detail)
{
wchar_t* name_w = utf8_to_utf16(name);
int ret = 0;
int type;
HANDLE h;
FILE_ATTRIBUTE_TAG_INFO info;

if (name_w == NULL)
return 0;

if (detail != NULL)
*detail = 0;

h = CreateFileW(name_w,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if (h == INVALID_HANDLE_VALUE) {
ret = 0;
debug("fileio_is_afunix_socket - ERROR: CreateFileW failed, error: 0x%08x", GetLastError());
goto clean;
}

if (GetFileInformationByHandleEx(h, FileAttributeTagInfo, &info, sizeof(info)) != FALSE) {
if (info.ReparseTag == IO_REPARSE_TAG_AF_UNIX) {
ret = 1;
if (detail != NULL)
*detail = 1;
goto clean;
}
}else{
ret = 0;
debug("fileio_is_afunix_socket - ERROR: GetFileInformationByHandleEx failed, error: 0x%08x", GetLastError());
}

SetLastError(ERROR_SUCCESS);
type = GetFileType(h);
if(GetLastError() != ERROR_SUCCESS) {
ret = 0;
debug("fileio_is_afunix_socket - ERROR: GetFileType failed, error: 0x%08x", GetLastError());
goto clean;
}

if (type == FILE_TYPE_PIPE) {
ret = 0;
if (detail != NULL)
*detail = 2;
goto clean;
} else if (type == FILE_TYPE_DISK) {
ret = 0;
if (detail != NULL)
*detail = 3;
goto clean;
}

clean:
if (name_w)
free(name_w);
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
return ret;
}

struct w32_io*
fileio_afunix_socket()
{
Expand Down
92 changes: 92 additions & 0 deletions contrib/win32/win32compat/lxss.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@

#include "w32fd.h"
#include "inc\utf.h"
#include "misc_internal.h"
#include "debug.h"

#include <Windows.h>
#include <winternl.h>
#include <sys/stat.h>


static const NTSTATUS STATUS_SUCCESS = 0;

#define MAX_EA_INFO_SIZE 64

#pragma pack(push, 1)
typedef struct _FILE_FULL_EA_INFORMATION {
ULONG NextEntryOffset;
BYTE Flags;
BYTE EaNameLength;
USHORT EaValueLength;
CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, * PFILE_FULL_EA_INFORMATION;

#pragma pack(pop)

typedef
NTSTATUS
(NTAPI* NtSetEaFileFn)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID EaBuffer,
IN ULONG EaBufferSize);

struct ea_keyvalue {
const char* name;
const char* value;
ULONG value_len;
};

static void lxss_set_ea_info(wchar_t* path, char* buffer, ULONG length, int reparse){
IO_STATUS_BLOCK ioStatus;
NTSTATUS r;
HMODULE hmod = GetModuleHandleW(L"ntdll.dll");
if (hmod == NULL)
return;
NtSetEaFileFn NtSetEaFile = (NtSetEaFileFn)GetProcAddress(hmod, "NtSetEaFile");
if (NtSetEaFile == NULL)
return;
HANDLE file = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | (reparse ? FILE_FLAG_OPEN_REPARSE_POINT : 0), NULL);
if (file == INVALID_HANDLE_VALUE)
return;

r = NtSetEaFile(file, &ioStatus, buffer, length);
if (r != STATUS_SUCCESS)
return;
CloseHandle(file);
}

void lxss_set_perm(wchar_t* path, int reparse, ULONG uid, ULONG gid, ULONG mode){
struct ea_keyvalue** p;
struct ea_keyvalue* ea[4]; // **
int count = 0;
struct ea_keyvalue uid_ea = {"$LXUID", (char*)&uid, sizeof(uid)};
struct ea_keyvalue gid_ea = {"$LXGID", (char*)&gid, sizeof(gid)};
struct ea_keyvalue mode_ea = {"$LXMOD", (char*)&mode, sizeof(mode)};
FILE_FULL_EA_INFORMATION* ea_info = NULL;
ea[0] = &uid_ea;
ea[1] = &gid_ea;
ea[2] = &mode_ea;
ea[3] = NULL;
__declspec(align(16)) char buffer[MAX_EA_INFO_SIZE * sizeof(ea) / sizeof(ea[0])];
char *pb = buffer;

for (p = ea; *p != NULL; p++) {
ea_info = (FILE_FULL_EA_INFORMATION*)pb;
ea_info->NextEntryOffset = MAX_EA_INFO_SIZE;
ea_info->Flags = 0;
ea_info->EaNameLength = (BYTE)strlen((*p)->name);
ea_info->EaValueLength = (USHORT)(*p)->value_len;
memcpy(ea_info->EaName, (*p)->name, ea_info->EaNameLength);
memcpy(ea_info->EaName + ea_info->EaNameLength, (*p)->value, (*p)->value_len);
pb += MAX_EA_INFO_SIZE;
++count;
}
// mark last info
if (ea_info)
ea_info->NextEntryOffset = 0;
lxss_set_ea_info(path, buffer, count * MAX_EA_INFO_SIZE, reparse);
}
21 changes: 21 additions & 0 deletions contrib/win32/win32compat/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,8 @@ realpath(const char *inputpath, char * resolved)
{
wchar_t* temppath_utf16 = NULL;
wchar_t* resolved_utf16 = NULL;
DWORD temppath_len = 0;
char* temppath_utf8 = NULL;
char path[PATH_MAX] = { 0, }, tempPath[PATH_MAX] = { 0, }, *ret = NULL;
int is_win_path = 1;

Expand All @@ -972,6 +974,25 @@ realpath(const char *inputpath, char * resolved)
if (is_bash_test_env() && bash_to_win_path(inputpath, path, _countof(path)))
is_win_path = 0;

if (_strnicmp(inputpath, TMP_DIR, strlen(TMP_DIR)) == 0) {
/* if input path is TMP_DIR, replace TMP_DIR with GetTempPath() */
temppath_utf16 = malloc(sizeof(wchar_t) * MAX_PATH + 1);
temppath_len = GetTempPathW(MAX_PATH, temppath_utf16);
if (temppath_len > 0 && temppath_len < MAX_PATH)
{
temppath_utf8 = utf16_to_utf8(temppath_utf16);
if (temppath_utf8 != NULL)
{
strcpy_s(path, PATH_MAX, temppath_utf8);
strcat_s(path, PATH_MAX, &inputpath[strlen(TMP_DIR)]);
is_win_path = 0;
free(temppath_utf8);
}
}
free(temppath_utf16);
temppath_utf16 = NULL;
}

if (is_win_path) {
if (_strnicmp(inputpath, PROGRAM_DATA, strlen(PROGRAM_DATA)) == 0) {
strcpy_s(path, PATH_MAX, __progdata);
Expand Down
2 changes: 2 additions & 0 deletions contrib/win32/win32compat/misc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#define NULL_DEVICE "/dev/null"
#define NULL_DEVICE_WIN "NUL"

#define TMP_DIR "/tmp/"

#define IsWin7OrLess() (!IsWindows8OrGreater())

#define IS_INVALID_HANDLE(h) ( ((NULL == h) || (INVALID_HANDLE_VALUE == h)) ? 1 : 0 )
Expand Down
Loading