Windows Service Silent Update: Difference between revisions
No edit summary |
m (Fix misc typos) |
||
Line 21: | Line 21: | ||
Other details about the service: | Other details about the service: | ||
*The service will be dealing with user tokens and therefore must be run as the SYSTEM account. | *The service will be dealing with user tokens and therefore must be run as the SYSTEM account. | ||
*The service will have a | *The service will have a manifest file which runs as administrator | ||
*The service will use the icon of updater.exe | *The service will use the icon of updater.exe | ||
*The service will be located in the tree under /toolkit/components/ | *The service will be located in the tree under /toolkit/components/ | ||
Line 127: | Line 127: | ||
== Test cases == | == Test cases == | ||
Below I describe some important things that come to mind that we should be testing. All of the usual update | Below I describe some important things that come to mind that we should be testing. All of the usual update tests and more should also be tested. | ||
*Test that using a limited user account does not install the service, nor prompt to install the service. | *Test that using a limited user account does not install the service, nor prompt to install the service. | ||
*Test that if the service is already installed, installing an update of a higher service number will replace the old service. | *Test that if the service is already installed, installing an update of a higher service number will replace the old service. | ||
*Test that if the service is already installed, installing an update of a lower service number will NOT replace the old service. | *Test that if the service is already installed, installing an update of a lower service number will NOT replace the old service. | ||
*Test that if the service is already installed, and another product with a higher | *Test that if the service is already installed, and another product with a higher version number gets installed, it will replace the old service. | ||
*Test that if the service is already installed, and another product with a lower | *Test that if the service is already installed, and another product with a lower version number gets installed, it will NOT replace the old service. | ||
*Test the same above rules cross architecture, from both x86 and x64. | *Test the same above rules cross architecture, from both x86 and x64. | ||
*Test applying updates from a limited user account. | *Test applying updates from a limited user account. |
Revision as of 21:05, 4 October 2011
Overview
When a user installs into the default Program Files directory, updates cannot be applied without us first prompting the user for elevated permissions with a User Access Control (UAC) dialog.
The tasks related to not prompting the user for UAC are in bug 481815 and in this feature page.
High Level Plan
Firefox will use a service to execute updates so that UAC prompts are not displayed.
The service is currently planned to be stopped until it is needed, when it is needed it will be started again for the period of the update.
New Windows Service component information
The name of the service is subject to change, but the current service info is:
Display name: Mozilla Application Updater
Service name: MozillaUpdater
File name: updater_svc.exe
Other details about the service:
- The service will be dealing with user tokens and therefore must be run as the SYSTEM account.
- The service will have a manifest file which runs as administrator
- The service will use the icon of updater.exe
- The service will be located in the tree under /toolkit/components/
How the service works
As soon as the service is started, it will watch a directory for new files. These new files are called 'work items'.
The directory being watched on Vista and above can be found here:
C:\ProgramData\Mozilla
The directory being watched on Windows XP and below can be found in:
C:\Documents and Settings\All Users\Application Data\Mozilla
Since the service is currently planned to only be started when needed, we may just have it scan a directory, do the work items it needs to, and then shut down itself automatically. The service security will be modified with a special ACE which allows non elevated processes to start and stop it.
A single service and service versioning
We plan to have only one Windows service which will service every product and every development channel.
- If a service is already installed, the service will be replaced on updates and installs only if it is newer than what is installed.
- If the user is running on an x64 computer, and has both x86 and x64 builds installed. The highest version number will still win, regardless of if it is x86 or x64.
Service work items
A 'work item' is just a file that contains the info that is usually passed to updater.exe to perform an update.
The very simple file format of these work items is:
- A 4 byte session ID for the user making the request
- The application path to updater.exe to use
- The command line string to pass to updater.exe
Applying an update from Firefox's perspective
- On Firefox (or any other Mozilla application that uses the service) startup, Firefox detects an update is ready to be applied
- Firefox checks to see if the service is started; if the service is not started it will start the service.
- Firefox will write out a 'work item' file into the directory being watched with the command line parameters that are passed to updater.exe
- If the service can't be started, is disabled, or does not exist, Firefox will execute updater.exe as it used to.
- Firefox shuts itself down.
Applying an update from the service's perspective
- The service gets woken up when it detects that a 'work item' is written immediately.
- The service parses the information from the work item file.
- The service will execute the update with updater.exe under the context of its own session (session 0) using CreateProcess.
- The path of updater.exe will be a copy of the updater.exe which exists inside the service directory. (A copy in case the original gets overwritten during the update).
- The post update process (helper.exe) currently does i) system level stuff, and ii) user level stuff. This component will be split in 2. The system level stuff will also be executed under session 0 using CreateProcess. The user level stuff will be executed under the parsed session ID and always uses Windows Station "winsta0" and Windows Desktop "Default" to create the process in.
STARTUPINFO si = {0}; si.cb = sizeof(STARTUPINFO); si.lpDesktop = L"winsta0\\Default";
- The service will execute the post update process under the context of the passed session ID using CreateProcessAsUser.
- If running Vista or later, before executing the post update process, the service gets the user token for the passed session ID and then gets its linked elevated token.
HANDLE GetElevatedTokenFromToken(HANDLE token) { // Magic below... // UAC creates 2 tokens. One is the restricted token which we have. // the other is the UAC elevated one. Since we are running as a service // as the system account we have access to both. TOKEN_LINKED_TOKEN tlt; HANDLE hNewLinkedToken = NULL; DWORD len; if(::GetTokenInformation(token, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, &tlt, sizeof(TOKEN_LINKED_TOKEN), &len)) { token = tlt.LinkedToken; hNewLinkedToken = token; } return hNewLinkedToken; }
- Once the update process is complete, if the command line parameters passed in the `work item` mentioned to restart Firefox, Firefox will be restarted. It will be restarted within the context of the passed Session ID but NOT using the elevated user token.
When the service fails
- If there is an error creating the work item, we will fall back to the old way of updating: using updater.exe.
- If there is an error parsing the `work item`, creating the process, or during update, the update will be aborted and the next startup of Firefox will attempt again.
Service as an optional component
If the service is not installed, or disabled, we will fall back to the old way of updating: using updater.exe
Limited user accounts
Whether a user is an administrator or a limited user account, they can initiate an update.
Service installation
- The service will be installed for users automatically via software update.
- There will be a checkbox in the installer for whether or not to install the service component.
- The service will be able to be uninstalled separately, it will show up as a new item under add/remove programs.
Preferences
- There will be a new about:config option for whether or not to use the service.
- The new setting will be a boolean setting called app.update.service
- This will be defaulted to False if it does not exist, but we will set this to True for Firefox.
- Other products who want to use the service should mark the setting as true.
Open Questions
- Should we use the service on Windows XP and below at all?
- A user may install to a location which is not elevated, should we bypass the service in that case?
- Should we add an extra signature check or hash check on updater.exe or helper.exe to ensure we are executing the correct file? A digital signature check can't currently be executed because Nightly builds do not sign binaries yet.
Test cases
Below I describe some important things that come to mind that we should be testing. All of the usual update tests and more should also be tested.
- Test that using a limited user account does not install the service, nor prompt to install the service.
- Test that if the service is already installed, installing an update of a higher service number will replace the old service.
- Test that if the service is already installed, installing an update of a lower service number will NOT replace the old service.
- Test that if the service is already installed, and another product with a higher version number gets installed, it will replace the old service.
- Test that if the service is already installed, and another product with a lower version number gets installed, it will NOT replace the old service.
- Test the same above rules cross architecture, from both x86 and x64.
- Test applying updates from a limited user account.
- Test applying updates from a Windows 2000 machine.
- Test applying updates from a Windows XP machine.
- Test applying updates from a Windows Vista machine at each of the UAC levels.
- Test applying updates from a Windows 7 machine at each of the UAC levels.