Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Launch games under the correct user account on Windows - #600

Merged
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch
Dec 27, 2022
Merged

Launch games under the correct user account on Windows#600
ReenigneArcher merged 2 commits into
LizardByte:nightlyfrom
cgutman:unprivileged_launch

Conversation

@cgutman

@cgutmancgutman commented Dec 21, 2022

Copy link
Copy Markdown
Collaborator

Description

This implements a new platf::run_unprivileged() function that can be used (on Windows, currently) to launch a process as the active console user (including their environment variables).

In order to make this work, I had to fix issues with the way we derive the working directory if one is not provided. That required adding a dependency on libboost-program-options for boost::program_options::split_unix() to perform proper command-line parsing to retrieve the actual binary name.

This could definitely use some testing since there are a ton of use cases to cover.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@psyke83

Copy link
Copy Markdown
Contributor

I believe that something may be wrong with path handling (but it applies to this PR and not #599). I tested with and without the complementary PR in case it helps to troubleshoot.

Test case (3 created test applications)

  • Add Notepad1, with command as notepad
  • Add Notepad2, with command as C:\Windows\System32\notepad.exe
  • Add Notepad3, with command as C:\Windows\System32\notepad.exe and working directory as C:\Windows\System32\

Results:

In summary, this PR makes notepad available (as it is in $Path), but C:\Windows\System32\notepad.exe fails to launch unless you manually add the working directory (which should not be necessary according to the Web UI's description).

Comment threadsrc/process.cpp Outdated
@ReenigneArcher

Copy link
Copy Markdown
Member

@cgutman
cgutmanforce-pushed the unprivileged_launch branch 2 times, most recently from 74886f8 to 83f1b99CompareDecember 21, 2022 17:46
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

OK, I think I've taken care of all the issues.

  • I've changed the behavior for detached commands to use the given working directory as discussed with @ReenigneArcher on Discord (previously working directory was unset for those commands)
  • Fixed working directory lookup issues caused by incorrect command parsing (Notepad1, 2, and 3 from @psyke83 's test should be working now)
  • Switched from ANSI to Unicode functions for process and environment creation. I verified Unicode support is working with non-ASCII working directories, commands, and environment variables (both in the user environment block and from apps.json in env).
  • Fixed Flatpak build by adding missing program_options library)
  • Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

@cgutman
cgutman marked this pull request as ready for review December 21, 2022 17:53
@ReenigneArcher

Copy link
Copy Markdown
Member

Fixed clang-format issue (seems to disagree with my local clang-format but I'll defer to the bot)

If you have any suggestions for changes to the .clang-format file, I'm happy to discuss. That file was provided to me early after I took over sunshine. One thing I personally don't like is the alignment of variable values, but I guess that's normal in c++.

@ReenigneArcher
ReenigneArcher marked this pull request as draft December 22, 2022 04:24
@Nonary

This comment was marked as spam.

@ReenigneArcher

Copy link
Copy Markdown
Member

Several users on the discord had tested this build and I don't recall any issues. We would likely get more testing if merged into nightly.

This PR is not ready to merge.

@cgutman
cgutman marked this pull request as ready for review December 27, 2022 19:40
@cgutman

Copy link
Copy Markdown
CollaboratorAuthor

platf::run_unprivileged() changes:

  • Added the ImpersonateLoggedOnUser() call to ensure that access checks are done against the user token rather than our SYSTEM token. This also allows launching apps on a network share or network drive.
  • Addressed handle inheritance issues in a cleaner way (using PROC_THREAD_ATTRIBUTE_HANDLE_LIST rather than manually disabling inheritance on Sunshine's own std handles)
  • Added CREATE_BREAKAWAY_FROM_JOB to handle changes in Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies #602 that would otherwise terminate the child process if SunshineSvc died
  • Added CREATE_NEW_CONSOLE to handle the case where log output is not redirected and incorrectly ends up in Sunshine's own log file
  • Removed bp::child() fallback if CreateProcessAsUser() fails. I left that fallback in place just in case CreateProcessAsUser() failed when running as non-admin, but that case seems to work just fine (CreateProcessAsUser() and ImpersonateLoggedOnUser() using your own user token requires no additional permissions).

Log file fixes:

  • Fixed Unicode log file path handling on Windows (previously, attempts to use non-ANSI log file paths would silently fail)
  • Added _SH_DENYNO to ensure reopening log files for applications that are still running will not fail with a sharing violation.

These changes also fix the crash that we saw with UWP notepad.exe with the previous version of this PR.

@ReenigneArcher
ReenigneArcher merged commit 05f5370 into LizardByte:nightlyDec 27, 2022
@Michoko92

Copy link
Copy Markdown

Awesome job! 👍

KuleRucket pushed a commit to KuleRucket/Sunshine that referenced this pull request Dec 28, 2022
@cgutmancgutman mentioned this pull request Jan 1, 2023
2 tasks
@exalented

exalented commented Jan 9, 2023

Copy link
Copy Markdown
Contributor

With the 17 release I can no longer launch an app on linux without sunshine core dumping:
Platform: Arch / Sway / Nvidia, running AUR package.

Warning: run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions.
terminate called after throwing an instance of 'boost::process::process_error'
what(): killpg(2) failed in terminate: Invalid argument
Aborted (core dumped)

@FrogTheFrogFrogTheFrog mentioned this pull request Jan 14, 2023
11 tasks
@ReenigneArcherReenigneArcher mentioned this pull request Apr 1, 2023
11 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants

@cgutman@psyke83@ReenigneArcher@Nonary@Michoko92@exalented