Skip to content

Commit 64f148c

Browse files
authored
fix for msrc cases (#752)
1 parent b4d7f73 commit 64f148c

File tree

6 files changed

+71
-2
lines changed

6 files changed

+71
-2
lines changed

contrib/win32/win32compat/ssh-agent/agent-main.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737

3838
#pragma warning(push, 3)
3939

40+
/* Pattern-list of allowed PKCS#11/Security key paths */
41+
char* allowed_providers = NULL;
42+
4043
int remote_add_provider;
4144

4245
int scm_start_service(DWORD, LPWSTR*);
@@ -134,8 +137,25 @@ wmain(int argc, wchar_t **wargv)
134137
fatal("Unknown -O option; only allow-remote-pkcs11 is supported");
135138
}
136139
}
140+
else if (wcsncmp(wargv[i], L"-P", 2) == 0) {
141+
if (allowed_providers != NULL)
142+
fatal("-P option already specified");
143+
if ((i + 1) < argc) {
144+
i++;
145+
if ((allowed_providers = utf16_to_utf8(wargv[i])) == NULL)
146+
fatal("Invalid argument for -P option");
147+
}
148+
else {
149+
fatal("Missing argument for -P option");
150+
}
151+
}
137152
}
138153
}
154+
155+
if (allowed_providers == NULL) {
156+
agent_initialize_allow_list();
157+
}
158+
139159
if (!StartServiceCtrlDispatcherW(dispatch_table)) {
140160
if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
141161
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */

contrib/win32/win32compat/ssh-agent/agent.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
#include <UserEnv.h>
3535
#include "..\misc_internal.h"
3636
#include <pwd.h>
37+
#include "xmalloc.h"
3738

3839
#define BUFSIZE 5 * 1024
3940

41+
extern char* allowed_providers;
4042
extern int remote_add_provider;
4143

4244
char* sshagent_con_username;
@@ -170,11 +172,11 @@ agent_listen_loop()
170172
GetModuleFileNameW(NULL, module_path, PATH_MAX);
171173
SetHandleInformation(con, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
172174
if (remote_add_provider == 1) {
173-
if (swprintf_s(path, PATH_MAX, L"%s %d %s", module_path, (int)(intptr_t)con, L"-Oallow-remote-pkcs11") == -1)
175+
if (swprintf_s(path, PATH_MAX, L"%s %d %s -P \"%S\"", module_path, (int)(intptr_t)con, L"-Oallow-remote-pkcs11", allowed_providers) == -1)
174176
verbose("Failed to create child process %ls ERROR:%d", module_path, GetLastError());
175177
}
176178
else {
177-
if (swprintf_s(path, PATH_MAX, L"%s %d", module_path, (int)(intptr_t)con) == -1)
179+
if (swprintf_s(path, PATH_MAX, L"%s %d -P \"%S\"", module_path, (int)(intptr_t)con, allowed_providers) == -1)
178180
verbose("Failed to create child process %ls ERROR:%d", module_path, GetLastError());
179181
}
180182
if (CreateProcessW(NULL, path, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi) == FALSE) {
@@ -408,3 +410,30 @@ agent_process_connection(HANDLE pipe)
408410
iocp_work(NULL);
409411
}
410412

413+
void
414+
agent_initialize_allow_list() {
415+
/*
416+
* allowed paths for PKCS11 libraries,
417+
* initialize to ProgramFiles and ProgramFiles(x86) by default
418+
* upstream uses /usr/lib/* and /usr/local/lib/*
419+
*/
420+
size_t prog_files_len = 0, prog_files_x86_len = 0;
421+
char* prog_files = NULL, * prog_files_x86 = NULL;
422+
423+
_dupenv_s(&prog_files, &prog_files_len, "ProgramFiles");
424+
if (!prog_files)
425+
fatal("couldn't find ProgramFiles environment variable");
426+
convertToForwardslash(prog_files);
427+
428+
_dupenv_s(&prog_files_x86, &prog_files_x86_len, "ProgramFiles(x86)");
429+
if (!prog_files_x86)
430+
fatal("couldn't find ProgramFiles environment variable");
431+
convertToForwardslash(prog_files_x86);
432+
433+
size_t allowed_providers_len = 1 + prog_files_len + 4 + prog_files_x86_len + 3;
434+
allowed_providers = xmalloc(allowed_providers_len);
435+
sprintf_s(allowed_providers, allowed_providers_len, "/%s/*,/%s/*", prog_files, prog_files_x86);
436+
437+
free(prog_files);
438+
free(prog_files_x86);
439+
}

contrib/win32/win32compat/ssh-agent/agent.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,4 @@ void agent_start(BOOL);
6363
void agent_process_connection(HANDLE);
6464
void agent_shutdown();
6565
void agent_cleanup_connection(struct agent_connection*);
66+
void agent_initialize_allow_list();

contrib/win32/win32compat/ssh-agent/keyagent-request.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "agent.h"
3333
#include "agent-request.h"
3434
#include "config.h"
35+
#include "match.h"
3536
#include <sddl.h>
3637
#ifdef ENABLE_PKCS11
3738
#include "ssh-pkcs11.h"
@@ -44,6 +45,7 @@
4445
#define MAX_VALUE_NAME_LENGTH 16383
4546
#define MAX_VALUE_DATA_LENGTH 2048
4647

48+
extern char* allowed_providers;
4749
extern int remote_add_provider;
4850

4951
/*
@@ -675,6 +677,12 @@ int process_add_smartcard_key(struct sshbuf* request, struct sshbuf* response, s
675677
goto done;
676678
}
677679

680+
if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) {
681+
verbose("refusing PKCS#11 add of \"%.100s\": "
682+
"provider not allowed", canonical_provider);
683+
goto done;
684+
}
685+
678686
// Remove 'drive root' if exists
679687
if (canonical_provider[0] == '/')
680688
memmove(canonical_provider, canonical_provider + 1, strlen(canonical_provider));
@@ -766,6 +774,8 @@ int process_add_smartcard_key(struct sshbuf* request, struct sshbuf* response, s
766774
free(pubkey_blob);
767775
if (provider)
768776
free(provider);
777+
if (allowed_providers)
778+
free(allowed_providers);
769779
if (pin) {
770780
SecureZeroMemory(pin, (DWORD)pin_len);
771781
free(pin);

scp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,7 +2117,11 @@ sink(int argc, char **argv, const char *src)
21172117
SCREWUP("size out of range");
21182118
size = (off_t)ull;
21192119

2120+
#ifdef WINDOWS
2121+
if (*cp == '\0' || strchr(cp, '/') != NULL || strchr(cp, '\\') != NULL ||
2122+
#else
21202123
if (*cp == '\0' || strchr(cp, '/') != NULL ||
2124+
#endif
21212125
strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) {
21222126
run_err("error: unexpected filename: %s", cp);
21232127
exit(1);

sftp-client.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,12 @@ extern int showprogress;
8484
#ifdef HAVE_CYGWIN
8585
# define SFTP_DIRECTORY_CHARS "/\\"
8686
#else /* HAVE_CYGWIN */
87+
#ifdef WINDOWS
88+
// Win32-OpenSSH converts all '/' to '\\' so search for '\\' instead
89+
# define SFTP_DIRECTORY_CHARS "\\"
90+
#else
8791
# define SFTP_DIRECTORY_CHARS "/"
92+
#endif /* WINDOWS */
8893
#endif /* HAVE_CYGWIN */
8994

9095
struct sftp_conn {

0 commit comments

Comments
 (0)