mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-29 16:54:51 +02:00
add motw to scp and sftp (#614)
* add motw to scp and sftp * retrigger appveyor * fix motw for filepaths with unicode characters * modify error handling * add debug for appveyor * modify motw method to use openssh method to open filestream * fix return value for null fileStreamPath pointer * fix spacing, comments, and failure message * clean up mark of the web method * incorporate MapUrlToZone for sftp & partially scp * update scp for motw failure case * Update contrib/win32/win32compat/misc.c Co-authored-by: Paul Higinbotham <paulhi@microsoft.com> * address pr review comments * refactor failure handling in motw methods * add CoUnitialize after CoInitializeEx call * use urlmon.h constants for com instance * update var name for consistency Co-authored-by: Paul Higinbotham <paulhi@microsoft.com>
This commit is contained in:
parent
ec26bbe178
commit
24c095e785
@ -60,6 +60,8 @@
|
|||||||
#include "w32fd.h"
|
#include "w32fd.h"
|
||||||
#include "inc\string.h"
|
#include "inc\string.h"
|
||||||
#include "inc\time.h"
|
#include "inc\time.h"
|
||||||
|
#include "..\..\..\atomicio.h"
|
||||||
|
#include "urlmon.h"
|
||||||
|
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
@ -135,6 +137,9 @@ int chroot_path_len = 0;
|
|||||||
/* UTF-16 version of the above */
|
/* UTF-16 version of the above */
|
||||||
wchar_t* chroot_pathw = NULL;
|
wchar_t* chroot_pathw = NULL;
|
||||||
|
|
||||||
|
/* motw zone_id initialized to invalid value */
|
||||||
|
DWORD motw_zone_id = 5;
|
||||||
|
|
||||||
int
|
int
|
||||||
usleep(unsigned int useconds)
|
usleep(unsigned int useconds)
|
||||||
{
|
{
|
||||||
@ -2119,3 +2124,100 @@ strrstr(const char *inStr, const char *pattern)
|
|||||||
|
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
add_mark_of_web(const char* filename)
|
||||||
|
{
|
||||||
|
if (motw_zone_id > 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char* fileStreamPath = NULL;
|
||||||
|
size_t fileStreamPathLen = strlen(filename) + strlen(":Zone.Identifier") + 1;
|
||||||
|
|
||||||
|
fileStreamPath = malloc(fileStreamPathLen * sizeof(char));
|
||||||
|
|
||||||
|
if (fileStreamPath == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf_s(fileStreamPath, fileStreamPathLen, "%s:Zone.Identifier", filename);
|
||||||
|
|
||||||
|
int ofd, status = 0;
|
||||||
|
char* zoneIdentifierStr = NULL;
|
||||||
|
size_t zoneIndentifierLen = strlen("[ZoneTransfer]\nZoneId=") + 1 + 1;
|
||||||
|
|
||||||
|
zoneIdentifierStr = malloc(zoneIndentifierLen * sizeof(char));
|
||||||
|
|
||||||
|
if (zoneIdentifierStr == NULL) {
|
||||||
|
status = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf_s(zoneIdentifierStr, zoneIndentifierLen, "[ZoneTransfer]\nZoneId=%d", motw_zone_id);
|
||||||
|
|
||||||
|
// create zone identifer file stream and then write the Mark of the Web to it
|
||||||
|
if ((ofd = open(fileStreamPath, O_WRONLY | O_CREAT, USHRT_MAX)) == -1) {
|
||||||
|
status = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atomicio(vwrite, ofd, zoneIdentifierStr, zoneIndentifierLen) != zoneIndentifierLen) {
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close(ofd) == -1) {
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(fileStreamPath);
|
||||||
|
if (zoneIdentifierStr)
|
||||||
|
free(zoneIdentifierStr);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the zone identifier value based on the provided hostname,
|
||||||
|
and sets the global motw_zone_id variable with that value. */
|
||||||
|
void get_zone_identifier(const char* hostname) {
|
||||||
|
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
debug("CoInitializeEx for MapUrlToZone failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IInternetSecurityManager *pIISM = NULL;
|
||||||
|
// CLSID_InternetSecurityManager & IID_IInternetSecurityManager declared in urlmon.h
|
||||||
|
hr = CoCreateInstance(&CLSID_InternetSecurityManager, NULL,
|
||||||
|
CLSCTX_ALL, &IID_IInternetSecurityManager, (void**)&pIISM);
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
debug("CoCreateInstance for MapUrlToZone failed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
wchar_t *hostname_w = NULL, *hostformat_w = NULL;
|
||||||
|
hostname_w = utf8_to_utf16(hostname);
|
||||||
|
if (hostname_w == NULL) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
size_t hostname_w_len = wcslen(hostname_w) + wcslen(L"ftp://") + 1;
|
||||||
|
hostformat_w = malloc(hostname_w_len * sizeof(wchar_t));
|
||||||
|
if (hostformat_w == NULL) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
swprintf_s(hostformat_w, hostname_w_len, L"ftp://%s", hostname_w);
|
||||||
|
hr = pIISM->lpVtbl->MapUrlToZone(pIISM, hostformat_w, &motw_zone_id, 0);
|
||||||
|
if (hr == S_OK) {
|
||||||
|
debug("MapUrlToZone zone identifier value: %d", motw_zone_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
motw_zone_id = 5;
|
||||||
|
debug("MapUrlToZone failed, resetting motw_zone_id to invalid value");
|
||||||
|
}
|
||||||
|
cleanup:
|
||||||
|
if (pIISM)
|
||||||
|
pIISM->lpVtbl->Release(pIISM);
|
||||||
|
if (hostname_w)
|
||||||
|
free(hostname_w);
|
||||||
|
if (hostformat_w)
|
||||||
|
free(hostformat_w);
|
||||||
|
out:
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
@ -49,6 +49,9 @@ extern char* chroot_path;
|
|||||||
extern int chroot_path_len;
|
extern int chroot_path_len;
|
||||||
extern wchar_t* chroot_pathw;
|
extern wchar_t* chroot_pathw;
|
||||||
|
|
||||||
|
/* motw zone_id */
|
||||||
|
extern DWORD motw_zone_id;
|
||||||
|
|
||||||
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
|
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
|
||||||
wchar_t * resolved_path_utf16(const char *);
|
wchar_t * resolved_path_utf16(const char *);
|
||||||
char* resolved_path_utf8(const char *);
|
char* resolved_path_utf8(const char *);
|
||||||
@ -82,4 +85,6 @@ wchar_t* get_final_path_by_handle(HANDLE h);
|
|||||||
int lookup_principal_name(const wchar_t * sam_account_name, wchar_t * user_principal_name);
|
int lookup_principal_name(const wchar_t * sam_account_name, wchar_t * user_principal_name);
|
||||||
BOOL is_bash_test_env();
|
BOOL is_bash_test_env();
|
||||||
int bash_to_win_path(const char *in, char *out, const size_t out_len);
|
int bash_to_win_path(const char *in, char *out, const size_t out_len);
|
||||||
void debug_assert_internal();
|
void debug_assert_internal();
|
||||||
|
int add_mark_of_web(const char* filename);
|
||||||
|
void get_zone_identifier(const char* hostname);
|
||||||
|
15
scp.c
15
scp.c
@ -135,6 +135,9 @@
|
|||||||
|
|
||||||
#include "sftp-common.h"
|
#include "sftp-common.h"
|
||||||
#include "sftp-client.h"
|
#include "sftp-client.h"
|
||||||
|
#ifdef WINDOWS
|
||||||
|
#include "misc_internal.h"
|
||||||
|
#endif // WINDOWS
|
||||||
|
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
@ -1138,6 +1141,9 @@ do_sftp_connect(char *host, char *user, int port, char *sftp_direct,
|
|||||||
reminp, remoutp, pidp) < 0)
|
reminp, remoutp, pidp) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef WINDOWS
|
||||||
|
get_zone_identifier(host);
|
||||||
|
#endif // WINDOWS
|
||||||
return do_init(*reminp, *remoutp, 32768, 64, limit_kbps);
|
return do_init(*reminp, *remoutp, 32768, 64, limit_kbps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,6 +1442,9 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* SCP */
|
/* SCP */
|
||||||
|
#ifdef WINDOWS
|
||||||
|
get_zone_identifier(host);
|
||||||
|
#endif // WINDOWS
|
||||||
xasprintf(&bp, "%s -f %s%s",
|
xasprintf(&bp, "%s -f %s%s",
|
||||||
cmd, *src == '-' ? "-- " : "", src);
|
cmd, *src == '-' ? "-- " : "", src);
|
||||||
if (do_cmd(ssh_program, host, suser, sport, 0, bp,
|
if (do_cmd(ssh_program, host, suser, sport, 0, bp,
|
||||||
@ -2074,6 +2083,12 @@ sink(int argc, char **argv, const char *src)
|
|||||||
omode = mode;
|
omode = mode;
|
||||||
mode |= S_IWUSR;
|
mode |= S_IWUSR;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
if (add_mark_of_web(np) == -1) {
|
||||||
|
if (verbose_mode) {
|
||||||
|
note_err("%s: add_mark_of_web failed\n", np);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// In windows, we would like to inherit the parent folder permissions by setting mode to USHRT_MAX.
|
// In windows, we would like to inherit the parent folder permissions by setting mode to USHRT_MAX.
|
||||||
if ((ofd = open(np, O_WRONLY|O_CREAT, USHRT_MAX)) == -1) {
|
if ((ofd = open(np, O_WRONLY|O_CREAT, USHRT_MAX)) == -1) {
|
||||||
#else
|
#else
|
||||||
|
@ -1727,6 +1727,11 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (add_mark_of_web(local_path) == -1) {
|
||||||
|
debug("%s: failed to add mark of the web", local_path);
|
||||||
|
}
|
||||||
|
#endif // WINDOWS
|
||||||
sshbuf_free(msg);
|
sshbuf_free(msg);
|
||||||
free(handle);
|
free(handle);
|
||||||
|
|
||||||
|
@ -54,6 +54,9 @@
|
|||||||
|
|
||||||
#include "sftp.h"
|
#include "sftp.h"
|
||||||
#include "sftp-common.h"
|
#include "sftp-common.h"
|
||||||
|
#ifdef WINDOWS
|
||||||
|
#include "misc_internal.h"
|
||||||
|
#endif // WINDOWS
|
||||||
|
|
||||||
char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
|
char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
|
||||||
|
|
||||||
@ -863,6 +866,19 @@ process_write(u_int32_t id)
|
|||||||
(r = sshbuf_get_string(iqueue, &data, &len)) != 0)
|
(r = sshbuf_get_string(iqueue, &data, &len)) != 0)
|
||||||
fatal_fr(r, "parse");
|
fatal_fr(r, "parse");
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
char* filepath = resolved_path_utf8(handle_to_name(handle));
|
||||||
|
if (filepath == NULL) {
|
||||||
|
debug("cannot convert handle %d to utf8 filepath for mark of the web", handle);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (add_mark_of_web(filepath) == -1) {
|
||||||
|
debug("add_mark_of_web to %s failed", filepath);
|
||||||
|
}
|
||||||
|
free(filepath);
|
||||||
|
}
|
||||||
|
#endif // WINDOWS
|
||||||
|
|
||||||
debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
|
debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
|
||||||
id, handle_to_name(handle), handle, (unsigned long long)off, len);
|
id, handle_to_name(handle), handle, (unsigned long long)off, len);
|
||||||
fd = handle_to_fd(handle);
|
fd = handle_to_fd(handle);
|
||||||
@ -1897,6 +1913,10 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||||||
logit("session opened for local user %s from [%s]",
|
logit("session opened for local user %s from [%s]",
|
||||||
pw->pw_name, client_addr);
|
pw->pw_name, client_addr);
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
get_zone_identifier(client_addr);
|
||||||
|
#endif // WINDOWS
|
||||||
|
|
||||||
in = STDIN_FILENO;
|
in = STDIN_FILENO;
|
||||||
out = STDOUT_FILENO;
|
out = STDOUT_FILENO;
|
||||||
|
|
||||||
|
3
sftp.c
3
sftp.c
@ -2637,6 +2637,9 @@ main(int argc, char **argv)
|
|||||||
freeargs(&args);
|
freeargs(&args);
|
||||||
|
|
||||||
conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
|
conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
|
||||||
|
#ifdef WINDOWS
|
||||||
|
get_zone_identifier(host);
|
||||||
|
#endif //WINDOWS
|
||||||
if (conn == NULL)
|
if (conn == NULL)
|
||||||
fatal("Couldn't initialise connection to server");
|
fatal("Couldn't initialise connection to server");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user