-
Notifications
You must be signed in to change notification settings - Fork 166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new config option to support thread token based agent process to … #133
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,11 +76,18 @@ | |
* See https://github.com/rprichard/winpty/issues/58. */ | ||
#define WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION 0x8ull | ||
|
||
/* Create agent proces from the thread token instead of current process. | ||
* This is usefull when winpty.dll is called by Windows Service program to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/usefull/useful There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
* impersonate to the original user from a remote process. | ||
* See https://github.com/rprichard/winpty/issues/132. */ | ||
#define WINPTY_FLAG_IMPERSONATE_THREAD 0x10ull | ||
|
||
#define WINPTY_FLAG_MASK (0ull \ | ||
| WINPTY_FLAG_CONERR \ | ||
| WINPTY_FLAG_PLAIN_OUTPUT \ | ||
| WINPTY_FLAG_COLOR_ESCAPES \ | ||
| WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION \ | ||
| WINPTY_FLAG_IMPERSONATE_THREAD \ | ||
) | ||
|
||
/* QuickEdit mode is initially disabled, and the agent does not send mouse | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -470,6 +470,7 @@ static bool shouldSpecifyHideFlag() { | |
} | ||
|
||
static OwnedHandle startAgentProcess( | ||
const winpty_config_t *cfg, | ||
const std::wstring &desktop, | ||
const std::wstring &controlPipeName, | ||
const std::wstring ¶ms, | ||
|
@@ -494,24 +495,92 @@ static OwnedHandle startAgentProcess( | |
sui.dwFlags |= STARTF_USESHOWWINDOW; | ||
sui.wShowWindow = SW_HIDE; | ||
} | ||
|
||
PROCESS_INFORMATION pi = {}; | ||
const BOOL success = | ||
CreateProcessW(exePath.c_str(), | ||
cmdlineV.data(), | ||
nullptr, nullptr, | ||
/*bInheritHandles=*/FALSE, | ||
/*dwCreationFlags=*/creationFlags, | ||
nullptr, nullptr, | ||
&sui, &pi); | ||
if (!success) { | ||
const DWORD lastError = GetLastError(); | ||
const auto errStr = | ||
(WStringBuilder(256) | ||
<< L"winpty-agent CreateProcess failed: cmdline='" << cmdline | ||
<< L"' err=0x" << whexOfInt(lastError)).str_moved(); | ||
throw LibWinptyException( | ||
WINPTY_ERROR_AGENT_CREATION_FAILED, errStr.c_str()); | ||
if (cfg->flags & WINPTY_FLAG_IMPERSONATE_THREAD) { | ||
HRESULT hr; | ||
HANDLE token = nullptr; | ||
if (!OpenThreadToken( | ||
GetCurrentThread(), | ||
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, | ||
FALSE, | ||
&token)) | ||
{ | ||
const DWORD lastError = GetLastError(); | ||
const auto errStr = | ||
(WStringBuilder(256) | ||
<< L"winpty-agent OpenThreadToken failed: cmdline='" << cmdline | ||
<< L"' err=0x" << whexOfInt(lastError)).str_moved(); | ||
throw LibWinptyException( | ||
WINPTY_ERROR_AGENT_CREATION_FAILED, errStr.c_str()); | ||
} | ||
|
||
HANDLE dupToken = nullptr; | ||
if (!DuplicateTokenEx( | ||
token, | ||
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, | ||
NULL, | ||
SecurityImpersonation, | ||
TokenPrimary, | ||
&dupToken)) | ||
{ | ||
CloseHandle(token); | ||
const DWORD lastError = GetLastError(); | ||
const auto errStr = | ||
(WStringBuilder(256) | ||
<< L"winpty-agent DuplicateTokenEx failed: cmdline='" << cmdline | ||
<< L"' err=0x" << whexOfInt(lastError)).str_moved(); | ||
throw LibWinptyException( | ||
WINPTY_ERROR_AGENT_CREATION_FAILED, errStr.c_str()); | ||
} | ||
|
||
DWORD exitCode = 0; | ||
const BOOL success = CreateProcessAsUser( | ||
dupToken, | ||
exePath.c_str(), | ||
cmdlineV.data(), | ||
nullptr, | ||
nullptr, | ||
FALSE, | ||
CREATE_DEFAULT_ERROR_MODE | CREATE_BREAKAWAY_FROM_JOB | CREATE_UNICODE_ENVIRONMENT | NORMAL_PRIORITY_CLASS, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious about these creation flags.
|
||
nullptr, | ||
nullptr, | ||
&sui, | ||
&pi); | ||
if (!success) { | ||
CloseHandle(token); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer this code use RAII (i.e. OwnedHandle), but I can fix that up myself after merging the change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. left as is. |
||
CloseHandle(dupToken); | ||
const DWORD lastError = GetLastError(); | ||
const auto errStr = | ||
(WStringBuilder(256) | ||
<< L"winpty-agent CreateProcessAsUser failed: cmdline='" << cmdline | ||
<< L"' err=0x" << whexOfInt(lastError)).str_moved(); | ||
throw LibWinptyException( | ||
WINPTY_ERROR_AGENT_CREATION_FAILED, errStr.c_str()); | ||
} | ||
|
||
CloseHandle(token); | ||
CloseHandle(dupToken); | ||
} else { | ||
const BOOL success = | ||
CreateProcessW(exePath.c_str(), | ||
cmdlineV.data(), | ||
nullptr, nullptr, | ||
/*bInheritHandles=*/FALSE, | ||
/*dwCreationFlags=*/creationFlags, | ||
nullptr, nullptr, | ||
&sui, &pi); | ||
if (!success) { | ||
const DWORD lastError = GetLastError(); | ||
const auto errStr = | ||
(WStringBuilder(256) | ||
<< L"winpty-agent CreateProcess failed: cmdline='" << cmdline | ||
<< L"' err=0x" << whexOfInt(lastError)).str_moved(); | ||
throw LibWinptyException( | ||
WINPTY_ERROR_AGENT_CREATION_FAILED, errStr.c_str()); | ||
} | ||
} | ||
|
||
CloseHandle(pi.hThread); | ||
TRACE("Created agent successfully, pid=%u, cmdline=%s", | ||
static_cast<unsigned int>(pi.dwProcessId), | ||
|
@@ -556,7 +625,7 @@ createAgentSession(const winpty_config_t *cfg, | |
|
||
DWORD agentPid = 0; | ||
wp->agentProcess = startAgentProcess( | ||
desktop, pipeName, params, creationFlags, agentPid); | ||
cfg, desktop, pipeName, params, creationFlags, agentPid); | ||
connectControlPipe(*wp.get()); | ||
verifyPipeClientPid(wp->controlPipe.get(), agentPid); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/proces/process
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done