diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/mozapps/update/updater/updater.cpp | 121 |
1 files changed, 85 insertions, 36 deletions
diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 6b01450b31..084945dc44 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -46,6 +46,7 @@ #include "updatecommon.h" #ifdef XP_MACOSX +# include "UpdateSettingsUtil.h" # include "updaterfileutils_osx.h" #endif // XP_MACOSX @@ -75,13 +76,16 @@ bool IsOwnedByGroupAdmin(const char* aAppBundle); bool IsRecursivelyWritable(const char* aPath); void LaunchChild(int argc, const char** argv); void LaunchMacPostProcess(const char* aAppBundle); -bool ObtainUpdaterArguments(int* argc, char*** argv); -bool ServeElevatedUpdate(int argc, const char** argv); +bool ObtainUpdaterArguments(int* aArgc, char*** aArgv, + MARChannelStringTable* aMARStrings); +bool ServeElevatedUpdate(int aArgc, const char** aArgv, + const char* aMARChannelID); void SetGroupOwnershipAndPermissions(const char* aAppBundle); bool PerformInstallationFromDMG(int argc, char** argv); struct UpdateServerThreadArgs { int argc; const NS_tchar** argv; + const char* marChannelID; }; #endif @@ -187,15 +191,6 @@ class AutoFile { } }; -struct MARChannelStringTable { - MARChannelStringTable() { - MARChannelID = mozilla::MakeUnique<char[]>(1); - MARChannelID[0] = '\0'; - } - - mozilla::UniquePtr<char[]> MARChannelID; -}; - //----------------------------------------------------------------------------- #ifdef XP_MACOSX @@ -292,6 +287,10 @@ static bool sUsingService = false; // that iteration will run with `gIsElevated == true`. static bool gIsElevated = false; +// This string contains the MAR channel IDs that are later extracted by one of +// the `ReadMARChannelIDsFrom` variants. +static MARChannelStringTable gMARStrings; + // Normally, we run updates as a result of user action (the user started Firefox // or clicked a "Restart to Update" button). But there are some cases when // we are not: @@ -2659,23 +2658,67 @@ static void WaitForServiceFinishThread(void* param) { #endif #ifdef MOZ_VERIFY_MAR_SIGNATURE +# ifndef XP_MACOSX /** * This function reads in the ACCEPTED_MAR_CHANNEL_IDS from update-settings.ini * - * @param path The path to the ini file that is to be read - * @param results A pointer to the location to store the read strings + * @param aPath The path to the ini file that is to be read + * @param aResults A pointer to the location to store the read strings + * @return OK on success + */ +static int ReadMARChannelIDsFromPath(const NS_tchar* aPath, + MARChannelStringTable* aResults) { + const unsigned int kNumStrings = 1; + const char* kUpdaterKeys = "ACCEPTED_MAR_CHANNEL_IDS\0"; + return ReadStrings(aPath, kUpdaterKeys, kNumStrings, &aResults->MARChannelID, + "Settings"); +} +# else // XP_MACOSX +/** + * This function reads in the ACCEPTED_MAR_CHANNEL_IDS from a string buffer. + * + * @param aChannels A string buffer containing the MAR channel(s). + * @param aResults A pointer to the location to store the read strings. * @return OK on success */ -static int ReadMARChannelIDs(const NS_tchar* path, - MARChannelStringTable* results) { +static int ReadMARChannelIDsFromBuffer(char* aChannels, + MARChannelStringTable* aResults) { const unsigned int kNumStrings = 1; const char* kUpdaterKeys = "ACCEPTED_MAR_CHANNEL_IDS\0"; - int result = ReadStrings(path, kUpdaterKeys, kNumStrings, - &results->MARChannelID, "Settings"); + return ReadStringsFromBuffer(aChannels, kUpdaterKeys, kNumStrings, + &aResults->MARChannelID, "Settings"); +} +# endif // XP_MACOSX - return result; +/** + * This function reads in the `ACCEPTED_MAR_CHANNEL_IDS` from the appropriate + * (platform-dependent) source and populates `gMARStrings`. + * + * @return + * `OK` on success, `UPDATE_SETTINGS_FILE_CHANNEL` on failure. + */ +static int PopulategMARStrings() { + int rv = UPDATE_SETTINGS_FILE_CHANNEL; +# ifdef XP_MACOSX + if (gIsElevated) { + // An elevated update process will have already populated gMARStrings when + // it connected to the unelevated update process to obtain the command line + // args. See `ObtainUpdaterArguments`. + rv = OK; + } else if (auto marChannels = + UpdateSettingsUtil::GetAcceptedMARChannelsValue()) { + rv = ReadMARChannelIDsFromBuffer(marChannels->data(), &gMARStrings); + } +# else + NS_tchar updateSettingsPath[MAXPATHLEN]; + NS_tsnprintf(updateSettingsPath, + sizeof(updateSettingsPath) / sizeof(updateSettingsPath[0]), + NS_T("%s/update-settings.ini"), gInstallDirPath); + rv = ReadMARChannelIDsFromPath(updateSettingsPath, &gMARStrings); +# endif + return rv == OK ? OK : UPDATE_SETTINGS_FILE_CHANNEL; } -#endif +#endif // MOZ_VERIFY_MAR_SIGNATURE static int GetUpdateFileName(NS_tchar* fileName, int maxChars) { NS_tsnprintf(fileName, maxChars, NS_T("%s/update.mar"), gPatchDirPath); @@ -2700,21 +2743,10 @@ static void UpdateThreadFunc(void* param) { } if (rv == OK) { - NS_tchar updateSettingsPath[MAXPATHLEN]; - NS_tsnprintf(updateSettingsPath, - sizeof(updateSettingsPath) / sizeof(updateSettingsPath[0]), -# ifdef XP_MACOSX - NS_T("%s/Contents/Resources/update-settings.ini"), -# else - NS_T("%s/update-settings.ini"), -# endif - gInstallDirPath); - MARChannelStringTable MARStrings; - if (ReadMARChannelIDs(updateSettingsPath, &MARStrings) != OK) { - rv = UPDATE_SETTINGS_FILE_CHANNEL; - } else { + rv = PopulategMARStrings(); + if (rv == OK) { rv = gArchiveReader.VerifyProductInformation( - MARStrings.MARChannelID.get(), MOZ_APP_VERSION); + gMARStrings.MARChannelID.get(), MOZ_APP_VERSION); } } #endif @@ -2819,7 +2851,8 @@ static void UpdateThreadFunc(void* param) { #ifdef XP_MACOSX static void ServeElevatedUpdateThreadFunc(void* param) { UpdateServerThreadArgs* threadArgs = (UpdateServerThreadArgs*)param; - gSucceeded = ServeElevatedUpdate(threadArgs->argc, threadArgs->argv); + gSucceeded = ServeElevatedUpdate(threadArgs->argc, threadArgs->argv, + threadArgs->marChannelID); if (!gSucceeded) { WriteStatusFile(ELEVATION_CANCELED); } @@ -2955,6 +2988,21 @@ int NS_main(int argc, NS_tchar** argv) { putenv(const_cast<char*>("MOZ_USING_SERVICE=")); #endif + if (argc == 2 && NS_tstrcmp(argv[1], NS_T("--channels-allowed")) == 0) { +#ifdef MOZ_VERIFY_MAR_SIGNATURE + int rv = PopulategMARStrings(); + if (rv == OK) { + printf("Channels Allowed: %s\n", gMARStrings.MARChannelID.get()); + return 0; + } + printf("Error: %d\n", rv); + return 1; +#else + printf("Not Applicable: No support for signature verification\n"); + return 0; +#endif + } + // The callback is the remaining arguments starting at callbackIndex. // The argument specified by callbackIndex is the callback executable and the // argument prior to callbackIndex is the working directory. @@ -2977,7 +3025,7 @@ int NS_main(int argc, NS_tchar** argv) { strstr(argv[0], "/Library/PrivilegedHelperTools/org.mozilla.updater") != 0; if (isElevated) { - if (!ObtainUpdaterArguments(&argc, &argv)) { + if (!ObtainUpdaterArguments(&argc, &argv, &gMARStrings)) { // Won't actually get here because ObtainUpdaterArguments will terminate // the current process on failure. return 1; @@ -3288,6 +3336,7 @@ int NS_main(int argc, NS_tchar** argv) { UpdateServerThreadArgs threadArgs; threadArgs.argc = argc; threadArgs.argv = const_cast<const NS_tchar**>(argv); + threadArgs.marChannelID = gMARStrings.MARChannelID.get(); Thread t1; if (t1.Run(ServeElevatedUpdateThreadFunc, &threadArgs) == 0) { @@ -4179,7 +4228,7 @@ int NS_main(int argc, NS_tchar** argv) { // Run update process on a background thread. ShowProgressUI may return // before QuitProgressUI has been called, so wait for UpdateThreadFunc to // terminate. Avoid showing the progress UI when staging an update, or if - // this is an elevated process on OSX. + // this is an elevated process on macOS. Thread t; if (t.Run(UpdateThreadFunc, nullptr) == 0) { if (!sStagedUpdate && !sReplaceRequest && !sUpdateSilently |