Skip to content
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

fix: windows auto-update #1679

Merged
merged 2 commits into from
Oct 8, 2020
Merged

fix: windows auto-update #1679

merged 2 commits into from
Oct 8, 2020

Conversation

lidel
Copy link
Member

@lidel lidel commented Oct 7, 2020

This PR aims to close #1570
Context: #1570 (comment)

WIP

cc @jessicaschilling @rafaelramalho19

@lidel lidel added the P0 Critical: Tackled by core team ASAP label Oct 7, 2020
@jessicaschilling
Copy link
Contributor

@lidel - is this related to #1677?

@lidel
Copy link
Member Author

lidel commented Oct 7, 2020

@jessicaschilling unclear. that error could be a side effect of autoupdate issue, or a duplicate of #1676 – asked for more information.

@lidel
Copy link
Member Author

lidel commented Oct 7, 2020

Closing the shop for today, but quick update:

I looked into setting up local update server, but it effectively becomes Rube Goldberg machine and I don't believe it is a reliable way of testing and debugging this. To be sure we test the right thing, we literally need to test in production.

For that reason I created a test app with CI and electron config similar to Desktop.

I'll copy relevant autoupdate code from Desktop tomorrow, so it is identical, and then we have setup to run some end-to-end tests.

@lidel
Copy link
Member Author

lidel commented Oct 8, 2020

Tested with altschmerz v0.0.3v0.0.4) and the simplified autoupdate provided by electron-updater on windows and it works fine when app is installed for current user, but fails to update when "all users" option is selected during install:

Capture-user-picker

The failure is the same as one described in #1514, so the original bug is still present in electron-updater when these NSIS settings are used.

Next:

  • check if a viable fix exists,
    • if not, we have to either disable "all users" option
      or detect it and disable automatic install, asking user for manual update instead"

@lidel
Copy link
Member Author

lidel commented Oct 8, 2020

Disclaimer: I am not a Windows person, so this may be obvious stuff, but took me a while to understand all the moving pieces. Having the altschmerz test app helped a lot.

I believe the crux of the problem was that we use custom NSIS settings, namely:

nsis:
  oneClick: false
  warningsAsErrors: false
  perMachine: false
  allowToChangeInstallationDirectory: true
  allowElevation: true # note: this is true by default, even when not defined in config

By default we install per user (perMachine: false), but we also give user an option to change that via the screen from my previous comment (oneClick: false).

We don't want to require admin all the time, because users should be able to install IPFS on machines where they don't have Admin (schools, libraries). That is why isAdminRightsRequired is false in the update manifest (as described in original bug report #1570 (comment)).

electron-builder has a bunch of default macros for NSIS, and some higher level flags that control some Windows-specific behaviours, for example, electron-builder/**/nsis/NsisTarget.ts#L438-L444 sets:

    if (options.perMachine === true) {
      defines.INSTALL_MODE_PER_ALL_USERS = null
    }

    if (!oneClick || options.perMachine === true) {
      defines.INSTALL_MODE_PER_ALL_USERS_REQUIRED = null
    }

INSTALL_MODE_PER_ALL_USERS and INSTALL_MODE_PER_ALL_USERS_REQUIRED are dynamic flags that control various things, one of them is deciding if installer will ask windows for elevated privileges before doing its thing.

In our case, INSTALL_MODE_PER_ALL_USERS is ON and INSTALL_MODE_PER_ALL_USERS_REQUIRED is OFF, and UAC_RunElevated is only used in _REQUIRED scenario – see electron-builder/**/nsis/multiUser.nsh#L52-L62

TLDR the fix here is to

  • (a) fix upstream
  • (b) extend assets/build/nsis.nsh with customInit script that requests UAC_RunElevated when ${if} $installMode == "all" (independent of INSTALL_MODE_PER_ALL_USERS_REQUIRED)

I'll prepare (b) first, as (a) will take long time before the fix lands upstream, and I still don't trust there won't be any regressions, as we had so many in the past, unfortunately.

This implements fix described in:
#1679 (comment)

License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
@lidel lidel marked this pull request as ready for review October 8, 2020 15:34
@lidel
Copy link
Member Author

lidel commented Oct 8, 2020

Tested in lidel/electron-updater-altschmerz#1 and ported the fix in 0bf120d – ok to merge and ship patch release?

@rafaelramalho19
Copy link
Contributor

Tested and looks good, but we can only really find out on the next version... so 🚢 it !

@lidel lidel merged commit 52f2c24 into master Oct 8, 2020
@lidel lidel deleted the fix/windows-autoupdate branch October 8, 2020 17:04
lidel added a commit that referenced this pull request Oct 8, 2020
autoInstallOnAppQuit works fine on windows, but we had a bunch of code
responsible for doing it manually due to macOS not being supported
natively by autoInstallOnAppQuit.

Due to this fix from
#1679 was not applied
correctly, and macOS-specific handling broke updates on windows.

This change ensures that macOS keeps using the old upgrade paths, but
Windows and AppImage leverage upstream code for applying upgrades.

License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
lidel added a commit that referenced this pull request Oct 8, 2020
autoInstallOnAppQuit works fine on windows, but we had a bunch of code
responsible for doing it manually due to macOS not being supported
natively by autoInstallOnAppQuit.

Due to this fix from
#1679 was not applied
correctly, and macOS-specific handling broke updates on windows.

This change ensures that macOS keeps using the old upgrade paths, but
Windows and AppImage leverage upstream code for applying upgrades.

License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
@lidel lidel added this to the v0.13.1 milestone Oct 9, 2020
@witcher112
Copy link

Hi guys!

I encountered this PR while resolving some of the UAC issues with electron-builder auto updater.

Just wanted to let you know that there might be an alternative solution - modifying the access rights after the installation, to grant full access permissions to the non-admin users (to be honest not my idea, I just observed what Steam does) so no administrative rights are required for the updater.

Here's the snippet for custom NSIS include:

!macro customInstall
  AccessControl::GrantOnFile "$INSTDIR" "(S-1-5-32-545)" "FullAccess"
  pop $0
  AccessControl::GrantOnFile "$INSTDIR" "(S-1-5-18)" "FullAccess"
  pop $0
!macroend

S-1-5-32-545 is a SID for Users group
S-1-5-18 is a SID for SYSTEM group

Note that you need to link AccessControl plugin to NSIS either through !addplugindir or by putting it into build/x86-unicode (source).

Cheers and good luck with your project!

@lidel
Copy link
Member Author

lidel commented Oct 22, 2020

@witcher112 thank you, useful to know there is an alternative approach in case current one stops working.

Maybe I misunderstood the meaning of GrantOnFile (or just lacking Windows background), but.. isn't granting write access to non-admin users effectively a decrease in security?

IIUC one user could overwrite binary that other users run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P0 Critical: Tackled by core team ASAP
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Auto-update broken on Windows
4 participants