def main(): filevault = fv_status() mac_ver = mac_version() if LooseVersion("10.11") <= LooseVersion(mac_ver): sip = sip_status() else: sip = 'Not Supported' # Yes, I know it came in 10.7.5, but eh. I don't care, I'm lazy if LooseVersion("10.8") <= LooseVersion(mac_ver): gatekeeper = gatekeeper_status() else: gatekeeper = 'Not Supported' plist_path = '/usr/local/sal/plugin_results.plist' if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) else: plist = [] result = {} result['plugin'] = 'MachineDetailSecurity' result['historical'] = True data = {} data['Filevault'] = filevault data['SIP'] = sip data['Gatekeeper'] = gatekeeper result['data'] = data plist.append(result) FoundationPlist.writePlist(plist, plist_path)
def main(): """Main""" # Create cache dir if it does not exist cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(cachedir): os.makedirs(cachedir) # Skip manual check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': print 'Manual check: skipping' exit(0) # Get results result = dict() info = get_displays_info() # Read in English localizations from SystemProfiler if getOsVersion() > 13: localization = FoundationPlist.readPlist('/System/Library/SystemProfiler/SPDisplaysReporter.spreporter/Contents/Resources/en.lproj/Localizable.strings') else: localization = FoundationPlist.readPlist('/System/Library/SystemProfiler/SPDisplaysReporter.spreporter/Contents/Resources/English.lproj/Localizable.strings') result = flatten_displays_info(info, localization) # Write displays results to cache output_plist = os.path.join(cachedir, 'displays.plist') plistlib.writePlist(result, output_plist)
def main(): if os.path.exists('/usr/bin/fdesetup'): filevault = fv_status() else: filevault = 'Not Supported' if os.path.exists('/usr/bin/csrutil'): sip = sip_status() else: sip = 'Not Supported' # Yes, I know it came in 10.7.5, but eh. I don't care, I'm lazy if os.path.exists('/usr/sbin/spctl'): gatekeeper = gatekeeper_status() else: gatekeeper = 'Not Supported' plist_path = '/usr/local/sal/plugin_results.plist' if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) else: plist = [] result = {} result['plugin'] = 'MachineDetailSecurity' result['historical'] = False data = {} data['Filevault'] = filevault data['SIP'] = sip data['Gatekeeper'] = gatekeeper result['data'] = data plist.append(result) FoundationPlist.writePlist(plist, plist_path)
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: new = updatecheck.getResourceIfChangedAtomically( '%s/applesus/' % url, APPLE_SUS_CATALOG) except fetch.MunkiDownloadError as e: logging.exception(u'MunkiDownloadError getting Apple SUS catalog: %s', e) return if new: # SUS catalog changed, clear last check date to run softwareupdate soon. munkicommon.set_pref('LastAppleSoftwareUpdateCheck', None) try: sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) except fpl.NSPropertyListSerializationException: # plist may not exist, but will be created when softwareupdate is run, then # the next execution of of this code will set the CatalogURL. logging.exception('Failed to read Apple SoftwareUpdate plist.') return # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST)
def main(): """Main""" # Skip manual check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': print 'Manual check: skipping' exit(0) # Create cache dir if it does not exist cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(cachedir): os.makedirs(cachedir) # Set the encoding # The "ugly hack" :P reload(sys) sys.setdefaultencoding('utf8') # Get results result = dict() info = get_firewall_info() result = merge_two_dicts(flatten_firewall_info(info), get_alf_preferences()) # Write firewall results to cache output_plist = os.path.join(cachedir, 'firewall.plist') FoundationPlist.writePlist(result, output_plist)
def checkForOSXFlashbackk(): # Checks Various browsers for the malware browsersToCheck = ["Firefox.app", "Safari.app", "Opera.app", "Google Chrome.app" "Camino.app", "Stainless.app", "OmniWebb.app", "Fluid.app"] userFilestoCheck = ["Library/LaunchAgents/com.sun.jsched.plist", ".jsched"] applicationsDirectory = "/Applications" plistLocation = "Contents/Info.plist" for browser in browsersToCheck: fullPathToPlist = (os.path.join(applicationsDirectory, browser, plistLocation)) if os.path.exists(fullPathToPlist): loadedPlist = FoundationPlist.readPlist(fullPathToPlist) malwareKey = loadedPlist.get("LSEnvironment", "") if malwareKey: return True # Check for malware in shared folder if os.path.exists("/Users/Shared/.libgmalloc.dylib"): return True # Check for malware in each user's folder for user in os.listdir("/Users/"): if not user.startswith('.'): fullPathToEnvPlist = (os.path.join("/Users", user, ".MacOSX", "environment.plist")) if os.path.exists(fullPathToEnvPlist): loadedPlist = FoundationPlist.readPlist(fullPathToEnvPlist) DYLDkey = loadedPlist.get("DYLD_INSERT_LIBRARIES", "") if DYLDkey: return True for fileToCheck in userFilestoCheck: if os.path.exists((os.path.join("/Users", user, fileToCheck))): print os.path.join("/Users", user, fileToCheck) return True return False
def main(): """Main""" # Skip manual check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': print 'Manual check: skipping' exit(0) # Create cache dir if it does not exist cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(cachedir): os.makedirs(cachedir) # Set the encoding # The "ugly hack" :P reload(sys) sys.setdefaultencoding('utf8') # Get results result = dict() result = merge_two_dicts(get_snowagent_config(), get_snowagent_version()) # Write snowagent results to cache output_plist = os.path.join(cachedir, 'snowagent.plist') FoundationPlist.writePlist(result, output_plist)
def main(): """Main""" # Remove old init_ard script, if it exists if os.path.isfile( os.path.dirname(os.path.realpath(__file__)) + '/init_ard'): os.remove(os.path.dirname(os.path.realpath(__file__)) + '/init_ard') # Create cache dir if it does not exist cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(cachedir): os.makedirs(cachedir) # Skip manual check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': print 'Manual check: skipping' exit(0) # Set the encoding reload(sys) sys.setdefaultencoding('utf8') # Get results result = dict() result = merge_two_dicts(get_remote_desktop_info(), get_remote_management_info()) result = merge_two_dicts(result, get_ard_info()) # Write ard results to cache output_plist = os.path.join(cachedir, 'ard.plist') FoundationPlist.writePlist(result, output_plist)
def main(): # Skip running on manual munki check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': print 'Manual check: skipping' exit(0) # Create cache dir if it does not exist cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(cachedir): os.makedirs(cachedir) result = {} # check if Sophos is installed if os.path.isdir('/Applications/Sophos Endpoint.app'): result.update({'Installed': 'Sophos Central'}) elif os.path.isdir('/Applications/Sophos Anti-Virus.app'): result.update({'Installed': 'Sophos Business'}) else: result.update({'Installed': 'Not Installed'}) # check if Sophos is running if result['Installed']: # check if Sophos is running result.update({'Running': check_sophos_running()}) # check component versions result.update({'Versions': check_sophos_versions()}) # Write results of checks to cache file output_plist = os.path.join(cachedir, 'sophos.plist') FoundationPlist.writePlist(result, output_plist)
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: new = updatecheck.getResourceIfChangedAtomically( '%s/applesus/' % url, APPLE_SUS_CATALOG) except fetch.MunkiDownloadError: logging.exception('MunkiDownloadError getting Apple SUS catalog.') return if new: # SUS catalog changed, clear last check date to run softwareupdate soon. munkicommon.set_pref('LastAppleSoftwareUpdateCheck', None) try: sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) except fpl.NSPropertyListSerializationException: # plist may not exist, but will be created when softwareupdate is run, then # the next execution of of this code will set the CatalogURL. logging.exception('Failed to read Apple SoftwareUpdate plist.') return # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST)
def main(): """main""" # Skip running on manual check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': print 'Manual check: skipping' exit(0) # Create cache dir if it does not exist cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(cachedir): os.makedirs(cachedir) # Create an empty directory object to hold results from check methods, then run. result = {} result.update({'gatekeeper': gatekeeper_check()}) result.update({'sip': sip_check()}) result.update({'ssh_users': ssh_user_access_check()}) result.update({'ssh_groups': ssh_group_access_check()}) result.update({'ard_users': ard_access_check()}) result.update({'firmwarepw': firmware_pw_check()}) result.update({'firewall_state': firewall_enable_check()}) result.update({'skel_state': skel_state_check()}) # Write results of checks to cache file output_plist = os.path.join(cachedir, 'security.plist') FoundationPlist.writePlist(result, output_plist)
def main(): # Get results result = dict() result = merge_two_dicts(get_user_config(), get_mau_prefs()) result = merge_two_dicts(result, vl_license_detect()) result = merge_two_dicts(result, o365_license_detect()) result = merge_two_dicts(result, shared_o365_license_detect()) result = merge_two_dicts(result, get_app_data("/Applications/Microsoft Excel.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft PowerPoint.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft Outlook.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft OneNote.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft Remote Desktop.app")) result = merge_two_dicts(result, get_app_data("/Applications/Microsoft Word.app")) result = merge_two_dicts(result, get_app_data("/Applications/OneDrive.app")) result = merge_two_dicts(result, get_app_data("/Applications/Microsoft Teams.app")) result = merge_two_dicts( result, get_app_data("/Applications/Skype for Business.app")) result = merge_two_dicts(result, get_app_data("/Applications/Company Portal.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft Defender ATP.app")) result = merge_two_dicts(result, get_app_data("/Applications/Yammer.app")) # Edge has four different channels, get them in priority result = merge_two_dicts( result, get_app_data("/Applications/Microsoft Edge Canary.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft Edge Dev.app")) result = merge_two_dicts( result, get_app_data("/Applications/Microsoft Edge Beta.app")) result = merge_two_dicts(result, get_app_data("/Applications/Microsoft Edge.app")) result = merge_two_dicts( result, get_app_data( "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app" )) # Write office results to cache cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) output_plist = os.path.join(cachedir, 'ms_office.plist') FoundationPlist.writePlist(result, output_plist)
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: updatecheck.getResourceIfChangedAtomically( '%s/applesus/' % url, APPLE_SUS_CATALOG) # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST) except (fetch.MunkiDownloadError, fpl.NSPropertyListSerializationException): logging.exception('MunkiDownloadError getting Apple SUS catalog.')
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: updatecheck.getResourceIfChangedAtomically('%s/applesus/' % url, APPLE_SUS_CATALOG) # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST) except (fetch.MunkiDownloadError, fpl.NSPropertyListSerializationException): logging.exception('MunkiDownloadError getting Apple SUS catalog.')
def main(): '''Main''' # get runtype (based on MunkiReport preflight code) if (len(sys.argv) > 1): runtype = sys.argv[1] else: runtype = 'custom' # Get the current Apple updates preference munki_prefs_location = '/Library/Preferences/ManagedInstalls.plist' # Make sure the preferences location exists (it should) if os.path.exists(munki_prefs_location): # Get the current preferences into a list munki_prefs = FoundationPlist.readPlist(munki_prefs_location) # Check the Apple updates preference exists if 'InstallAppleSoftwareUpdates' in munki_prefs: # Assign the current preference to a temporary variable InstallAppleSoftwareUpdates = munki_prefs[ 'InstallAppleSoftwareUpdates'] else: # If the Apple updates preference doesn't exist... # Let's assign it to the temporary variable InstallAppleSoftwareUpdates = False # And also add it to the list munki_prefs['InstallAppleSoftwareUpdates'] = False # If the runtype is manualcheck, turn off Apple updates if runtype == 'manualcheck' and InstallAppleSoftwareUpdates == True: InstallAppleSoftwareUpdates = False # Any other scenario, turn on Apple updates else: InstallAppleSoftwareUpdates = True # If the preference has changed, write it back to the preferences file if InstallAppleSoftwareUpdates != munki_prefs[ 'InstallAppleSoftwareUpdates']: munki_prefs[ 'InstallAppleSoftwareUpdates'] = InstallAppleSoftwareUpdates FoundationPlist.writePlist(munki_prefs, munki_prefs_location)
def main(): """Main""" # Set the encoding reload(sys) sys.setdefaultencoding('utf8') # Get information about the browser extensions users = get_users() result = process_browsers(users) # Write browser extensions to cache cachedir = '%s/cache' % os.path.dirname(os.path.realpath(__file__)) output_plist = os.path.join(cachedir, 'browser_extensions.plist') FoundationPlist.writePlist(result, output_plist)
def get_munkiimport_prefs(): """Get the current user's munkiimport preferences as plist dict.""" try: prefs = FoundationPlist.readPlist(MUNKIIMPORT_PREFS) except NSPropertyListSerializationException: prefs = {} return prefs
def GetPlistValue(key, secure=False, plist=None): """Returns the value of a given plist key. Args: key: string key to get from the plist. secure: boolean; True = munki secure plist, False = munki regular plist. plist: optional, str plist path to use, instead of Munki plist. Note, if plist is supplied, secure boolean is ignored. Returns: string value, or empty string if the key doesn't exist. """ if not plist: if secure: plist = DEFAULT_SECURE_MANAGED_INSTALLS_PLIST_PATH else: plist = DEFAULT_MANAGED_INSTALLS_PLIST_PATH if OBJC_OK: pl = fpl.readPlist(plist) return pl.get(key, '') # get XML output of (potential) binary plist from plutil. exit_code, plist_xml, unused_err = Exec( ['/usr/bin/plutil', '-convert', 'xml1', '-o', '-', plist]) if exit_code: logging.error('Failed to convert plist to xml1: %s', plist) return '' plist_contents = plistlib.readPlistFromString(plist_xml) return plist_contents.get(key, '')
def get_sys_profile(): """Get sysprofiler info. Returns: System Profiler report for networking, drives, and hardware as a plist dict, or an empty dict. """ command = [ '/usr/sbin/system_profiler', '-xml', 'SPHardwareDataType', 'SPStorageDataType', 'SPSoftwareDataType' ] try: output = subprocess.check_output(command) except subprocess.CalledProcessError: return {} try: system_profile = FoundationPlist.readPlistFromString(output) except FoundationPlist.FoundationPlistException: system_profile = {} # sytem_profiler gives us back an array; convert to a dict with just # the data we care about. results = {} for data_type in system_profile: key = data_type['_dataType'] results[key] = data_type['_items'] return results
def process_registered_apps(mau_config): apps = mau_config['Applications'] registered_apps = {} for app in apps: app_name = app.split("/")[-1].split(".")[0] if app_name != "": registered_apps[app_name] = {} for item in apps[app]: if item == 'Application ID': registered_apps[app_name]['application_id'] = apps[app][ item] registered_apps[app_name]['applicationpath'] = app try: info_plist = FoundationPlist.readPlist( app + "/Contents/Info.plist") app_name_lower = app_name.lower() if "remote_desktop" in app_name_lower or "onedrive" in app_name_lower or "teams" in app_name_lower or "company" in app_name_lower or "edge" in app_name_lower: registered_apps[app_name][ 'versionondisk'] = info_plist[ 'CFBundleShortVersionString'] else: registered_apps[app_name][ 'versionondisk'] = info_plist[ 'CFBundleVersion'] # registered_apps[app_name]['versionondisk'] = info_plist['CFBundleVersion'] except Exception: pass return registered_apps
def build_pkginfo_cache_with_errors(repo): """Build a dictionary of pkgsinfo. Args: repo: String path to the base of a Munki repo. Returns: Tuple of: Dictionary of pkgsinfo with: key: path to pkginfo. val: pkginfo dictionary. Dictionary of errors with: key: path to pkginfo. val: Exception message. """ pkginfos = {} errors = {} pkginfo_dir = os.path.join(repo, "pkgsinfo") for dirpath, _, filenames in os.walk(pkginfo_dir): for ifile in filter(is_pkginfo, filenames): path = os.path.join(dirpath, ifile) try: pkginfo_file = FoundationPlist.readPlist(path) except FoundationPlist.FoundationPlistException as error: errors[path] = error.message continue pkginfos[path] = pkginfo_file return (pkginfos, errors)
def get_managed_install_report(): """Return Munki ManagedInstallsReport.plist as a plist dict. Returns: ManagedInstalls report for last Munki run as a plist dict, or an empty dict. """ # Checks munki preferences to see where the install directory is set to. managed_install_dir = munkicommon.pref('ManagedInstallDir') # set the paths based on munki's configuration. managed_install_report = os.path.join( managed_install_dir, 'ManagedInstallReport.plist') munkicommon.display_debug2( "Looking for munki's ManagedInstallReport.plist at {} ...".format( managed_install_report)) try: munki_report = FoundationPlist.readPlist(managed_install_report) except FoundationPlist.FoundationPlistException: munki_report = {} if 'MachineInfo' not in munki_report: munki_report['MachineInfo'] = {} munkicommon.display_debug2('ManagedInstallReport.plist:') munkicommon.display_debug2(format_plist(munki_report)) return munki_report
def get_ard_info(): try: plist = FoundationPlist.readPlist("/Library/Preferences/com.apple.ARDAgent.plist") out = {} for item in plist: if item == 'Administrators': admin_json = [] admin_machines = [] for mac_address_entry in str(plist[item]).split(" };"): machine_entry = {} for mac_address in mac_address_entry.split('\n'): if " = " in mac_address: key = mac_address.split(' = ')[0].strip() if " = {" in mac_address: machine_entry["MAC_address"] = key elif key == "HasLatestReportingInfo": machine_entry[key] = to_bool(mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip()) elif key == "LastContact": machine_entry[key] = string_to_time(mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip()) elif key == "port": machine_entry[key] = str(mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip()) elif key == "ComputerName": value = mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip() machine_entry[key] = value admin_machines.append(value) else: machine_entry[key] = mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip() admin_json.append(machine_entry) out['administrators'] = json.dumps(admin_json[:-1]) try: out['admin_machines'] = ', '.join(admin_machines) except Exception: pass elif item == 'TaskServers': task_json = [] for mac_address_entry in str(plist[item]).split(" };"): task_entry = {} for mac_address in mac_address_entry.split('\n'): if " = " in mac_address: key = mac_address.split(' = ')[0].strip() if " = {" in mac_address: task_entry["MAC_address"] = key elif key == "port": task_entry[key] = str(mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip()) else: task_entry[key] = mac_address.split(' =')[1].replace('";', "").replace(';', "").replace(' "', "").strip() task_json.append(task_entry) out['task_servers'] = json.dumps(task_json[:-1]) return out except Exception: return {}
def get_update_feed_data(self, update_url): """Find the latest version of LaunchBar and output as a string.""" try: html = self.download(update_url) plist_data = plistlib.readPlistFromString(html) except BaseException as e: raise ProcessorError("Can't download %s: %s" % (update_url, e)) return plist_data
def UploadAllManagedInstallReports(on_corp, logout=False): """Uploads any installs, updates, uninstalls back to Simian server. If no reports of installs/updates/uninstalls exist to report, then this function only contacts the server if logout is True. Args: on_corp: str, on_corp status from GetClientIdentifier. logout: bool, default False, whether to logout or not when finished. """ # Report installs from the ManagedInstallsReport archives. archives_dir = os.path.join(munkicommon.pref('ManagedInstallDir'), 'Archives') if os.path.isdir(archives_dir): for fname in os.listdir(archives_dir): if not fname.startswith('ManagedInstallReport-'): continue install_report_path = os.path.join(archives_dir, fname) if not os.path.isfile(install_report_path): continue install_report, _ = GetManagedInstallReport( install_report_path=install_report_path) try: _UploadManagedInstallReport(on_corp, install_report) try: os.unlink(install_report_path) except (IOError, OSError): logging.warning( 'Failed to delete ManagedInstallsReport.plist: %s', install_report_path) except ServerRequestError: logging.exception( 'Error uploading ManagedInstallReport installs.') # Report installs from the current ManagedInstallsReport.plist. install_report, install_report_path = GetManagedInstallReport() try: _UploadManagedInstallReport(on_corp, install_report, logout=logout) # Clear reportable information now that is has been published. install_report['InstallResults'] = [] install_report['RemovalResults'] = [] install_report['ProblemInstalls'] = [] fpl.writePlist(install_report, install_report_path) except ServerRequestError: logging.exception('Error uploading ManagedInstallReport installs.')
def get_pkgid_version(this_pkg_plist, this_pkg_id): if this_pkg_id in this_pkg_plist: cmd = [pkgutil_path, "--pkg-info-plist", this_pkg_id] cmd_output = subprocess.check_output(cmd) cmd_output_plist = plistlib.readPlistFromString(cmd_output) pkg_version = cmd_output_plist['pkg-version'] return pkg_version else: return False
def pref(prefname): """Returns a preference for prefname""" try: _prefs = FoundationPlist.readPlist(PREFSPATH) except Exception: return None if prefname in _prefs: return _prefs[prefname] else: return None
def main(): uptime_seconds = get_uptime() plist_path = '/usr/local/sal/plugin_results.plist' if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) else: plist = [] result = {} result['plugin'] = 'Uptime' result['historical'] = False data = {} data['UptimeDays'] = uptime_seconds / 60 / 60 / 24 data['UptimeSeconds'] = uptime_seconds result['data'] = data plist.append(result) FoundationPlist.writePlist(plist, plist_path)
def main(): plist_path = ( '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist') if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) version = str(plist['Version']) else: version = 'Not supported' add_plugin_results('XprotectVersion', {'Version': version})
def build_prefs(): # If munkiimport prefs exist, offer them as defaults. munkiimport_prefs = get_munkiimport_prefs() keys = ("repo_path", "repo_url") prefs = {} print("No preference file was found for Spruce. Please allow me to " "break it down for you.") for key in keys: choice = None while choice is None: default = munkiimport_prefs.get(key, "") choice = raw_input( "Please enter a value for '{}' or hit enter to use the " "default value '{}': ".format(key, default)) prefs[key] = choice if choice else default FoundationPlist.writePlist(prefs, SPRUCE_PREFS) return prefs
def UploadAllManagedInstallReports(on_corp, logout=False): """Uploads any installs, updates, uninstalls back to Simian server. If no reports of installs/updates/uninstalls exist to report, then this function only contacts the server if logout is True. Args: on_corp: str, on_corp status from GetClientIdentifier. logout: bool, default False, whether to logout or not when finished. """ # Report installs from the ManagedInstallsReport archives. archives_dir = os.path.join(munkicommon.pref('ManagedInstallDir'), 'Archives') if os.path.isdir(archives_dir): for fname in os.listdir(archives_dir): if not fname.startswith('ManagedInstallReport-'): continue install_report_path = os.path.join(archives_dir, fname) if not os.path.isfile(install_report_path): continue install_report, _ = GetManagedInstallReport( install_report_path=install_report_path) try: _UploadManagedInstallReport(on_corp, install_report) try: os.unlink(install_report_path) except (IOError, OSError): logging.warning( 'Failed to delete ManagedInstallsReport.plist: %s', install_report_path) except ServerRequestError: logging.exception('Error uploading ManagedInstallReport installs.') # Report installs from the current ManagedInstallsReport.plist. install_report, install_report_path = GetManagedInstallReport() try: _UploadManagedInstallReport(on_corp, install_report, logout=logout) # Clear reportable information now that is has been published. install_report['InstallResults'] = [] install_report['RemovalResults'] = [] install_report['ProblemInstalls'] = [] fpl.writePlist(install_report, install_report_path) except ServerRequestError: logging.exception('Error uploading ManagedInstallReport installs.')
def build_prefs(): # If munkiimport prefs exist, offer them as defaults. munkiimport_prefs = get_munkiimport_prefs() keys = ("repo_path", "repo_url") prefs = {} print ("No preference file was found for Spruce. Please allow me to " "break it down for you.") for key in keys: choice = None while choice is None: default = munkiimport_prefs.get(key, "") choice = raw_input( "Please enter a value for '{}' or hit enter to use the " "default value '{}': ".format(key, default)) prefs[key] = choice if choice else default FoundationPlist.writePlist(prefs, SPRUCE_PREFS) return prefs
def get_update_feed_data(self, update_url): """Find the latest version of LaunchBar and output as a string.""" try: f = urllib2.urlopen(update_url) html = f.read() plist_data = plistlib.readPlistFromString(html) f.close() except BaseException as e: raise ProcessorError("Can't download %s: %s" % (update_url, e)) return plist_data
def get_app_bundle_version(app_path): '''Return the CFBundleVersion of the app based on its path''' try: info_plist = FoundationPlist.readPlist(app_path + "/Contents/Info.plist") return info_plist['CFBundleVersion'] except Exception: return ""
def ard_access_check(): """Check for local users who have ARD permissions First we need to check if all users are allowed. If not, we look for granular permissions in the directory. Thank you @frogor and @foigus for help on the directory part.""" # First method: check if all users are permitted. # Thank you to @steffan for pointing out this plist key! plist_path = '/Library/Preferences/com.apple.RemoteManagement.plist' if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) if plist.get('ARD_AllLocalUsers', None): return "All users permitted" else: # Second method - check local directory for naprivs sp = subprocess.Popen(['dscl', '.', '-list', '/Users'], stdout=subprocess.PIPE) out, err = sp.communicate() user_list = out.split() ard_users = [] for user in user_list: if user[0] in '_': continue else: args = '/Users/' + user sp = subprocess.Popen( ['dscl', '.', '-read', args, 'naprivs'], stderr=subprocess.PIPE, stdout=subprocess.PIPE) out, err = sp.communicate() if out not in 'No such key': ard_users.append(user) else: pass remote_user_check = subprocess.Popen( ['dscl', '.', 'list', '/Groups'], stdout=subprocess.PIPE) remote_out, remote_err = remote_user_check.communicate() ard_user_list = [] if "com.apple.local.ard_interact" in remote_out: ard_user_sp = subprocess.Popen([ 'dscl', '.', 'read', '/Groups/com.apple.local.ard_interact', 'GroupMembership' ], stdout=subprocess.PIPE) ard_user_out, ard_user_err = ard_user_sp.communicate() ard_user_list = ard_user_out.split() ard_users.extend(ard_user_list[1:]) return ard_users else: # plist_path does not exist, which indicates that ARD is not enabled. return "ARD Disabled"
def UploadAllManagedInstallReports(client, on_corp): """Uploads any installs, updates, uninstalls back to Simian server. Args: client: A SimianAuthClient. on_corp: str, on_corp status from GetClientIdentifier. """ # Report installs from the ManagedInstallsReport archives. archives_dir = os.path.join(munkicommon.pref('ManagedInstallDir'), 'Archives') if os.path.isdir(archives_dir): for fname in os.listdir(archives_dir): if not fname.startswith('ManagedInstallReport-'): continue install_report_path = os.path.join(archives_dir, fname) if not os.path.isfile(install_report_path): continue install_report, _ = GetManagedInstallReport( install_report_path=install_report_path) try: _UploadManagedInstallReport(client, on_corp, install_report) try: os.unlink(install_report_path) except (IOError, OSError): logging.warning( 'Failed to delete ManagedInstallsReport.plist: %s', install_report_path) except ServerRequestError: logging.exception( 'Error uploading ManagedInstallReport installs.') # Report installs from the current ManagedInstallsReport.plist. install_report, install_report_path = GetManagedInstallReport() try: _UploadManagedInstallReport(client, on_corp, install_report) # Clear reportable information now that is has been published. install_report['InstallResults'] = [] install_report['RemovalResults'] = [] install_report['ProblemInstalls'] = [] fpl.writePlist(install_report, install_report_path) except ServerRequestError: logging.exception('Error uploading ManagedInstallReport installs.')
def main(): plist_path = ( '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist' ) if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) version = str(plist['Version']) else: version = 'Not supported' add_plugin_results('XprotectVersion', {'Version': version})
def get_prefs(): # If prefs don't exist yet, offer to help create them. try: prefs = FoundationPlist.readPlist(SPRUCE_PREFS) except FoundationPlist.NSPropertyListSerializationException: prefs = None if not prefs or not prefs.get("repo_path"): prefs = build_prefs() return prefs
def add_plugin_results(plugin, data, historical=False): """Add data to the shared plugin results plist. This function creates the shared results plist file if it does not already exist; otherwise, it adds the entry by appending. Args: plugin (str): Name of the plugin returning data. data (dict): Dictionary of results. historical (bool): Whether to keep only one record (False) or all results (True). Optional, defaults to False. """ plist_path = '/usr/local/sal/plugin_results.plist' if os.path.exists(plist_path): plugin_results = FoundationPlist.readPlist(plist_path) else: plugin_results = [] plugin_results.append({'plugin': plugin, 'historical': historical, 'data': data}) FoundationPlist.writePlist(plugin_results, plist_path)
def get_user_config(): # Get the MAU's config as seen from the current or last person logged in # Because some settings are user specific try: mau_config = FoundationPlist.readPlist( get_user_path() + "/Library/Preferences/com.microsoft.autoupdate2.plist") mau_config_items = {} for item in mau_config: if item == 'UpdateCache': mau_config_items['updatecache'] = mau_config[item] elif item == 'ManifestServer': mau_config_items['manifestserver'] = mau_config[item] elif item == 'AutoUpdateVersion': mau_config_items['autoupdateversion'] = mau_config[item] elif item == 'ChannelName': mau_config_items['channelname'] = mau_config[item] elif item == 'HowToCheck': mau_config_items['howtocheck'] = mau_config[item] elif item == 'LastCheckForUpdates' or item == 'LastUpdate': if mau_config[item] != "Dec 29, 1 at 7:03:58 PM": pattern = '%Y-%m-%d %H:%M:%S +0000' mau_config_items['lastcheckforupdates'] = int( time.mktime( time.strptime( str(mau_config[item]).replace(" at ", ", "), pattern))) elif item == 'StartDaemonOnAppLaunch': mau_config_items['startdaemononapplaunch'] = to_bool( mau_config[item]) elif item == 'Applications': mau_config_items[ 'registeredapplications'] = process_registered_apps( mau_config) # Add in update information if enabled msupdate_check_enabled = to_bool( CFPreferencesCopyAppValue('msupdate_check_enabled', 'org.munkireport.ms_office')) if os.path.exists( '/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate' ) and msupdate_check_enabled == 1: mau_config_items = get_msupdate_update_check(mau_config_items) mau_config_items['msupdate_check_enabled'] = 1 else: mau_config_items['msupdate_check_enabled'] = 0 return (mau_config_items) except Exception: return {}
def GetManagedInstallReport(install_report_path=None): """Returns the ManagedInstallReport.plist plist object.""" if not install_report_path: managed_installs_dir = munkicommon.pref('ManagedInstallDir') install_report_path = os.path.join( managed_installs_dir, 'ManagedInstallReport.plist') try: install_report = fpl.readPlist(install_report_path) except fpl.NSPropertyListSerializationException, e: logging.debug('Error reading %s : %s', install_report_path, str(e)) return {}, install_report_path
def UploadAllManagedInstallReports(client, on_corp): """Uploads any installs, updates, uninstalls back to Simian server. Args: client: A SimianAuthClient. on_corp: str, on_corp status from GetClientIdentifier. """ # Report installs from the ManagedInstallsReport archives. archives_dir = os.path.join(munkicommon.pref('ManagedInstallDir'), 'Archives') if os.path.isdir(archives_dir): for fname in os.listdir(archives_dir): if not fname.startswith('ManagedInstallReport-'): continue install_report_path = os.path.join(archives_dir, fname) if not os.path.isfile(install_report_path): continue install_report, _ = GetManagedInstallReport( install_report_path=install_report_path) try: _UploadManagedInstallReport(client, on_corp, install_report) try: os.unlink(install_report_path) except (IOError, OSError): logging.warning( 'Failed to delete ManagedInstallsReport.plist: %s', install_report_path) except ServerRequestError: logging.exception('Error uploading ManagedInstallReport installs.') # Report installs from the current ManagedInstallsReport.plist. install_report, install_report_path = GetManagedInstallReport() try: _UploadManagedInstallReport(client, on_corp, install_report) # Clear reportable information now that is has been published. install_report['InstallResults'] = [] install_report['RemovalResults'] = [] install_report['ProblemInstalls'] = [] fpl.writePlist(install_report, install_report_path) except ServerRequestError: logging.exception('Error uploading ManagedInstallReport installs.')
def main(): install_report_path = "/Library/Managed Installs/ManagedInstallReport.plist" install_report_data = plistlib.readPlist(install_report_path) install_end = install_report_data['EndTime'] install_end_parsed = parser.parse(install_end) to_zone = tz.gettz(time.tzname[time.daylight]) install_end_local = install_end_parsed.astimezone(to_zone) result_date_format = "%Y-%m-%d %H:%M:%S" install_end_date = install_end_local.strftime(result_date_format) extension_attribute = install_end_date print_extension_attribute(extension_attribute)
def getBundleInfo(path): """ Returns Info.plist data if available for bundle at path """ infopath = os.path.join(path, "Contents", "Info.plist") if not os.path.exists(infopath): infopath = os.path.join(path, "Resources", "Info.plist") if os.path.exists(infopath): try: plist = FoundationPlist.readPlist(infopath) return plist except FoundationPlist.NSPropertyListSerializationException: pass return None
def findItemsToCheck(repo_path, itemlist=None): '''Builds a list of items to check; only the latest version of an item is retained. If itemlist is given, include items only on that list.''' all_catalog_path = os.path.join(repo_path, 'catalogs/all') catalogitems = FoundationPlist.readPlist(all_catalog_path) itemdb = {} for catalogitem in catalogitems: if itemlist and catalogitem['name'] not in itemlist: continue name = catalogitem['name'] if name not in itemdb: itemdb[name] = catalogitem elif (munkicommon.MunkiLooseVersion(catalogitem['version']) > munkicommon.MunkiLooseVersion(itemdb[name]['version'])): itemdb[name] = catalogitem pkg_list = [] for key in itemdb.keys(): pkg_list.append(itemdb[key]) return pkg_list
def get_manifests(): # TODO: Add handling similar to pkgsinfo for errors. Add errors # to report. manifest_dir = os.path.join(get_repo_path(), "manifests") manifests = {} for dirpath, dirnames, filenames in os.walk(manifest_dir): for dirname in dirnames: if dirname.startswith("."): dirnames.remove(dirname) for filename in filenames: if filename not in IGNORED_FILES and not filename.startswith("."): manifest_filename = os.path.join(dirpath, filename) try: manifests[manifest_filename] = FoundationPlist.readPlist( manifest_filename) except FoundationPlist.NSPropertyListSerializationException as err: robo_print("Failed to open manifest '{}' with error " "'{}'.".format(manifest_filename, err.message), LogLevel.WARNING) return manifests
if options.checkstate: updatecheck.MACHINE = munkicommon.getMachineFacts() updatecheck.CONDITIONS = munkicommon.getConditions() updatecheck.getCatalogs(cataloglist) for check_item in options.checkstate: installed_state = "unknown" item_pl = updatecheck.getItemDetail(check_item, cataloglist) if item_pl: if updatecheck.installedState(item_pl): installed_state = "installed" exit_code = 0 else: installed_state = "not installed" exit_code = 1 print "%s: %s" % (check_item, installed_state) exit(exit_code) if not options.install and not options.uninstall: exit() manifest = {} manifest["catalogs"] = cataloglist manifest["managed_installs"] = options.install or [] manifest["managed_uninstalls"] = options.uninstall or [] FoundationPlist.writePlist(manifest, "/tmp/localmanifest.plist") updatecheckresult = updatecheck.check(localmanifestpath="/tmp/localmanifest.plist") if updatecheckresult == 1: need_to_restart = installer.run() if need_to_restart: print "Please restart immediately!"
def get_all_catalog(): """Return the Munki 'all' catalog as a plist dict.""" munki_repo = get_repo_path() all_path = os.path.join(munki_repo, "catalogs", "all") return FoundationPlist.readPlist(all_path)
from munkilib import FoundationPlist, munkicommon import os from datetime import datetime FILE_LOCATION = "/Users/Shared/.msc-dnd.plist" # Does the file exist? if not os.path.isfile(FILE_LOCATION): # File isn't here, set the Munki pref to False munkicommon.set_pref('SuppressUserNotification', False) sys.exit(0) # If it does, get the current date? else: plist = FoundationPlist.readPlist(FILE_LOCATION) if 'DNDEndDate' not in plist: # The key we need isn't in there, remove the file, set pref and exit os.remove(FILE_LOCATION) munkicommon.set_pref('SuppressUserNotification', False) sys.exit(0) else: # Is the current date greater than the DND date? saved_time = datetime.strptime(str(plist['DNDEndDate']), "%Y-%m-%d %H:%M:%S +0000") current_time = datetime.now() if saved_time < current_time: # print "Current time is greater" # If yes, remove the file and set the Munki pref for suppress notifications to False os.remove(FILE_LOCATION) munkicommon.set_pref('SuppressUserNotification', False) sys.exit(0)
if item_pl: if updatecheck.installedState(item_pl): installed_state = "installed" exit_code = 0 else: installed_state = "not installed" exit_code = 1 print("%s: %s") % (check_item, installed_state) sys.exit(exit_code) if not options.install and not options.uninstall: sys.exit() temp_dir = tempfile.mkdtemp() temp_plist = temp_dir + "/localmanifest.plist" manifest = {} manifest["catalogs"] = cataloglist manifest["managed_installs"] = options.install or [] manifest["managed_uninstalls"] = options.uninstall or [] FoundationPlist.writePlist(manifest, temp_plist) updatecheckresult = updatecheck.check(localmanifestpath=temp_plist) if updatecheckresult == 1: need_to_restart = installer.run() if need_to_restart: print("Please restart immediately!") try: shutil.rmtree(temp_dir) except OSError: print("Could not remove temp directory")
def main(): # Skip a manual check if len(sys.argv) > 1: if sys.argv[1] == 'manualcheck': munkicommon.display_debug2("Manual check: skipping MunkiInfo Plugin") exit(0) prefs_to_get = [ 'ManagedInstallDir', 'SoftwareRepoURL', 'ClientIdentifier', 'LogFile', 'LoggingLevel', 'LogToSyslog', 'InstallAppleSoftwareUpdates', 'AppleSoftwareUpdatesOnly', 'SoftwareUpdateServerURL', 'DaysBetweenNotifications', 'LastNotifiedDate', 'UseClientCertificate', 'SuppressUserNotification', 'SuppressAutoInstall', 'SuppressStopButtonOnInstall', 'PackageVerificationMode', 'FollowHTTPRedirects', 'UnattendedAppleUpdates', 'ClientCertificatePath', 'ClientKeyPath', 'LastAppleSoftwareUpdateCheck', 'LastCheckDate', 'LastCheckResult', 'LogFile', 'SoftwareRepoCACertificate', 'SoftwareRepoCAPath', 'PackageURL', 'CatalogURL', 'ManifestURL', 'IconURL', 'ClientResourceURL', 'ClientResourcesFilename', 'HelpURL', 'UseClientCertificateCNAsClientIdentifier', 'AdditionalHttpHeaders', 'SuppressLoginwindowInstall', 'InstallRequiresLogout', 'ShowRemovalDetail', 'MSULogEnabled', 'MSUDebugLogEnabled', 'LocalOnlyManifest', 'UnattendedAppleUpdates' ] plist_path = '/usr/local/sal/plugin_results.plist' if os.path.exists(plist_path): plist = FoundationPlist.readPlist(plist_path) else: plist = [] result = {} result['plugin'] = 'MunkiInfo' result['historical'] = False data = {} for the_pref in prefs_to_get: data[the_pref] = str(munkicommon.pref(the_pref)) result['data'] = data plist.append(result) FoundationPlist.writePlist(plist, plist_path)
def getiteminfo(itempath): """ Gets info for filesystem items passed to makecatalog item, to be used for the "installs" key. Determines if the item is an application, bundle, Info.plist, or a file or directory and gets additional metadata for later comparison. """ infodict = {} if munkicommon.isApplication(itempath): infodict['type'] = 'application' infodict['path'] = itempath plist = getBundleInfo(itempath) for key in ['CFBundleName', 'CFBundleIdentifier', 'CFBundleShortVersionString', 'CFBundleVersion']: if key in plist: infodict[key] = plist[key] if 'LSMinimumSystemVersion' in plist: infodict['minosversion'] = plist['LSMinimumSystemVersion'] elif 'SystemVersionCheck:MinimumSystemVersion' in plist: infodict['minosversion'] = \ plist['SystemVersionCheck:MinimumSystemVersion'] else: infodict['minosversion'] = '10.6' elif os.path.exists(os.path.join(itempath, 'Contents', 'Info.plist')) or \ os.path.exists(os.path.join(itempath, 'Resources', 'Info.plist')): infodict['type'] = 'bundle' infodict['path'] = itempath plist = getBundleInfo(itempath) for key in ['CFBundleShortVersionString', 'CFBundleVersion']: if key in plist: infodict[key] = plist[key] elif itempath.endswith("Info.plist") or \ itempath.endswith("version.plist"): infodict['type'] = 'plist' infodict['path'] = itempath try: plist = FoundationPlist.readPlist(itempath) for key in ['CFBundleShortVersionString', 'CFBundleVersion']: if key in plist: infodict[key] = plist[key] except FoundationPlist.NSPropertyListSerializationException: pass # let's help the admin -- if CFBundleShortVersionString is empty # or doesn't start with a digit, and CFBundleVersion is there # use CFBundleVersion as the version_comparison_key if (not infodict.get('CFBundleShortVersionString') or infodict['CFBundleShortVersionString'][0] not in '0123456789'): if infodict.get('CFBundleVersion'): infodict['version_comparison_key'] = 'CFBundleVersion' elif 'CFBundleShortVersionString' in infodict: infodict['version_comparison_key'] = 'CFBundleShortVersionString' if not 'CFBundleShortVersionString' in infodict and \ not 'CFBundleVersion' in infodict: infodict['type'] = 'file' infodict['path'] = itempath if os.path.isfile(itempath): infodict['md5checksum'] = munkicommon.getmd5hash(itempath) return infodict
Adds Internet Plug-Ins to the Application Inventory data that is gathered by munki. Thanks to Adam Reed and Josh Malone """ import os import sys sys.path.insert(0,'/usr/local/munki') from munkilib import FoundationPlist invPath = r"/Library/Managed Installs/ApplicationInventory.plist" plugins = r"/Library/Internet Plug-Ins/" directoryListing = os.listdir(plugins) appinv = FoundationPlist.readPlist(invPath) print "Adding %i plugins" % len(directoryListing) for x in directoryListing: path = os.path.join(plugins, x, 'Contents/Info.plist') try: info = FoundationPlist.readPlist(path) plugin = {} plugin['CFBundleName'] = info.get('CFBundleName', x) plugin['bundleid'] = info.get('CFBundleIdentifier', 'N/A') plugin['version'] = info.get('CFBundleVersion','N/A') plugin['path'] = os.path.join(plugins, x) plugin['name'] = info.get('CFBundleName', os.path.splitext(os.path.basename(x))[0]) appinv.append(plugin.copy()) except Exception, message:
updatecheck.getResourceIfChangedAtomically('%s/repair' % url, download) except fetch.MunkiDownloadError, e: raise RepairClientError( 'MunkiDownloadError getting Munki client: %s' % str(e)) return_code, stdout, stderr = Exec( ['/usr/bin/hdiutil', 'attach', '-mountRandom', '/tmp', '-nobrowse', '-plist', '/tmp/munkiclient.dmg']) if return_code != 0: raise RepairClientError( 'Failed to attach dmg with ret %s. Error: %s' % (return_code, stderr)) # Get the mount point of the the mounted dmg; NOTE: if the munki dmg ever has # multiple mount points then this will need adjusting. mount_point = None pl = fpl.readPlistFromString(stdout) for item in pl['system-entities']: if 'mount-point' in item: mount_point = item['mount-point'] if not mount_point or not os.path.isdir(mount_point): raise RepairClientError('Mount point not found:' % mount_point) return_code, stdout, stderr = Exec( ['/usr/sbin/installer', '-pkg', '%s/munkitools.pkg' % mount_point, '-target', '/']) if return_code != 0: raise RepairClientError( 'Failed to install pkg with ret %s. Error: %s' % (return_code, stderr)) unused_return_code, unused_stdout, unused_stderr = Exec( ['/usr/bin/hdiutil', 'detach', mount_point, '-force'])