allowing users to configure the default shell through windows registry (#215)
This commit is contained in:
parent
7a4a10a224
commit
9c95d8e2bb
|
@ -255,8 +255,11 @@ struct key_translation keys[] = {
|
|||
|
||||
static SHORT lastX = 0;
|
||||
static SHORT lastY = 0;
|
||||
static wchar_t system32_path[PATH_MAX];
|
||||
static wchar_t cmd_exe_path[PATH_MAX];
|
||||
static wchar_t system32_path[PATH_MAX + 1] = { 0, };
|
||||
static wchar_t cmd_exe_path[PATH_MAX + 1] = { 0, };
|
||||
static wchar_t default_shell_path[PATH_MAX + 3] = { 0, }; /* 2 - quotes, 1 - Null terminator */
|
||||
static wchar_t default_shell_cmd_option[10] = { 0, }; /* for cmd.exe/powershell it is "/c", for bash.exe it is "-c" */
|
||||
static BOOL is_default_shell_configured = FALSE;
|
||||
|
||||
SHORT currentLine = 0;
|
||||
consoleEvent* head = NULL;
|
||||
|
@ -1192,19 +1195,70 @@ cleanup:
|
|||
}
|
||||
|
||||
wchar_t *
|
||||
w32_cmd_path()
|
||||
get_default_shell_path()
|
||||
{
|
||||
HKEY reg_key = 0;
|
||||
int tmp_len = PATH_MAX;
|
||||
errno_t r = 0;
|
||||
if ((r = wcsncpy_s(cmd_exe_path, _countof(cmd_exe_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1)) != 0) {
|
||||
printf_s("wcsncpy_s failed with error: %d.", r);
|
||||
REGSAM mask = STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY;
|
||||
wchar_t *tmp = malloc(PATH_MAX + 1);
|
||||
|
||||
if (!tmp) {
|
||||
printf_s("get_default_shell_path(), Unable to allocate memory");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if ((r = wcscat_s(cmd_exe_path, _countof(cmd_exe_path), L"\\cmd.exe")) != 0) {
|
||||
printf_s("wcscat_s failed with error: %d.", r);
|
||||
memset(tmp, 0, PATH_MAX + 1);
|
||||
memset(default_shell_path, 0, _countof(default_shell_path));
|
||||
|
||||
if ((RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\OpenSSH", 0, mask, ®_key) == ERROR_SUCCESS) &&
|
||||
(RegQueryValueExW(reg_key, L"DefaultShell", 0, NULL, (LPBYTE)tmp, &tmp_len) == ERROR_SUCCESS) &&
|
||||
(tmp)) {
|
||||
is_default_shell_configured = TRUE;
|
||||
|
||||
/* If required, add quotes to the default shell. */
|
||||
if (tmp[0] != L'"') {
|
||||
default_shell_path[0] = L'\"';
|
||||
wcscat_s(default_shell_path, _countof(default_shell_path), tmp);
|
||||
wcscat_s(default_shell_path, _countof(default_shell_path), L"\"");
|
||||
} else
|
||||
wcscat_s(default_shell_path, _countof(default_shell_path), tmp);
|
||||
|
||||
/* Fetch the default shell command option.
|
||||
* For cmd.exe/powershell.exe it is "/c", for bash.exe it is "-c".
|
||||
* For cmd.exe/powershell.exe/bash.exe, verify if present otherwise auto-populate.
|
||||
*/
|
||||
memset(tmp, 0, PATH_MAX + 1);
|
||||
|
||||
if ((RegQueryValueExW(reg_key, L"DefaultShellCommandOption", 0, NULL, (LPBYTE)tmp, &tmp_len) == ERROR_SUCCESS)) {
|
||||
wcscat_s(default_shell_cmd_option, _countof(default_shell_cmd_option), L" ");
|
||||
wcscat_s(default_shell_cmd_option, _countof(default_shell_cmd_option), tmp);
|
||||
wcscat_s(default_shell_cmd_option, _countof(default_shell_cmd_option), L" ");
|
||||
}
|
||||
}
|
||||
|
||||
if (((r = wcsncpy_s(cmd_exe_path, _countof(cmd_exe_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1)) != 0) ||
|
||||
((r = wcscat_s(cmd_exe_path, _countof(cmd_exe_path), L"\\cmd.exe")) != 0)) {
|
||||
printf_s("get_default_shell_path(), wcscat_s failed with error: %d.", r);
|
||||
exit(255);
|
||||
}
|
||||
return cmd_exe_path;
|
||||
|
||||
/* if default shell is not configured then use cmd.exe as the default shell */
|
||||
if (!is_default_shell_configured)
|
||||
wcscat_s(default_shell_path, _countof(default_shell_path), cmd_exe_path);
|
||||
|
||||
memset(default_shell_cmd_option, 0, _countof(default_shell_cmd_option));
|
||||
if (!default_shell_cmd_option[0]) {
|
||||
if (wcsstr(default_shell_path, L"cmd.exe") || wcsstr(default_shell_path, L"powershell.exe"))
|
||||
wcscat_s(default_shell_cmd_option, _countof(default_shell_cmd_option), L" /c ");
|
||||
else if (wcsstr(default_shell_path, L"bash.exe"))
|
||||
wcscat_s(default_shell_cmd_option, _countof(default_shell_cmd_option), L" -c ");
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
free(tmp);
|
||||
|
||||
return default_shell_path;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1280,10 +1334,24 @@ start_with_pty(wchar_t *command)
|
|||
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0));
|
||||
|
||||
cmd[0] = L'\0';
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, w32_cmd_path()));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, get_default_shell_path()));
|
||||
if (command) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c "));
|
||||
if(default_shell_cmd_option[0])
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, default_shell_cmd_option));
|
||||
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, command));
|
||||
} else {
|
||||
/* Launch the default shell through cmd.exe.
|
||||
* If we don't launch default shell through cmd.exe then the powershell colors are rendered badly to the ssh client.
|
||||
*/
|
||||
if (is_default_shell_configured) {
|
||||
wchar_t tmp_cmd[PATH_MAX + 1] = {0,};
|
||||
wcscat_s(tmp_cmd, _countof(tmp_cmd), cmd);
|
||||
cmd[0] = L'\0';
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, cmd_exe_path));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, tmp_cmd));
|
||||
}
|
||||
}
|
||||
|
||||
SetConsoleCtrlHandler(NULL, FALSE);
|
||||
|
@ -1454,9 +1522,11 @@ start_withno_pty(wchar_t *command)
|
|||
/* if above failed with FILE_NOT_FOUND, try running the provided command under cmd*/
|
||||
if (run_under_cmd) {
|
||||
cmd[0] = L'\0';
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, w32_cmd_path()));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, get_default_shell_path()));
|
||||
if (command) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c "));
|
||||
if (default_shell_cmd_option[0])
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, default_shell_cmd_option));
|
||||
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, command));
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,19 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
|
|||
Options = '-i $identifyFile -l $($server.localAdminUserName)'
|
||||
}
|
||||
)#>
|
||||
$defaultRegistryPath = "HKLM:\Software\OpenSSH"
|
||||
$registryKeyName = "DefaultShell"
|
||||
|
||||
function ConfigureDefaultShell {
|
||||
param([string]$default_shell_path)
|
||||
|
||||
if (!(Test-Path $defaultRegistryPath)) {
|
||||
New-Item -Path $defaultRegistryPath -Force | Out-Null
|
||||
New-ItemProperty -Path $defaultRegistryPath -Name $registryKeyName -Value $default_shell_path -PropertyType String -Force
|
||||
} else {
|
||||
New-ItemProperty -Path $defaultRegistryPath -Name $registryKeyName -Value $default_shell_path -PropertyType String -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
|
@ -133,6 +145,34 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
|
|||
}#>
|
||||
}
|
||||
|
||||
Context "$tC - configure default shell Scenarios" {
|
||||
BeforeAll {$tI=1}
|
||||
AfterAll{$tC++}
|
||||
AfterEach {
|
||||
Remove-ItemProperty -Name $registryKeyName -Path $defaultRegistryPath -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
It "$tC.$tI - default shell as powershell" {
|
||||
$shell_path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).path
|
||||
if($shell_path -ne $null) {
|
||||
ConfigureDefaultShell -default_shell_path $shell_path
|
||||
|
||||
$o = ssh test_target Write-Output 1234
|
||||
$o | Should Be "1234"
|
||||
}
|
||||
}
|
||||
|
||||
It "$tC.$tI - default shell as cmd" {
|
||||
$shell_path = (Get-Command cmd.exe -ErrorAction SilentlyContinue).path
|
||||
if($shell_path -ne $null) {
|
||||
ConfigureDefaultShell -default_shell_path $shell_path
|
||||
|
||||
$o = ssh test_target where cmd
|
||||
$o | Should Contain "cmd"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context "$tC - cmdline parameters" {
|
||||
|
||||
BeforeAll {$tI=1}
|
||||
|
|
Loading…
Reference in New Issue