/* * Get the login items available in System Preferences * * Based on * https://github.com/synack/knockknock/blob/master/plugins/loginItem.py */ void getLoginItems(QueryData& results) { for (const auto& dir : getHomeDirectories()) { pt::ptree tree; fs::path plist_path = dir / kLoginItemsPlistPath; try { if (!fs::exists(plist_path) || !fs::is_regular_file(plist_path)) { continue; } } catch (const fs::filesystem_error& e) { // Likely permission denied VLOG(1) << "Error checking path " << plist_path << ": " << e.what(); continue; } auto status = osquery::parsePlist(plist_path.string(), tree); if (!status.ok()) { VLOG(1) << "Error parsing " << plist_path << ": " << status.toString(); continue; } // Enumerate Login Items if we successfully opened the plist for (const auto& entry : tree.get_child(kLoginItemsKeyPath)) { Row r; auto name = entry.second.get<std::string>("Name"); r["name"] = name; r["type"] = "Login Item"; r["source"] = plist_path.string(); auto alias_data = entry.second.get<std::string>("Alias"); try { std::string bin_path; if (!parseAliasData(alias_data, bin_path).ok()) { VLOG(1) << "No valid path found for " << name << " in " << plist_path; } r["path"] = bin_path; } catch (const std::exception& e) { VLOG(1) << "Error parsing alias data for " << name << " in " << plist_path; } results.push_back(r); } } }
void genLoginItems(const fs::path& homedir, QueryData& results) { pt::ptree tree; fs::path sipath = homedir / kLoginItemsPlistPath; if (!pathExists(sipath.string()).ok() || !isReadable(sipath.string()).ok()) { // User does not have a startup items list, or bad permissions. return; } if (!osquery::parsePlist(sipath.string(), tree).ok()) { // Could not parse the user's startup items plist. return; } // Enumerate Login Items if we successfully opened the plist. for (const auto& plist_path : kLoginItemsKeyPaths) { try { for (const auto& entry : tree.get_child(plist_path)) { Row r; r["name"] = entry.second.get<std::string>("Name", ""); r["type"] = "Login Item"; r["source"] = sipath.string(); auto alias_data = entry.second.get<std::string>("Alias", ""); std::string bin_path; if (!parseAliasData(alias_data, bin_path).ok()) { VLOG(1) << "No valid path found for " << r["name"] << " in " << sipath; } r["path"] = bin_path; results.push_back(r); } } catch (const pt::ptree_error& e) { continue; } } }