mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-23 14:04:59 +02:00
added support to run shellhost with -notty
This commit is contained in:
parent
bc83d7d29e
commit
08cda06aa2
@ -1047,7 +1047,7 @@ cleanup:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmain(int ac, wchar_t **av) {
|
||||
int start_with_pty(int ac, wchar_t **av) {
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
wchar_t cmd[MAX_PATH];
|
||||
@ -1076,18 +1076,6 @@ int wmain(int ac, wchar_t **av) {
|
||||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
/* create job to hold all child processes */
|
||||
{
|
||||
/* TODO - this does not work as expected*/
|
||||
HANDLE job = CreateJobObject(NULL, NULL);
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info;
|
||||
memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
|
||||
job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info)))
|
||||
return -1;
|
||||
CloseHandle(job);
|
||||
}
|
||||
|
||||
/* WM_APPEXIT */
|
||||
hostThreadId = GetCurrentThreadId();
|
||||
hostProcessId = GetCurrentProcessId();
|
||||
@ -1170,3 +1158,177 @@ cleanup:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLE child_pipe_read;
|
||||
HANDLE child_pipe_write;
|
||||
DWORD WINAPI MonitorChild_nopty(
|
||||
_In_ LPVOID lpParameter
|
||||
) {
|
||||
WaitForSingleObject(child, INFINITE);
|
||||
CloseHandle(pipe_in);
|
||||
//printf("XXXX CHILD PROCESS DEAD XXXXX");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int start_withno_pty(int ac, wchar_t **av) {
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
wchar_t cmd[MAX_PATH];
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
BOOL ret;
|
||||
|
||||
pipe_in = GetStdHandle(STD_INPUT_HANDLE);
|
||||
pipe_out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
pipe_err = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
/* copy pipe handles passed through std io*/
|
||||
if ((pipe_in == INVALID_HANDLE_VALUE)
|
||||
|| (pipe_out == INVALID_HANDLE_VALUE)
|
||||
|| (pipe_err == INVALID_HANDLE_VALUE))
|
||||
return -1;
|
||||
|
||||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
sa.bInheritHandle = TRUE;
|
||||
if (!CreatePipe(&child_pipe_read, &child_pipe_write, &sa, 128))
|
||||
return -1;
|
||||
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = child_pipe_read;
|
||||
si.hStdOutput = pipe_out;
|
||||
si.hStdError = pipe_err;
|
||||
|
||||
/* disable inheritance on child_pipe_write and pipe_in*/
|
||||
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0));
|
||||
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(child_pipe_write, HANDLE_FLAG_INHERIT, 0));
|
||||
|
||||
/*TODO - pick this up from system32*/
|
||||
cmd[0] = L'\0';
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L"cmd.exe"));
|
||||
ac -= 2;
|
||||
av += 2;
|
||||
if (ac)
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" /c"));
|
||||
while (ac) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av));
|
||||
ac--;
|
||||
av++;
|
||||
}
|
||||
|
||||
GOTO_CLEANUP_ON_FALSE(CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi));
|
||||
|
||||
/* close unwanted handles*/
|
||||
CloseHandle(child_pipe_read);
|
||||
child_pipe_read = INVALID_HANDLE_VALUE;
|
||||
|
||||
child = pi.hProcess;
|
||||
/* monitor child exist */
|
||||
monitor_thread = CreateThread(NULL, 0, MonitorChild_nopty, NULL, 0, NULL);
|
||||
if (monitor_thread == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
|
||||
/* disable Ctrl+C hander in this process*/
|
||||
SetConsoleCtrlHandler(NULL, TRUE);
|
||||
|
||||
/* process data from pipe_in and route appropriately */
|
||||
while (1) {
|
||||
char buf[128];
|
||||
DWORD rd = 0, wr = 0, i = 0;
|
||||
GOTO_CLEANUP_ON_FALSE(ReadFile(pipe_in, buf, 128, &rd, NULL));
|
||||
|
||||
while (i < rd) {
|
||||
|
||||
/* skip arrow keys */
|
||||
if ((rd - i >= 3) && (buf[i] == '\033') && (buf[i + 1] == '[')
|
||||
&& (buf[i + 2] >= 'A') && (buf[i + 2] <= 'D')) {
|
||||
i += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip tab */
|
||||
if (buf[i] == '\t') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ctrl +C
|
||||
if (buf[i] == '\003') {
|
||||
GOTO_CLEANUP_ON_FALSE(GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0));
|
||||
in_cmd_len = 0;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// for backspace, we need to send space and another backspace for visual erase
|
||||
if (buf[i] == '\b') {
|
||||
if (in_cmd_len > 0) {
|
||||
GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, "\b \b", 3, &wr, NULL));
|
||||
in_cmd_len--;
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//for CR and LF
|
||||
if ((buf[i] == '\r') || (buf[i] == '\n')) {
|
||||
|
||||
/* TODO - do a much accurate mapping */
|
||||
GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL));
|
||||
if ((buf[i] == '\r') && ((i == rd - 1) || (buf[i + 1] != '\n'))) {
|
||||
buf[i] = '\n';
|
||||
GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL));
|
||||
}
|
||||
in_cmd[in_cmd_len] = buf[i];
|
||||
in_cmd_len++;
|
||||
GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, in_cmd, in_cmd_len, &wr, NULL));
|
||||
in_cmd_len = 0;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL));
|
||||
in_cmd[in_cmd_len] = buf[i];
|
||||
in_cmd_len++;
|
||||
if (in_cmd_len == MAX_CMD_LEN - 1) {
|
||||
GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, in_cmd, in_cmd_len, &wr, NULL));
|
||||
in_cmd_len = 0;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if (child != INVALID_HANDLE_VALUE)
|
||||
TerminateProcess(child, 0);
|
||||
if (monitor_thread != INVALID_HANDLE_VALUE)
|
||||
WaitForSingleObject(monitor_thread, INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmain(int ac, wchar_t **av) {
|
||||
|
||||
|
||||
/* create job to hold all child processes */
|
||||
{
|
||||
/* TODO - this does not work as expected*/
|
||||
HANDLE job = CreateJobObject(NULL, NULL);
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info;
|
||||
memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
|
||||
job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info)))
|
||||
return -1;
|
||||
CloseHandle(job);
|
||||
}
|
||||
|
||||
if ((ac == 1) || wcscmp(av[1], L"-nopty"))
|
||||
return start_with_pty(ac, av);
|
||||
else
|
||||
return start_withno_pty(ac, av);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user