OLD | NEW |
1 #!/bin/bash -p | 1 #!/bin/bash -p |
2 | 2 |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 # usage: keystone_install.sh update_dmg_mount_point | 7 # usage: keystone_install.sh update_dmg_mount_point |
8 # | 8 # |
9 # Called by the Keystone system to update the installed application with a new | 9 # Called by the Keystone system to update the installed application with a new |
10 # version from a disk image. | 10 # version from a disk image. |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 readonly UNROOTED_DEBUG_FILE="Library/Google/Google Chrome Updater Debug" | 713 readonly UNROOTED_DEBUG_FILE="Library/Google/Google Chrome Updater Debug" |
714 | 714 |
715 readonly APP_VERSION_KEY="CFBundleShortVersionString" | 715 readonly APP_VERSION_KEY="CFBundleShortVersionString" |
716 readonly APP_BUNDLEID_KEY="CFBundleIdentifier" | 716 readonly APP_BUNDLEID_KEY="CFBundleIdentifier" |
717 readonly KS_VERSION_KEY="KSVersion" | 717 readonly KS_VERSION_KEY="KSVersion" |
718 readonly KS_PRODUCT_KEY="KSProductID" | 718 readonly KS_PRODUCT_KEY="KSProductID" |
719 readonly KS_URL_KEY="KSUpdateURL" | 719 readonly KS_URL_KEY="KSUpdateURL" |
720 readonly KS_BRAND_KEY="KSBrandID" | 720 readonly KS_BRAND_KEY="KSBrandID" |
721 | 721 |
722 readonly QUARANTINE_ATTR="com.apple.quarantine" | 722 readonly QUARANTINE_ATTR="com.apple.quarantine" |
723 readonly KEYCHAIN_REAUTHORIZE_DIR=".keychain_reauthorize" | |
724 | 723 |
725 # Don't use rsync -a, because -a expands to -rlptgoD. -g and -o copy owners | 724 # Don't use rsync -a, because -a expands to -rlptgoD. -g and -o copy owners |
726 # and groups, respectively, from the source, and that is undesirable in this | 725 # and groups, respectively, from the source, and that is undesirable in this |
727 # case. -D copies devices and special files; copying devices only works | 726 # case. -D copies devices and special files; copying devices only works |
728 # when running as root, so for consistency between privileged and | 727 # when running as root, so for consistency between privileged and |
729 # unprivileged operation, this option is omitted as well. | 728 # unprivileged operation, this option is omitted as well. |
730 # -I, --ignore-times don't skip files that match in size and mod-time | 729 # -I, --ignore-times don't skip files that match in size and mod-time |
731 # -l, --links copy symlinks as symlinks | 730 # -l, --links copy symlinks as symlinks |
732 # -r, --recursive recurse into directories | 731 # -r, --recursive recurse into directories |
733 # -p, --perms preserve permissions | 732 # -p, --perms preserve permissions |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 # Collect the installed application's brand code, it will be used later. It | 1027 # Collect the installed application's brand code, it will be used later. It |
1029 # is not an error for the installed application to not have a brand code. | 1028 # is not an error for the installed application to not have a brand code. |
1030 local old_ks_plist="${installed_app_plist}" | 1029 local old_ks_plist="${installed_app_plist}" |
1031 note "old_ks_plist = ${old_ks_plist}" | 1030 note "old_ks_plist = ${old_ks_plist}" |
1032 local old_brand | 1031 local old_brand |
1033 old_brand="$(infoplist_read "${old_ks_plist}" \ | 1032 old_brand="$(infoplist_read "${old_ks_plist}" \ |
1034 "${KS_BRAND_KEY}" 2> /dev/null || | 1033 "${KS_BRAND_KEY}" 2> /dev/null || |
1035 true)" | 1034 true)" |
1036 note "old_brand = ${old_brand}" | 1035 note "old_brand = ${old_brand}" |
1037 | 1036 |
| 1037 local update_versioned_dir= |
| 1038 if [[ -z "${is_patch}" ]]; then |
| 1039 update_versioned_dir="${update_app}/${VERSIONS_DIR}/${update_version_app}" |
| 1040 note "update_versioned_dir = ${update_versioned_dir}" |
| 1041 fi |
| 1042 |
1038 if has_32_bit_only_cpu; then | 1043 if has_32_bit_only_cpu; then |
1039 # On a 32-bit-only system, make sure that the update contains 32-bit code. | 1044 # On a 32-bit-only system, make sure that the update contains 32-bit code. |
1040 note "system is 32-bit-only" | 1045 note "system is 32-bit-only" |
1041 | 1046 |
1042 local test_binary | 1047 local test_binary |
1043 if [[ -z "${is_patch}" ]]; then | 1048 if [[ -z "${is_patch}" ]]; then |
1044 # For a full installer, the framework is available, so check it for | 1049 # For a full installer, the framework is available, so check it for |
1045 # 32-bit code. | 1050 # 32-bit code. |
1046 local old_framework_dir="${old_versioned_dir}/${FRAMEWORK_DIR}" | 1051 local update_framework_dir="${update_versioned_dir}/${FRAMEWORK_DIR}" |
1047 test_binary="${old_framework_dir}/${FRAMEWORK_NAME}" | 1052 test_binary="${update_framework_dir}/${FRAMEWORK_NAME}" |
1048 else | 1053 else |
1049 # No application code is guaranteed to be available at this point for a | 1054 # No application code is guaranteed to be available at this point for a |
1050 # patch updater, but goobspatch is built alongside and will have the | 1055 # patch updater, but goobspatch is built alongside and will have the |
1051 # same bitness of the product that this updater will install, so it's a | 1056 # same bitness of the product that this updater will install, so it's a |
1052 # reasonable proxy. | 1057 # reasonable proxy. |
1053 test_binary="${patch_dir}/goobspatch" | 1058 test_binary="${patch_dir}/goobspatch" |
1054 fi | 1059 fi |
1055 note "test_binary = ${test_binary}" | 1060 note "test_binary = ${test_binary}" |
1056 | 1061 |
1057 if ! file "${test_binary}" | grep -q 'i386$'; then | 1062 if ! file "${test_binary}" | grep -q 'i386$'; then |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 # of the versioned directory, so toss out whatever's there. Don't treat | 1102 # of the versioned directory, so toss out whatever's there. Don't treat |
1098 # this as a critical step: if removal fails, operation can still proceed to | 1103 # this as a critical step: if removal fails, operation can still proceed to |
1099 # to the dirpatcher or rsync, which will likely fail. | 1104 # to the dirpatcher or rsync, which will likely fail. |
1100 if [[ -e "${new_versioned_dir}" ]] && | 1105 if [[ -e "${new_versioned_dir}" ]] && |
1101 ([[ -L "${new_versioned_dir}" ]] || | 1106 ([[ -L "${new_versioned_dir}" ]] || |
1102 ! [[ -d "${new_versioned_dir}" ]]); then | 1107 ! [[ -d "${new_versioned_dir}" ]]); then |
1103 note "removing non-directory in place of versioned directory" | 1108 note "removing non-directory in place of versioned directory" |
1104 rm -f "${new_versioned_dir}" 2> /dev/null || true | 1109 rm -f "${new_versioned_dir}" 2> /dev/null || true |
1105 fi | 1110 fi |
1106 | 1111 |
1107 local update_versioned_dir | 1112 if [[ -n "${is_patch}" ]]; then |
1108 if [[ -z "${is_patch}" ]]; then | |
1109 update_versioned_dir="${update_app}/${VERSIONS_DIR}/${update_version_app}" | |
1110 note "update_versioned_dir = ${update_versioned_dir}" | |
1111 else # [[ -n "${is_patch}" ]] | |
1112 # dirpatcher won't patch into a directory that already exists. Doing so | 1113 # dirpatcher won't patch into a directory that already exists. Doing so |
1113 # would be a bad idea, anyway. If ${new_versioned_dir} already exists, | 1114 # would be a bad idea, anyway. If ${new_versioned_dir} already exists, |
1114 # it may be something left over from a previous failed or incomplete | 1115 # it may be something left over from a previous failed or incomplete |
1115 # update attempt, or it may be the live versioned directory if this is a | 1116 # update attempt, or it may be the live versioned directory if this is a |
1116 # same-version update intended only to change channels. Since there's no | 1117 # same-version update intended only to change channels. Since there's no |
1117 # way to tell, this case is handled by having dirpatcher produce the new | 1118 # way to tell, this case is handled by having dirpatcher produce the new |
1118 # versioned directory in a temporary location and then having rsync copy | 1119 # versioned directory in a temporary location and then having rsync copy |
1119 # it into place as an ${update_versioned_dir}, the same as in a non-patch | 1120 # it into place as an ${update_versioned_dir}, the same as in a non-patch |
1120 # update. If ${new_versioned_dir} doesn't exist, dirpatcher can place the | 1121 # update. If ${new_versioned_dir} doesn't exist, dirpatcher can place the |
1121 # new versioned directory at that location directly. | 1122 # new versioned directory at that location directly. |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 | 1602 |
1602 if os_xattr_supports_r; then | 1603 if os_xattr_supports_r; then |
1603 # On 10.6, xattr supports -r for recursive operation. | 1604 # On 10.6, xattr supports -r for recursive operation. |
1604 xattr -d -r "${QUARANTINE_ATTR}" "${installed_app}" 2> /dev/null | 1605 xattr -d -r "${QUARANTINE_ATTR}" "${installed_app}" 2> /dev/null |
1605 else | 1606 else |
1606 # On earlier systems, xattr doesn't support -r, so run xattr via find. | 1607 # On earlier systems, xattr doesn't support -r, so run xattr via find. |
1607 find "${installed_app}" -exec xattr -d "${QUARANTINE_ATTR}" {} + \ | 1608 find "${installed_app}" -exec xattr -d "${QUARANTINE_ATTR}" {} + \ |
1608 2> /dev/null | 1609 2> /dev/null |
1609 fi | 1610 fi |
1610 | 1611 |
1611 # Do Keychain reauthorization. This involves running a stub executable on | |
1612 # the dmg that loads the newly-updated framework and jumps to it to perform | |
1613 # the reauthorization. The stub executable can be signed by the old | |
1614 # certificate even after the rest of Chrome switches to the new certificate, | |
1615 # so it still has access to the old Keychain items. The stub executable is | |
1616 # an unbundled flat file executable whose name matches the real | |
1617 # application's bundle identifier, so it's permitted access to the Keychain | |
1618 # items. Doing a reauthorization step at update time reauthorizes Keychain | |
1619 # items for users who never bother restarting Chrome, and provides a | |
1620 # mechanism to continue doing reauthorizations even after the certificate | |
1621 # changes. However, it only works for non-system ticket installations of | |
1622 # Chrome, because the updater runs as root when on a system ticket, and root | |
1623 # can't access individual user Keychains. | |
1624 # | |
1625 # Even if the reauthorization tool is launched, it doesn't necessarily try | |
1626 # to do anything. It will only attempt to perform a reauthorization if one | |
1627 # hasn't yet been done at update time. | |
1628 note "maybe reauthorizing Keychain" | |
1629 | |
1630 if [[ -z "${system_ticket}" ]]; then | |
1631 local new_bundleid_app | |
1632 new_bundleid_app="$(infoplist_read "${installed_app_plist}" \ | |
1633 "${APP_BUNDLEID_KEY}" || true)" | |
1634 note "new_bundleid_app = ${new_bundleid_app}" | |
1635 | |
1636 local keychain_reauthorize_dir="\ | |
1637 ${update_dmg_mount_point}/${KEYCHAIN_REAUTHORIZE_DIR}" | |
1638 local keychain_reauthorize_path="\ | |
1639 ${keychain_reauthorize_dir}/${new_bundleid_app}" | |
1640 note "keychain_reauthorize_path = ${keychain_reauthorize_path}" | |
1641 | |
1642 if [[ -x "${keychain_reauthorize_path}" ]]; then | |
1643 local framework_dir="${new_versioned_dir}/${FRAMEWORK_DIR}" | |
1644 local framework_code_path="${framework_dir}/${FRAMEWORK_NAME}" | |
1645 note "framework_code_path = ${framework_code_path}" | |
1646 | |
1647 if [[ -f "${framework_code_path}" ]]; then | |
1648 note "reauthorizing Keychain" | |
1649 "${keychain_reauthorize_path}" "${framework_code_path}" | |
1650 fi | |
1651 fi | |
1652 else | |
1653 note "system ticket, not reauthorizing Keychain" | |
1654 fi | |
1655 | |
1656 # Great success! | 1612 # Great success! |
1657 note "done!" | 1613 note "done!" |
1658 | 1614 |
1659 trap - EXIT | 1615 trap - EXIT |
1660 | 1616 |
1661 return 0 | 1617 return 0 |
1662 } | 1618 } |
1663 | 1619 |
1664 # Check "less than" instead of "not equal to" in case Keystone ever changes to | 1620 # Check "less than" instead of "not equal to" in case Keystone ever changes to |
1665 # pass more arguments. | 1621 # pass more arguments. |
1666 if [[ ${#} -lt 1 ]]; then | 1622 if [[ ${#} -lt 1 ]]; then |
1667 usage | 1623 usage |
1668 exit 2 | 1624 exit 2 |
1669 fi | 1625 fi |
1670 | 1626 |
1671 main "${@}" | 1627 main "${@}" |
1672 exit ${?} | 1628 exit ${?} |
OLD | NEW |