New SSH connections have updated environment variables (#509)

This commit is contained in:
vthiebaut10 2022-02-04 12:58:11 -05:00 committed by GitHub
parent 0d88c342a5
commit 66b991a47c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 54 deletions

View File

@ -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)
{ {

View File

@ -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,11 +134,24 @@ 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);
for (int j = 0; j < 2; j++)
{
/* First update the environment variables with the value from the System Environment, and then User. */
/* User variables overwrite the value of system variables with the same name (Except Path) */
if (j == 0)
ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &reg_key);
else
ret = RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, &reg_key); ret = RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, &reg_key);
if (ret != ERROR_SUCCESS)
//error("Error retrieving user environment variables. RegOpenKeyExW returned %d", ret); if (ret != ERROR_SUCCESS) {
return; error_message = get_registry_operation_error_message(ret);
else while (1) { error("Unable to open Registry Key %s. %s", (j == 0 ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER"), error_message);
if (error_message)
free(error_message);
continue;
}
while (1) {
to_apply = NULL; to_apply = NULL;
required = data_chars * sizeof(wchar_t); required = data_chars * sizeof(wchar_t);
name_chars = 256; name_chars = 256;
@ -127,8 +166,13 @@ setup_session_user_vars(wchar_t* profile_path)
i--; i--;
continue; continue;
} }
else if (ret != ERROR_SUCCESS) 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 (error_message)
free(error_message);
break; break;
}
if (type == REG_SZ) if (type == REG_SZ)
to_apply = data; to_apply = data;
@ -144,21 +188,31 @@ setup_session_user_vars(wchar_t* profile_path)
to_apply = data_expanded; to_apply = data_expanded;
} }
if (_wcsicmp(name, L"PATH") == 0) { /* Ensure that variables in the whitelist are not being overwritten with the value from the registry */
if ((required = GetEnvironmentVariableW(L"PATH", NULL, 0)) != 0) { for (int k = 0; k < ARRAYSIZE(whitelist); k++) {
/* "required" includes null term */ if (_wcsicmp(name, whitelist[k]) == 0)
path_value = xmalloc((wcslen(to_apply) + 1 + required) * 2); {
GetEnvironmentVariableW(L"PATH", path_value, required); to_apply = NULL;
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;
} }
/* 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) if (to_apply)
SetEnvironmentVariableW(name, to_apply); SetEnvironmentVariableW(name, to_apply);
} }
cleanup: cleanup:
if (reg_key) if (reg_key)
RegCloseKey(reg_key); RegCloseKey(reg_key);
if (data) if (data)
@ -167,6 +221,15 @@ cleanup:
free(data_expanded); free(data_expanded);
if (path_value) if (path_value)
free(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;
}
} }
static int static int