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 lastX = 0;
|
||||||
static SHORT lastY = 0;
|
static SHORT lastY = 0;
|
||||||
static wchar_t system32_path[PATH_MAX];
|
static wchar_t system32_path[PATH_MAX + 1] = { 0, };
|
||||||
static wchar_t cmd_exe_path[PATH_MAX];
|
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;
|
SHORT currentLine = 0;
|
||||||
consoleEvent* head = NULL;
|
consoleEvent* head = NULL;
|
||||||
|
@ -1192,19 +1195,70 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *
|
wchar_t *
|
||||||
w32_cmd_path()
|
get_default_shell_path()
|
||||||
{
|
{
|
||||||
|
HKEY reg_key = 0;
|
||||||
|
int tmp_len = PATH_MAX;
|
||||||
errno_t r = 0;
|
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) {
|
REGSAM mask = STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY;
|
||||||
printf_s("wcsncpy_s failed with error: %d.", r);
|
wchar_t *tmp = malloc(PATH_MAX + 1);
|
||||||
|
|
||||||
|
if (!tmp) {
|
||||||
|
printf_s("get_default_shell_path(), Unable to allocate memory");
|
||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = wcscat_s(cmd_exe_path, _countof(cmd_exe_path), L"\\cmd.exe")) != 0) {
|
memset(tmp, 0, PATH_MAX + 1);
|
||||||
printf_s("wcscat_s failed with error: %d.", r);
|
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);
|
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
|
int
|
||||||
|
@ -1280,10 +1334,24 @@ start_with_pty(wchar_t *command)
|
||||||
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0));
|
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0));
|
||||||
|
|
||||||
cmd[0] = L'\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) {
|
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));
|
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);
|
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 above failed with FILE_NOT_FOUND, try running the provided command under cmd*/
|
||||||
if (run_under_cmd) {
|
if (run_under_cmd) {
|
||||||
cmd[0] = L'\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) {
|
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));
|
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)'
|
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 {
|
BeforeEach {
|
||||||
|
@ -98,7 +110,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Context "$tC - exit code (exit-status.sh)" {
|
Context "$tC - exit code (exit-status.sh)" {
|
||||||
BeforeAll {$tI=1}
|
BeforeAll {$tI=1}
|
||||||
AfterAll{$tC++}
|
AfterAll{$tC++}
|
||||||
|
@ -131,8 +143,36 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
|
||||||
0 | ssh -p $port $ssouser@$server pause
|
0 | ssh -p $port $ssouser@$server pause
|
||||||
$true | Should Be $true
|
$true | Should Be $true
|
||||||
}#>
|
}#>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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" {
|
Context "$tC - cmdline parameters" {
|
||||||
|
|
||||||
BeforeAll {$tI=1}
|
BeforeAll {$tI=1}
|
||||||
|
|
Loading…
Reference in New Issue