summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/update/updater/updater.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/mozapps/update/updater/updater.cpp121
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