Enable MAR verification on linux via NSS
authorBrian R. Bondy <netzen@gmail.com>
Tue, 21 Apr 2015 16:39:59 -0400
changeset 491407 b89252024475f9d547f56aff682d395a0b5d863e
parent 491406 6c0403f538f30403f7a9c8f6b3f4dcb088e558db
child 491408 4609f9272a9369e4ccf038dfb43558d9751ecfc9
push id47343
push userbmo:dothayer@mozilla.com
push dateWed, 01 Mar 2017 22:58:58 +0000
milestone40.0a1
Enable MAR verification on linux via NSS
browser/confvars.sh
toolkit/mozapps/update/updater/updater-common.build
toolkit/mozapps/update/updater/updater.cpp
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -5,31 +5,32 @@
 
 MOZ_APP_BASENAME=Firefox
 MOZ_APP_VENDOR=Mozilla
 MOZ_UPDATER=1
 MOZ_PHOENIX=1
 
 if test "$OS_ARCH" = "WINNT"; then
   MOZ_MAINTENANCE_SERVICE=1
-  MOZ_VERIFY_MAR_SIGNATURE=1
   if ! test "$HAVE_64BIT_BUILD"; then
     if test "$MOZ_UPDATE_CHANNEL" = "nightly" -o \
             "$MOZ_UPDATE_CHANNEL" = "aurora" -o \
             "$MOZ_UPDATE_CHANNEL" = "beta" -o \
             "$MOZ_UPDATE_CHANNEL" = "release"; then
       if ! test "$MOZ_DEBUG"; then
         MOZ_STUB_INSTALLER=1
       fi
     fi
   fi
 elif test "$OS_ARCH" = "Darwin"; then
   MOZ_VERIFY_MAR_SIGNATURE=1
 fi
 
+MOZ_VERIFY_MAR_SIGNATURE=1
+
 # Enable building ./signmar and running libmar signature tests
 MOZ_ENABLE_SIGNMAR=1
 
 MOZ_CHROME_FILE_FORMAT=omni
 MOZ_DISABLE_EXPORT_JS=1
 MOZ_SAFE_BROWSING=1
 MOZ_SERVICES_COMMON=1
 MOZ_SERVICES_CRYPTO=1
--- a/toolkit/mozapps/update/updater/updater-common.build
+++ b/toolkit/mozapps/update/updater/updater-common.build
@@ -46,17 +46,17 @@ if CONFIG['OS_ARCH'] == 'WINNT':
         'advapi32',
     ]
 elif CONFIG['OS_ARCH'] == 'Linux' and CONFIG['MOZ_VERIFY_MAR_SIGNATURE']:
     USE_LIBS += [
         'nss',
         'signmar',
         'updatecommon',
     ]
-    OS_LIBS += CONFIG['nspr']
+    OS_LIBS += CONFIG['NSPR_LIBS']
 else:
     USE_LIBS += [
         'updatecommon',
     ]
 
 USE_LIBS += [
     'mar',
 ]
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -2265,16 +2265,36 @@ UpdateThreadFunc(void *param)
     }
     WriteStatusFile(rv);
   }
 
   LOG(("calling QuitProgressUI"));
   QuitProgressUI();
 }
 
+#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX)
+#include "prprf.h"
+#define PATH_SEPARATOR ":"
+#define LD_LIBRARY_PATH_ENVVAR_NAME "LD_LIBRARY_PATH"
+static void
+AppendToLibPath(const char *appPath)
+{
+  char *s = nullptr;
+  char *pathValue = getenv(LD_LIBRARY_PATH_ENVVAR_NAME);
+  if (nullptr == pathValue || '\0' == *pathValue) {
+    s = PR_smprintf("%s=%s", LD_LIBRARY_PATH_ENVVAR_NAME, appPath);
+  } else {
+    s = PR_smprintf("%s=%s" PATH_SEPARATOR "%s",
+                    LD_LIBRARY_PATH_ENVVAR_NAME, appPath, pathValue);
+  }
+  putenv(s);
+  PR_smprintf_free(s);
+}
+#endif
+
 int NS_main(int argc, NS_tchar **argv)
 {
 #if defined(MOZ_WIDGET_GONK)
   if (getenv("LD_PRELOAD")) {
     // If the updater is launched with LD_PRELOAD set, then we wind up
     // preloading libmozglue.so. Under some circumstances, this can cause
     // the remount of /system to fail when going from rw to ro, so if we
     // detect LD_PRELOAD we unsetenv it and relaunch ourselves without it.
@@ -2286,16 +2306,20 @@ int NS_main(int argc, NS_tchar **argv)
     execv(argv[0], argv);
     __android_log_print(ANDROID_LOG_INFO, "updater",
                         "execve failed: errno: %d. Exiting...", errno);
     _exit(1);
   }
 #endif
 
 #if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX)
+  // When using NSS some NSS shared libraries must be in the path, so we add
+  // in the application directory into the path.
+  AppendToLibPath(argv[2]);
+
   // On Windows and Mac we rely on native APIs to do verifications so we don't
   // need to initialize NSS at all there.
   // Otherwise, minimize the amount of NSS we depend on by avoiding all the NSS
   // databases.
   if (NSS_NoDB_Init(NULL) != SECSuccess) {
    PRErrorCode error = PR_GetError();
    fprintf(stderr, "Could not initialize NSS: %s (%d)",
            PR_ErrorToName(error), (int) error);