mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-28 08:14:24 +02:00
New SSH connections have updated environment variables (#509)
This commit is contained in:
parent
0d88c342a5
commit
66b991a47c
@ -24,6 +24,7 @@ if ($TestFilePath) {
|
|||||||
# convert to bash format
|
# convert to bash format
|
||||||
$TestFilePath = $TestFilePath -replace "\\","/"
|
$TestFilePath = $TestFilePath -replace "\\","/"
|
||||||
}
|
}
|
||||||
|
$OriginalUserPath = [System.Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::User)
|
||||||
|
|
||||||
# Make sure config.h exists. It is used in some bashstests (Ex - sftp-glob.sh, cfgparse.sh)
|
# Make sure config.h exists. It is used in some bashstests (Ex - sftp-glob.sh, cfgparse.sh)
|
||||||
# first check in $BashTestsPath folder. If not then it's parent folder. If not then in the $OpenSSHBinPath
|
# first check in $BashTestsPath folder. If not then it's parent folder. If not then in the $OpenSSHBinPath
|
||||||
@ -101,6 +102,10 @@ try
|
|||||||
$env:path = $TEST_SHELL_DIR + ";" + $env:path
|
$env:path = $TEST_SHELL_DIR + ";" + $env:path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Prepend shell path to User PATH in the registry so that SSHD authenticated child process can inherit it.
|
||||||
|
# We can probably delete the logic above to add it to the process PATH, but there is no need.
|
||||||
|
[System.Environment]::SetEnvironmentVariable('Path', $TEST_SHELL_DIR + ";" + $OriginalUserPath, [System.EnvironmentVariableTarget]::User)
|
||||||
|
|
||||||
$BashTestsPath = $BashTestsPath -replace "\\","/"
|
$BashTestsPath = $BashTestsPath -replace "\\","/"
|
||||||
Push-location $BashTestsPath
|
Push-location $BashTestsPath
|
||||||
|
|
||||||
@ -254,6 +259,8 @@ try
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
# Restore User Path variable in the registry once the tests finish running.
|
||||||
|
[System.Environment]::SetEnvironmentVariable('Path', $OriginalUserPath, [System.EnvironmentVariableTarget]::User)
|
||||||
# remove temp test directory
|
# remove temp test directory
|
||||||
if (!$SkipCleanup)
|
if (!$SkipCleanup)
|
||||||
{
|
{
|
||||||
|
@ -78,8 +78,30 @@ do_setup_env_proxy(struct ssh *, Session *, const char *);
|
|||||||
goto cleanup; \
|
goto cleanup; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
static char*
|
||||||
|
get_registry_operation_error_message(const LONG error_code)
|
||||||
|
{
|
||||||
|
char* message = NULL;
|
||||||
|
wchar_t* wmessage = NULL;
|
||||||
|
DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error_code, 0, (wchar_t*)&wmessage, 0, NULL);
|
||||||
|
if (length == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (wmessage[length - 1] == L'\n')
|
||||||
|
wmessage[length - 1] = L'\0';
|
||||||
|
if (length > 1 && wmessage[length - 2] == L'\r')
|
||||||
|
wmessage[length - 2] = L'\0';
|
||||||
|
|
||||||
|
message = utf16_to_utf8(wmessage);
|
||||||
|
LocalFree(wmessage);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO - built env var set and pass it along with CreateProcess */
|
/* TODO - built env var set and pass it along with CreateProcess */
|
||||||
/* set user environment variables from user profile */
|
/* Set environment variables with values from the registry */
|
||||||
|
/* Ensure that environment of new connections reflect the current state of the machine */
|
||||||
static void
|
static void
|
||||||
setup_session_user_vars(wchar_t* profile_path)
|
setup_session_user_vars(wchar_t* profile_path)
|
||||||
{
|
{
|
||||||
@ -90,6 +112,10 @@ setup_session_user_vars(wchar_t* profile_path)
|
|||||||
wchar_t *data = NULL, *data_expanded = NULL, *path_value = NULL, *to_apply;
|
wchar_t *data = NULL, *data_expanded = NULL, *path_value = NULL, *to_apply;
|
||||||
DWORD type, name_chars = 256, data_chars = 0, data_expanded_chars = 0, required, i = 0;
|
DWORD type, name_chars = 256, data_chars = 0, data_expanded_chars = 0, required, i = 0;
|
||||||
LONG ret;
|
LONG ret;
|
||||||
|
char *error_message;
|
||||||
|
|
||||||
|
/*These whitelisted environment variables should not be overwritten with the value from the registry*/
|
||||||
|
wchar_t* whitelist[] = { L"PROCESSOR_ARCHITECTURE", L"USERNAME" };
|
||||||
|
|
||||||
SetEnvironmentVariableW(L"USERPROFILE", profile_path);
|
SetEnvironmentVariableW(L"USERPROFILE", profile_path);
|
||||||
|
|
||||||
@ -108,65 +134,102 @@ setup_session_user_vars(wchar_t* profile_path)
|
|||||||
swprintf_s(path, _countof(path), L"%s\\AppData\\Roaming", profile_path);
|
swprintf_s(path, _countof(path), L"%s\\AppData\\Roaming", profile_path);
|
||||||
SetEnvironmentVariableW(L"APPDATA", path);
|
SetEnvironmentVariableW(L"APPDATA", path);
|
||||||
|
|
||||||
ret = RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key);
|
for (int j = 0; j < 2; j++)
|
||||||
if (ret != ERROR_SUCCESS)
|
{
|
||||||
//error("Error retrieving user environment variables. RegOpenKeyExW returned %d", ret);
|
/* First update the environment variables with the value from the System Environment, and then User. */
|
||||||
return;
|
/* User variables overwrite the value of system variables with the same name (Except Path) */
|
||||||
else while (1) {
|
if (j == 0)
|
||||||
to_apply = NULL;
|
ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, ®_key);
|
||||||
required = data_chars * sizeof(wchar_t);
|
else
|
||||||
name_chars = 256;
|
ret = RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key);
|
||||||
ret = RegEnumValueW(reg_key, i++, name, &name_chars, 0, &type, (LPBYTE)data, &required);
|
|
||||||
if (ret == ERROR_NO_MORE_ITEMS)
|
if (ret != ERROR_SUCCESS) {
|
||||||
break;
|
error_message = get_registry_operation_error_message(ret);
|
||||||
else if (ret == ERROR_MORE_DATA || required > data_chars * 2) {
|
error("Unable to open Registry Key %s. %s", (j == 0 ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER"), error_message);
|
||||||
if (data != NULL)
|
if (error_message)
|
||||||
free(data);
|
free(error_message);
|
||||||
data = xmalloc(required);
|
|
||||||
data_chars = required / 2;
|
|
||||||
i--;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ret != ERROR_SUCCESS)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (type == REG_SZ)
|
while (1) {
|
||||||
to_apply = data;
|
to_apply = NULL;
|
||||||
else if (type == REG_EXPAND_SZ) {
|
required = data_chars * sizeof(wchar_t);
|
||||||
required = ExpandEnvironmentStringsW(data, data_expanded, data_expanded_chars);
|
name_chars = 256;
|
||||||
if (required > data_expanded_chars) {
|
ret = RegEnumValueW(reg_key, i++, name, &name_chars, 0, &type, (LPBYTE)data, &required);
|
||||||
if (data_expanded)
|
if (ret == ERROR_NO_MORE_ITEMS)
|
||||||
free(data_expanded);
|
break;
|
||||||
data_expanded = xmalloc(required * 2);
|
else if (ret == ERROR_MORE_DATA || required > data_chars * 2) {
|
||||||
data_expanded_chars = required;
|
if (data != NULL)
|
||||||
ExpandEnvironmentStringsW(data, data_expanded, data_expanded_chars);
|
free(data);
|
||||||
|
data = xmalloc(required);
|
||||||
|
data_chars = required / 2;
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
to_apply = data_expanded;
|
else if (ret != ERROR_SUCCESS) {
|
||||||
}
|
error_message = get_registry_operation_error_message(ret);
|
||||||
|
error("Failed to enumerate the value for registry key %s. %s", (j == 0 ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER"), error_message);
|
||||||
if (_wcsicmp(name, L"PATH") == 0) {
|
if (error_message)
|
||||||
if ((required = GetEnvironmentVariableW(L"PATH", NULL, 0)) != 0) {
|
free(error_message);
|
||||||
/* "required" includes null term */
|
break;
|
||||||
path_value = xmalloc((wcslen(to_apply) + 1 + required) * 2);
|
|
||||||
GetEnvironmentVariableW(L"PATH", path_value, required);
|
|
||||||
path_value[required - 1] = L';';
|
|
||||||
GOTO_CLEANUP_ON_ERR(memcpy_s(path_value + required, (wcslen(to_apply) + 1) * 2, to_apply, (wcslen(to_apply) + 1) * 2));
|
|
||||||
to_apply = path_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == REG_SZ)
|
||||||
|
to_apply = data;
|
||||||
|
else if (type == REG_EXPAND_SZ) {
|
||||||
|
required = ExpandEnvironmentStringsW(data, data_expanded, data_expanded_chars);
|
||||||
|
if (required > data_expanded_chars) {
|
||||||
|
if (data_expanded)
|
||||||
|
free(data_expanded);
|
||||||
|
data_expanded = xmalloc(required * 2);
|
||||||
|
data_expanded_chars = required;
|
||||||
|
ExpandEnvironmentStringsW(data, data_expanded, data_expanded_chars);
|
||||||
|
}
|
||||||
|
to_apply = data_expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure that variables in the whitelist are not being overwritten with the value from the registry */
|
||||||
|
for (int k = 0; k < ARRAYSIZE(whitelist); k++) {
|
||||||
|
if (_wcsicmp(name, whitelist[k]) == 0)
|
||||||
|
{
|
||||||
|
to_apply = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Path is a special case. The System Path value is appended to the User Path value */
|
||||||
|
if (_wcsicmp(name, L"PATH") == 0 && j == 1) {
|
||||||
|
if ((required = GetEnvironmentVariableW(L"PATH", NULL, 0)) != 0) {
|
||||||
|
size_t user_path_size = wcslen(to_apply);
|
||||||
|
path_value = xmalloc((required + user_path_size + 2) * 2);
|
||||||
|
GOTO_CLEANUP_ON_ERR(memcpy_s(path_value, (user_path_size + 1) * 2, to_apply, (user_path_size + 1) * 2));
|
||||||
|
path_value[user_path_size] = L';';
|
||||||
|
GetEnvironmentVariableW(L"PATH", path_value + user_path_size + 1, required);
|
||||||
|
to_apply = path_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_apply)
|
||||||
|
SetEnvironmentVariableW(name, to_apply);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (to_apply)
|
cleanup:
|
||||||
SetEnvironmentVariableW(name, to_apply);
|
if (reg_key)
|
||||||
|
RegCloseKey(reg_key);
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
if (data_expanded)
|
||||||
|
free(data_expanded);
|
||||||
|
if (path_value)
|
||||||
|
free(path_value);
|
||||||
|
i = 0;
|
||||||
|
data = NULL;
|
||||||
|
data_expanded = NULL;
|
||||||
|
path_value = NULL;
|
||||||
|
name_chars = 256;
|
||||||
|
data_chars = 0;
|
||||||
|
data_expanded_chars = 0;
|
||||||
|
reg_key = 0;
|
||||||
}
|
}
|
||||||
cleanup:
|
|
||||||
if (reg_key)
|
|
||||||
RegCloseKey(reg_key);
|
|
||||||
if (data)
|
|
||||||
free(data);
|
|
||||||
if (data_expanded)
|
|
||||||
free(data_expanded);
|
|
||||||
if (path_value)
|
|
||||||
free(path_value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user