Add chrome-management-service binary to linux installer

Adds support for the chrome_management_service in the linux build and
implements the setup needed (setgid, chmod, etc) for this binary to
do the key rotation.

This is the design document:
docs.google.com/document/d/1k_sel8sb-z4YYABn7qzLnZQfWbfYk32B8rgEW-gNq7M

Bug: b/210343548

Change-Id: Ibec3bebca37c5d9476682380610b0791c966d2ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3534341
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Hamda Mare <hmare@google.com>
Cr-Commit-Position: refs/heads/main@{#983144}
diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn
index 6fc55684..0a7f45e 100644
--- a/chrome/installer/linux/BUILD.gn
+++ b/chrome/installer/linux/BUILD.gn
@@ -36,6 +36,7 @@
 packaging_files_executables = [
   "$root_out_dir/chrome",
   "$root_out_dir/chrome_crashpad_handler",
+  "$root_out_dir/chrome_management_service",
   "$root_out_dir/chrome_sandbox",
 ]
 packaging_files_shlibs = []
@@ -192,6 +193,11 @@
   deps = [ "//components/crash/core/app:chrome_crashpad_handler" ]
 }
 
+strip_binary("strip_chrome_management_service") {
+  binary_input = "$root_out_dir/chrome_management_service"
+  deps = [ "//chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service:chrome_management_service" ]
+}
+
 strip_binary("strip_chrome_sandbox") {
   binary_input = "$root_out_dir/chrome_sandbox"
   deps = [ "//sandbox/linux:chrome_sandbox" ]
@@ -386,10 +392,12 @@
     ":save_build_info",
     ":strip_chrome_binary",
     ":strip_chrome_crashpad_handler",
+    ":strip_chrome_management_service",
     ":strip_chrome_sandbox",
     ":theme_files",
     "//chrome",
     "//chrome:packed_resources",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service:chrome_management_service",
     "//chrome/browser/resources/media/mei_preload:component",
     "//components/crash/core/app:chrome_crashpad_handler",
     "//sandbox/linux:chrome_sandbox",
diff --git a/chrome/installer/linux/common/chromium-browser/chromium-browser.info b/chrome/installer/linux/common/chromium-browser/chromium-browser.info
index 6f67b061..b02a49c 100644
--- a/chrome/installer/linux/common/chromium-browser/chromium-browser.info
+++ b/chrome/installer/linux/common/chromium-browser/chromium-browser.info
@@ -17,6 +17,9 @@
 # Base directory for package installation.
 INSTALLDIR=/opt/chromium.org/chromium
 
+# Directory for device policy enrollments.
+ENROLLMENTDIR=/etc/chromium/policies/enrollment
+
 # Display string for desktop menu/icon.
 MENUNAME="Chromium Web Browser"
 
diff --git a/chrome/installer/linux/common/google-chrome/google-chrome.info b/chrome/installer/linux/common/google-chrome/google-chrome.info
index 2ad1b5c..a59750ea 100644
--- a/chrome/installer/linux/common/google-chrome/google-chrome.info
+++ b/chrome/installer/linux/common/google-chrome/google-chrome.info
@@ -17,6 +17,9 @@
 # Base directory for package installation.
 INSTALLDIR=/opt/google/chrome
 
+# Directory for device policy enrollments.
+ENROLLMENTDIR=/etc/opt/chrome/policies/enrollment
+
 # Display string for desktop menu/icon.
 MENUNAME="Google Chrome"
 
diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include
index f646063e1..6b6fa70 100644
--- a/chrome/installer/linux/common/installer.include
+++ b/chrome/installer/linux/common/installer.include
@@ -86,6 +86,7 @@
     -e "s#@@BUILDDIR@@#${OUTPUTDIR}#g" \
     -e "s#@@STAGEDIR@@#${STAGEDIR}#g" \
     -e "s#@@SCRIPTDIR@@#${SCRIPTDIR}#g" \
+    -e "s#@@ENROLLMENTDIR@@#${ENROLLMENTDIR}#g" \
     -e "s#@@MENUNAME@@#${MENUNAME}#g" \
     -e "s#@@PRODUCTURL@@#${PRODUCTURL}#g" \
     -e "s#@@PREDEPENDS@@#${PREDEPENDS}#g" \
@@ -146,6 +147,11 @@
   strippedfile="${OUTPUTDIR}/chrome_crashpad_handler.stripped"
   install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/chrome_crashpad_handler"
 
+  # Final permissions for the chrome-management-service will be set in
+  # postinst chrome_management_service_setup().
+  strippedfile="${OUTPUTDIR}/chrome_management_service.stripped"
+  install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/chrome-management-service"
+
   # resources
   install -m 644 "${OUTPUTDIR}/resources.pak" "${STAGEDIR}/${INSTALLDIR}/"
   # TODO(mmoss): This has broken a couple times on adding new .pak files. Maybe
@@ -411,6 +417,8 @@
         exit 1
       fi
       local expected_perms=777
+    elif [ "${base_name}" = "chrome-management-service" ]; then
+      local expected_perms=755
     elif [ "${base_name}" = "chrome-sandbox" ]; then
       local expected_perms=4755
     elif [[ "${base_name}" = "nacl_irt_"*".nexe" ]]; then
diff --git a/chrome/installer/linux/common/postinst.include b/chrome/installer/linux/common/postinst.include
index 4e3023e..be47cd4 100644
--- a/chrome/installer/linux/common/postinst.include
+++ b/chrome/installer/linux/common/postinst.include
@@ -77,3 +77,32 @@
     "^[ 	]*<web-browsers>[ 	]*$" \
     "@@INSTALLDIR@@/default-app-block"
 fi
+
+# This function performs the setup for the chrome management service process.
+# It creates a new chromemgmt group, creates the signing key file, and updates
+# permissions for both the signing key file and the binary.
+chrome_management_service_setup() {
+  if [ ! -f "$DEFAULTS_FILE" ]; then
+    return
+  fi
+
+  if ! grep -q "install_device_trust_key_management_command=true" \
+    "$DEFAULTS_FILE"; then
+    return
+  fi
+
+  getent group chromemgmt > /dev/null || groupadd chromemgmt
+
+  chgrp chromemgmt "@@INSTALLDIR@@/chrome-management-service"
+  chmod 2755 "@@INSTALLDIR@@/chrome-management-service"
+
+  mkdir -p "@@ENROLLMENTDIR@@"
+  SIGNING_KEY_FILE="@@ENROLLMENTDIR@@/DeviceTrustSigningKey"
+  if [ ! -e "$SIGNING_KEY_FILE" ]; then
+    touch "$SIGNING_KEY_FILE"
+    chgrp chromemgmt "$SIGNING_KEY_FILE"
+    chmod 664 "$SIGNING_KEY_FILE"
+  fi
+}
+
+chrome_management_service_setup