def download_icons(item_list, icon_dir): """Download icons for items in the list. Based on updatecheck.py, modified. Copied from https://github.com/munki/munki/blob/master/code/client/munkilib/updatecheck.py#L2824 Attempts to download icons (actually png files) for items in item_list """ icon_list = [] icon_known_exts = [ '.bmp', '.gif', '.icns', '.jpg', '.jpeg', '.png', '.psd', '.tga', '.tif', '.tiff', '.yuv' ] icon_base_url = (pref('IconURL') or pref('SoftwareRepoURL') + '/icons/') icon_base_url = icon_base_url.rstrip('/') + '/' for item in item_list: icon_name = item.get('icon_name') or item['name'] pkginfo_icon_hash = item.get('icon_hash') if not os.path.splitext(icon_name)[1] in icon_known_exts: icon_name += '.png' icon_list.append(icon_name) icon_url = icon_base_url + urllib2.quote(icon_name.encode('UTF-8')) icon_path = os.path.join(icon_dir, icon_name) if os.path.isfile(icon_path): xattr_hash = getxattr(icon_path, XATTR_SHA) if not xattr_hash: xattr_hash = getsha256hash(icon_path) writeCachedChecksum(icon_path, xattr_hash) else: xattr_hash = 'nonexistent' icon_subdir = os.path.dirname(icon_path) if not os.path.exists(icon_subdir): try: os.makedirs(icon_subdir, 0755) except OSError, err: print 'Could not create %s' % icon_subdir continue custom_headers = [''] if BASIC_AUTH: # custom_headers = ['Authorization: Basic %s' % BASIC_AUTH] custom_headers = BASIC_AUTH if pkginfo_icon_hash != xattr_hash: item_name = item.get('display_name') or item['name'] message = 'Getting icon %s for %s...' % (icon_name, item_name) try: dummy_value = getResourceIfChangedAtomically( icon_url, icon_path, custom_headers=custom_headers, message=message) except MunkiDownloadError, err: print('Could not retrieve icon %s from the server: %s', icon_name, err) else: if os.path.isfile(icon_path): writeCachedChecksum(icon_path)
def writeCachedChecksum(file_path, fhash=None): """Write the sha256 checksum of a file to an xattr so we do not need to calculate it again. Optionally pass the recently calculated hash value. """ if not fhash: fhash = munkicommon.getsha256hash(file_path) if len(fhash) == 64: xattr.setxattr(file_path, XATTR_SHA, fhash) return fhash return None
def checkForSoftwareUpdates(forcecheck=True): '''Does our Apple Software Update check if needed''' sucatalog = os.path.join(swupdCacheDir(temp=False), 'apple.sucatalog') catcksum = munkicommon.getsha256hash(sucatalog) try: catalogchanged = cacheAppleSUScatalog() except ReplicationError, err: munkicommon.display_warning('Could not download Apple SUS catalog:') munkicommon.display_warning('\t', err) return False
def download_icons(item_list, icon_dir): """Download icons for items in the list. Based on updatecheck.py, modified. Copied from https://github.com/munki/munki/blob/master/code/client/munkilib/updatecheck.py#L2824 Attempts to download icons (actually png files) for items in item_list """ icon_list = [] icon_known_exts = ['.bmp', '.gif', '.icns', '.jpg', '.jpeg', '.png', '.psd', '.tga', '.tif', '.tiff', '.yuv'] icon_base_url = (pref('IconURL') or pref('SoftwareRepoURL') + '/icons/') icon_base_url = icon_base_url.rstrip('/') + '/' for item in item_list: icon_name = item.get('icon_name') or item['name'] pkginfo_icon_hash = item.get('icon_hash') if not os.path.splitext(icon_name)[1] in icon_known_exts: icon_name += '.png' icon_list.append(icon_name) icon_url = icon_base_url + urllib2.quote(icon_name.encode('UTF-8')) icon_path = os.path.join(icon_dir, icon_name) if os.path.isfile(icon_path): xattr_hash = getxattr(icon_path, XATTR_SHA) if not xattr_hash: xattr_hash = getsha256hash(icon_path) writeCachedChecksum(icon_path, xattr_hash) else: xattr_hash = 'nonexistent' icon_subdir = os.path.dirname(icon_path) if not os.path.exists(icon_subdir): try: os.makedirs(icon_subdir, 0755) except OSError, err: print 'Could not create %s' % icon_subdir continue custom_headers = [''] if BASIC_AUTH: # custom_headers = ['Authorization: Basic %s' % BASIC_AUTH] custom_headers = BASIC_AUTH if pkginfo_icon_hash != xattr_hash: item_name = item.get('display_name') or item['name'] message = 'Getting icon %s for %s...' % (icon_name, item_name) try: dummy_value = getResourceIfChangedAtomically( icon_url, icon_path, custom_headers=custom_headers, message=message) except MunkiDownloadError, err: print ('Could not retrieve icon %s from the server: %s', icon_name, err) else: if os.path.isfile(icon_path): writeCachedChecksum(icon_path)
def verifySoftwarePackageIntegrity(file_path, item_hash, always_hash=False): """Verifies the integrity of the given software package. The feature is controlled through the PackageVerificationMode key in the ManagedInstalls.plist. Following modes currently exist: none: No integrity check is performed. hash: Integrity check is performed by calcualting a SHA-256 hash of the given file and comparing it against the reference value in catalog. Only applies for package plists that contain the item_key; for packages without the item_key, verifcation always returns True. hash_strict: Same as hash, but returns False for package plists that do not contain the item_key. Args: file_path: The file to check integrity on. item_hash: the sha256 hash expected. always_hash: True/False always check (& return) the hash even if not necessary for this function. Returns: (True/False, sha256-hash) True if the package integrity could be validated. Otherwise, False. """ mode = munkicommon.pref('PackageVerificationMode') chash = None item_name = getURLitemBasename(file_path) if always_hash: chash = munkicommon.getsha256hash(file_path) if not mode: return (True, chash) elif mode.lower() == 'none': munkicommon.display_warning('Package integrity checking is disabled.') return (True, chash) elif mode.lower() == 'hash' or mode.lower() == 'hash_strict': if item_hash: munkicommon.display_status_minor('Verifying package integrity...') if not chash: chash = munkicommon.getsha256hash(file_path) if item_hash == chash: return (True, chash) else: munkicommon.display_error( 'Hash value integrity check for %s failed.' % item_name) return (False, chash) else: if mode.lower() == 'hash_strict': munkicommon.display_error( 'Reference hash value for %s is missing in catalog.' % item_name) return (False, chash) else: munkicommon.display_warning( 'Reference hash value missing for %s -- package ' 'integrity verification skipped.' % item_name) return (True, chash) else: munkicommon.display_error( 'The PackageVerificationMode in the ManagedInstalls.plist has an ' 'illegal value: %s' % munkicommon.pref('PackageVerificationMode')) return (False, chash)
def record_profile_receipt(profile_path, profile_identifier): '''Stores a receipt for this profile in our profile tracking plist''' profile_hash = munkicommon.getsha256hash(profile_path) if profile_identifier: store_profile_receipt_data(profile_identifier, profile_hash)
def checkForSoftwareUpdates(forcecheck=True): '''Does our Apple Software Update check if needed''' sucatalog = os.path.join(swupdCacheDir(temp=False), 'apple.sucatalog') catcksum = munkicommon.getsha256hash(sucatalog) try: catalogchanged = cacheAppleSUScatalog() except ReplicationError, err: munkicommon.display_warning('Could not download Apple SUS catalog:') munkicommon.display_warning('\t', err) return False if catalogchanged == -1: munkicommon.display_warning('Could not download Apple SUS catalog.') return False if catalogchanged and catcksum != munkicommon.getsha256hash(sucatalog): munkicommon.log('Apple update catalog has changed.') forcecheck = True if installedApplePackagesChanged(): munkicommon.log('Installed Apple packages have changed.') forcecheck = True if not availableUpdatesAreDownloaded(): munkicommon.log('Downloaded updates do not match our list ' 'of available updates.') forcecheck = True if forcecheck: updatelist = getAvailableUpdates() if updatelist: writeFilteredUpdateCatalog(updatelist) try: cacheSwupdMetadata()