mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-07 09:58:54 +00:00
Merge pull request #1224 from theopolis/duti_table
OS X application duti/scheme listing table
This commit is contained in:
commit
53c407781f
@ -51,6 +51,8 @@ namespace osquery {
|
||||
#define BIGINT(x) boost::lexical_cast<std::string>(x)
|
||||
/// See the affinity type documentation for TEXT.
|
||||
#define UNSIGNED_BIGINT(x) boost::lexical_cast<std::string>(x)
|
||||
/// See the affinity type documentation for TEXT.
|
||||
#define DOUBLE(x) boost::lexical_cast<std::string>(x)
|
||||
|
||||
/**
|
||||
* @brief The SQLite type affinities as represented as implementation literals.
|
||||
@ -67,6 +69,8 @@ namespace osquery {
|
||||
#define BIGINT_LITERAL long long int
|
||||
/// See the literal type documentation for TEXT_LITERAL.
|
||||
#define UNSIGNED_BIGINT_LITERAL unsigned long long int
|
||||
/// See the literal type documentation for TEXT_LITERAL.
|
||||
#define DOUBLE_LITERAL double
|
||||
/// Cast an SQLite affinity type to the literal type.
|
||||
#define AS_LITERAL(literal, value) boost::lexical_cast<literal>(value)
|
||||
|
||||
@ -89,7 +93,7 @@ enum ConstraintOperator : unsigned char {
|
||||
GREATER_THAN_OR_EQUALS = 32
|
||||
};
|
||||
|
||||
/// Type for flags for what constraint operators are admissable.
|
||||
/// Type for flags for what constraint operators are admissible.
|
||||
typedef unsigned char ConstraintOperatorFlag;
|
||||
/// Flag for any operator type.
|
||||
#define ANY_OP 0xFFU
|
||||
|
@ -172,7 +172,7 @@ Initializer::Initializer(int& argc, char**& argv, ToolType tool)
|
||||
if (Flag::isDefault("database_path")) {
|
||||
osquery::FLAGS_database_path = homedir + "/shell.db";
|
||||
}
|
||||
if (Flag::isDefault("extension_socket")) {
|
||||
if (Flag::isDefault("extensions_socket")) {
|
||||
osquery::FLAGS_extensions_socket = homedir + "/shell.em";
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +144,16 @@ int xColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col) {
|
||||
<< ") to BIGINT";
|
||||
}
|
||||
sqlite3_result_int64(ctx, afinite);
|
||||
} else if (type == "DOUBLE") {
|
||||
double afinite;
|
||||
try {
|
||||
afinite = boost::lexical_cast<double>(value);
|
||||
} catch (const boost::bad_lexical_cast &e) {
|
||||
afinite = 0;
|
||||
VLOG(1) << "Error casting" << column_name << " (" << value
|
||||
<< ") to DOUBLE";
|
||||
}
|
||||
sqlite3_result_double(ctx, afinite);
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
|
@ -8,6 +8,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
@ -18,6 +20,8 @@
|
||||
#include <osquery/tables.h>
|
||||
#include <osquery/sql.h>
|
||||
|
||||
#include "osquery/core/conversions.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
@ -47,6 +51,110 @@ const std::vector<std::string> kHomeDirSearchPaths = {
|
||||
"Applications", "Desktop", "Downloads",
|
||||
};
|
||||
|
||||
enum AppSchemeFlags {
|
||||
kSchemeNormal = 0,
|
||||
// Default flag from the list of schemes on a default OS X 10.10 install.
|
||||
kSchemeSystemDefault = 1,
|
||||
// Protected flag from Apple Reference: Inter-app Communication
|
||||
kSchemeProtected = 2,
|
||||
};
|
||||
|
||||
const std::map<std::string, unsigned short> kApplicationSchemes = {
|
||||
{"account", 0},
|
||||
{"addressbook", kSchemeSystemDefault},
|
||||
{"afp", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"aim", kSchemeSystemDefault},
|
||||
{"alfred", 0},
|
||||
{"alfredapp", 0},
|
||||
{"app-prefs", 0},
|
||||
{"applefeedback", kSchemeSystemDefault},
|
||||
{"applescript", kSchemeSystemDefault},
|
||||
{"apupdate", kSchemeSystemDefault},
|
||||
{"at", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"atom", 0},
|
||||
{"bluejeans", 0},
|
||||
{"calinvite", 0},
|
||||
{"calinvitelist", 0},
|
||||
{"callto", 0},
|
||||
{"calshow", 0},
|
||||
{"cloudphoto", kSchemeSystemDefault},
|
||||
{"conf", 0},
|
||||
{"daap", kSchemeSystemDefault},
|
||||
{"dict", kSchemeSystemDefault},
|
||||
{"facetime", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"fb", kSchemeSystemDefault},
|
||||
{"fbauth", 0},
|
||||
{"file", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"ftp", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"gamecenter", kSchemeSystemDefault},
|
||||
{"gopher", 0},
|
||||
{"grammar", 0},
|
||||
{"h323", 0},
|
||||
{"help", kSchemeSystemDefault},
|
||||
{"http", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"https", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"iadoptout", 0},
|
||||
{"ibooks", kSchemeSystemDefault},
|
||||
{"ical", kSchemeSystemDefault},
|
||||
{"ichat", kSchemeSystemDefault},
|
||||
{"icloud-sharing", kSchemeSystemDefault},
|
||||
{"im", kSchemeSystemDefault},
|
||||
{"imessage", kSchemeSystemDefault},
|
||||
{"ipps", kSchemeSystemDefault},
|
||||
{"irc", 0},
|
||||
{"itls", kSchemeSystemDefault},
|
||||
{"itms", kSchemeSystemDefault},
|
||||
{"itms-books", kSchemeSystemDefault},
|
||||
{"itms-bookss", kSchemeSystemDefault},
|
||||
{"itmsp-app", 0},
|
||||
{"itunesradio", kSchemeSystemDefault},
|
||||
{"macappstore", kSchemeSystemDefault},
|
||||
{"macappstores", kSchemeSystemDefault},
|
||||
{"mailto", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"map", 0},
|
||||
{"maps", kSchemeSystemDefault},
|
||||
{"message", kSchemeSystemDefault},
|
||||
{"messages", kSchemeSystemDefault},
|
||||
{"ms-excel", 0},
|
||||
{"ms-word", 0},
|
||||
{"munki", 0},
|
||||
{"news", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"nntp", 0},
|
||||
{"nwnode", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"omnifocus", 0},
|
||||
{"ophttp", 0},
|
||||
{"pcast", kSchemeSystemDefault},
|
||||
{"photos", kSchemeSystemDefault},
|
||||
{"photos-event", 0},
|
||||
{"photos-migrate-iphoto", 0},
|
||||
{"photos-redirect", 0},
|
||||
{"powerpoint", 0},
|
||||
{"prefs", 0},
|
||||
{"qs", 0},
|
||||
{"qsinstall", 0},
|
||||
{"qss-http", 0},
|
||||
{"qssp-http", 0},
|
||||
{"reminders", kSchemeSystemDefault},
|
||||
{"rtsp", kSchemeSystemDefault},
|
||||
{"shoebox", 0},
|
||||
{"slack", 0},
|
||||
{"smb", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"sms", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"ssh", kSchemeSystemDefault},
|
||||
{"tel", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"telnet", kSchemeSystemDefault},
|
||||
{"twitter", kSchemeSystemDefault},
|
||||
{"txmt", 0},
|
||||
{"vnc", kSchemeSystemDefault | kSchemeProtected},
|
||||
{"wais", 0},
|
||||
{"webapp", 0},
|
||||
{"webcal", kSchemeSystemDefault},
|
||||
{"whois", 0},
|
||||
{"wunderlist", 0},
|
||||
{"xmpp", kSchemeSystemDefault},
|
||||
{"yelp", 0},
|
||||
};
|
||||
|
||||
void genApplicationsFromPath(const fs::path& path,
|
||||
std::vector<std::string>& apps) {
|
||||
std::vector<std::string> new_apps;
|
||||
@ -93,13 +201,20 @@ QueryData genApps(QueryContext& context) {
|
||||
|
||||
// Walk through several groups of common search paths that may contain apps.
|
||||
std::vector<std::string> apps;
|
||||
genApplicationsFromPath("/Applications", apps);
|
||||
if (context.constraints["path"].exists(EQUALS)) {
|
||||
auto app_constraints = context.constraints["path"].getAll(EQUALS);
|
||||
for (const auto& app : app_constraints) {
|
||||
apps.push_back((fs::path(app) / "Contents/Info.plist").string());
|
||||
}
|
||||
} else {
|
||||
genApplicationsFromPath("/Applications", apps);
|
||||
|
||||
// List all users on the system, and walk common search paths with homes.
|
||||
auto homes = osquery::getHomeDirectories();
|
||||
for (const auto& home : homes) {
|
||||
for (const auto& path : kHomeDirSearchPaths) {
|
||||
genApplicationsFromPath(home / path, apps);
|
||||
// List all users on the system, and walk common search paths with homes.
|
||||
auto homes = osquery::getHomeDirectories();
|
||||
for (const auto& home : homes) {
|
||||
for (const auto& path : kHomeDirSearchPaths) {
|
||||
genApplicationsFromPath(home / path, apps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,11 +225,6 @@ QueryData genApps(QueryContext& context) {
|
||||
|
||||
// For each found application (path with an Info.plist) parse the plist.
|
||||
for (const auto& path : apps) {
|
||||
if (!context.constraints["path"].matches(path)) {
|
||||
// Optimize by not searching when a path is a constraint.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!osquery::parsePlist(path, tree).ok()) {
|
||||
TLOG << "Error parsing application plist: " << path;
|
||||
continue;
|
||||
@ -126,5 +236,73 @@ QueryData genApps(QueryContext& context) {
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
QueryData genAppSchemes(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
for (const auto& scheme : kApplicationSchemes) {
|
||||
auto protocol = scheme.first + "://";
|
||||
auto cfprotocol = CFStringCreateWithCString(
|
||||
kCFAllocatorDefault, protocol.c_str(), protocol.length());
|
||||
if (cfprotocol == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a "fake" URL that only contains the protocol component of a URI.
|
||||
auto url = CFURLCreateWithString(kCFAllocatorDefault, cfprotocol, nullptr);
|
||||
CFRelease(cfprotocol);
|
||||
if (url == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// List all application bundles that request this protocol scheme.
|
||||
auto apps = LSCopyApplicationURLsForURL(url, kLSRolesAll);
|
||||
if (apps == nullptr) {
|
||||
CFRelease(url);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check the default handler assigned to the protocol scheme.
|
||||
auto default_app =
|
||||
LSCopyDefaultApplicationURLForURL(url, kLSRolesAll, nullptr);
|
||||
CFRelease(url);
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(apps); i++) {
|
||||
Row r;
|
||||
r["scheme"] = scheme.first;
|
||||
|
||||
auto app = CFArrayGetValueAtIndex(apps, i);
|
||||
if (app == nullptr || CFGetTypeID(app) != CFURLGetTypeID()) {
|
||||
// Handle problems with application listings.
|
||||
continue;
|
||||
}
|
||||
|
||||
auto path = CFURLCopyFileSystemPath((CFURLRef)app, kCFURLPOSIXPathStyle);
|
||||
if (path == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
r["handler"] = stringFromCFString(path);
|
||||
CFRelease(path);
|
||||
// Check if the handler is set (in the OS) as the default.
|
||||
if (default_app != nullptr &&
|
||||
CFEqual((CFTypeRef)app, (CFTypeRef)default_app)) {
|
||||
r["enabled"] = "1";
|
||||
} else {
|
||||
r["enabled"] = "0";
|
||||
}
|
||||
r["external"] = (scheme.second & kSchemeSystemDefault) ? "0" : "1";
|
||||
r["protected"] = (scheme.second & kSchemeProtected) ? "1" : "0";
|
||||
results.push_back(r);
|
||||
}
|
||||
|
||||
if (default_app != nullptr) {
|
||||
CFRelease(default_app);
|
||||
}
|
||||
|
||||
CFRelease(apps);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,9 +139,9 @@ void parseWhereFrom(QueryData &results, const std::string &path) {
|
||||
CFRelease(attributes);
|
||||
}
|
||||
|
||||
void extractQuarantineProperty(const std::string table_key_name,
|
||||
void extractQuarantineProperty(const std::string &table_key_name,
|
||||
CFTypeRef property,
|
||||
const std::string path,
|
||||
const std::string &path,
|
||||
QueryData &results) {
|
||||
std::string value;
|
||||
if (CFGetTypeID(property) == CFStringGetTypeID()) {
|
||||
|
@ -62,8 +62,8 @@ const std::map<CSSM_ACL_AUTHORIZATION_TAG, std::string> kACLAuthorizationTags =
|
||||
{CSSM_ACL_AUTHORIZATION_CHANGE_OWNER, "change_owner"},
|
||||
};
|
||||
|
||||
Status inline parseKeychainItemACLEntry(SecACLRef acl,
|
||||
std::vector<KeychainItemACL> &acls) {
|
||||
Status parseKeychainItemACLEntry(SecACLRef acl,
|
||||
std::vector<KeychainItemACL> &acls) {
|
||||
KeychainItemACL acl_data;
|
||||
OSStatus os_status;
|
||||
|
||||
@ -105,21 +105,22 @@ Status inline parseKeychainItemACLEntry(SecACLRef acl,
|
||||
app_index);
|
||||
CFDataRef data = nullptr;
|
||||
os_status = SecTrustedApplicationCopyData(app, &data);
|
||||
if (os_status != noErr) {
|
||||
return Status(os_status, "Coult not copy trusted application data");
|
||||
if (os_status != noErr || data == nullptr) {
|
||||
CFRelease(application_list);
|
||||
if (data != nullptr) {
|
||||
// To be very safe, assume data may have been allocated on error.
|
||||
CFRelease(data);
|
||||
}
|
||||
return Status(os_status, "Could not copy trusted application data");
|
||||
}
|
||||
|
||||
const UInt8 *bytes = CFDataGetBytePtr(data);
|
||||
if (bytes && bytes[0] == 0x2f) {
|
||||
if (bytes != nullptr && bytes[0] == '/') {
|
||||
acl_data.applications.push_back(std::string((const char *)bytes));
|
||||
}
|
||||
if (data != nullptr) {
|
||||
CFRelease(data);
|
||||
}
|
||||
}
|
||||
if (application_list != nullptr) {
|
||||
CFRelease(application_list);
|
||||
CFRelease(data);
|
||||
}
|
||||
CFRelease(application_list);
|
||||
}
|
||||
|
||||
acls.push_back(acl_data);
|
||||
@ -131,7 +132,10 @@ Status parseKeychainItemACL(SecAccessRef access,
|
||||
OSStatus os_status;
|
||||
CFArrayRef acl_list = nullptr;
|
||||
os_status = SecAccessCopyACLList(access, &acl_list);
|
||||
if (os_status != noErr) {
|
||||
if (os_status != noErr || acl_list == nullptr) {
|
||||
if (acl_list != nullptr) {
|
||||
CFRelease(acl_list);
|
||||
}
|
||||
return Status(os_status, "Could not copy ACL list");
|
||||
}
|
||||
|
||||
@ -144,14 +148,12 @@ Status parseKeychainItemACL(SecAccessRef access,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (acl_list != nullptr) {
|
||||
CFRelease(acl_list);
|
||||
}
|
||||
|
||||
CFRelease(acl_list);
|
||||
return Status(0, "OK");
|
||||
}
|
||||
|
||||
static std::string inline attributeBufferToString(const void *data, UInt32 length) {
|
||||
static std::string attributeBufferToString(const void *data, UInt32 length) {
|
||||
std::stringstream stream;
|
||||
uint8 *p = (uint8 *)data;
|
||||
while (length--) {
|
||||
@ -165,10 +167,10 @@ static std::string inline attributeBufferToString(const void *data, UInt32 lengt
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
Status inline genKeychainACLAppsForEntry(SecKeychainRef keychain,
|
||||
SecKeychainItemRef item,
|
||||
const std::string &path,
|
||||
QueryData &results) {
|
||||
Status genKeychainACLAppsForEntry(SecKeychainRef keychain,
|
||||
SecKeychainItemRef item,
|
||||
const std::string &path,
|
||||
QueryData &results) {
|
||||
KeychainItemMetadata item_metadata;
|
||||
item_metadata.keychain_path = path;
|
||||
|
||||
@ -180,14 +182,16 @@ Status inline genKeychainACLAppsForEntry(SecKeychainRef keychain,
|
||||
OSStatus os_status;
|
||||
Status s;
|
||||
os_status = SecKeychainItemCopyAccess(item, &access);
|
||||
if (os_status == errSecNoAccessForItem) {
|
||||
s = Status(1, "No ACLs for keychain item");
|
||||
if (os_status == errSecNoAccessForItem || access == nullptr) {
|
||||
if (access != nullptr) {
|
||||
CFRelease(access);
|
||||
}
|
||||
return Status(os_status, "No ACLs for keychain item");
|
||||
}
|
||||
|
||||
std::vector<KeychainItemACL> acl;
|
||||
s = parseKeychainItemACL(access, acl);
|
||||
if (access != nullptr) {
|
||||
CFRelease(access);
|
||||
}
|
||||
CFRelease(access);
|
||||
if (!s.ok()) {
|
||||
return s;
|
||||
}
|
||||
@ -214,7 +218,7 @@ Status inline genKeychainACLAppsForEntry(SecKeychainRef keychain,
|
||||
SecKeychainAttributeList *attr_list = nullptr;
|
||||
os_status = SecKeychainItemCopyAttributesAndData(
|
||||
item, info, &item_class, &attr_list, nullptr, nullptr);
|
||||
if (os_status != noErr) {
|
||||
if (os_status != noErr || attr_list == nullptr || info == nullptr) {
|
||||
if (attr_list != nullptr) {
|
||||
SecKeychainItemFreeAttributesAndData(attr_list, nullptr);
|
||||
}
|
||||
@ -225,21 +229,11 @@ Status inline genKeychainACLAppsForEntry(SecKeychainRef keychain,
|
||||
"Could not copy attributes and data from the keychain");
|
||||
}
|
||||
|
||||
Status copy_attr_status = Status(0, "OK");
|
||||
if (info == nullptr || attr_list == nullptr) {
|
||||
copy_attr_status = Status(1, "Could not get info or attr_list");
|
||||
}
|
||||
// Bail if the number of elements from the info/Attr list do not match.
|
||||
if (info->count != attr_list->count) {
|
||||
copy_attr_status = Status(1, "Info and attributes don't match");
|
||||
}
|
||||
if (!copy_attr_status.ok()) {
|
||||
if (attr_list != nullptr) {
|
||||
SecKeychainItemFreeAttributesAndData(attr_list, nullptr);
|
||||
}
|
||||
if (info != nullptr) {
|
||||
SecKeychainFreeAttributeInfo(info);
|
||||
}
|
||||
return copy_attr_status;
|
||||
SecKeychainItemFreeAttributesAndData(attr_list, nullptr);
|
||||
SecKeychainFreeAttributeInfo(info);
|
||||
return Status(1, "Info and attributes do not match");
|
||||
}
|
||||
|
||||
for (int i = 0; i < info->count; ++i) {
|
||||
@ -254,12 +248,10 @@ Status inline genKeychainACLAppsForEntry(SecKeychainRef keychain,
|
||||
attributeBufferToString(attribute->data, attribute->length);
|
||||
}
|
||||
}
|
||||
if (attr_list != nullptr) {
|
||||
SecKeychainItemFreeAttributesAndData(attr_list, nullptr);
|
||||
}
|
||||
if (info != nullptr) {
|
||||
SecKeychainFreeAttributeInfo(info);
|
||||
}
|
||||
|
||||
// Finally, release/free the info/Attr lists.
|
||||
SecKeychainItemFreeAttributesAndData(attr_list, nullptr);
|
||||
SecKeychainFreeAttributeInfo(info);
|
||||
|
||||
for (const auto &acl_data : acl) {
|
||||
for (const auto &app_path : acl_data.applications) {
|
||||
@ -281,29 +273,24 @@ Status genKeychainACLApps(const std::string &path, QueryData &results) {
|
||||
OSStatus os_status = 0;
|
||||
|
||||
os_status = SecKeychainOpen(path.c_str(), &keychain);
|
||||
if (os_status != noErr) {
|
||||
if (os_status != noErr || keychain == nullptr) {
|
||||
if (keychain != nullptr) {
|
||||
CFRelease(keychain);
|
||||
}
|
||||
return Status(os_status, "Could not open the keychain at " + path);
|
||||
}
|
||||
if (keychain == nullptr) {
|
||||
return Status(1, "keychain object was not populated properly");
|
||||
}
|
||||
|
||||
SecKeychainSearchRef search = nullptr;
|
||||
OSQUERY_USE_DEPRECATED(os_status = SecKeychainSearchCreateFromAttributes(
|
||||
keychain, CSSM_DL_DB_RECORD_ANY, NULL, &search););
|
||||
if (os_status != noErr) {
|
||||
if (keychain != nullptr) {
|
||||
CFRelease(keychain);
|
||||
if (os_status != noErr || search == nullptr) {
|
||||
if (search != nullptr) {
|
||||
CFRelease(search);
|
||||
}
|
||||
CFRelease(keychain);
|
||||
return Status(os_status,
|
||||
"Could not pull keychain items from the search API");
|
||||
}
|
||||
if (search == nullptr) {
|
||||
if (keychain != nullptr) {
|
||||
CFRelease(keychain);
|
||||
}
|
||||
return Status(1, "keychain search object was not populated properly");
|
||||
}
|
||||
|
||||
SecKeychainItemRef item = nullptr;
|
||||
while (true) {
|
||||
@ -320,19 +307,15 @@ Status genKeychainACLApps(const std::string &path, QueryData &results) {
|
||||
}
|
||||
}
|
||||
|
||||
if (keychain != nullptr) {
|
||||
CFRelease(keychain);
|
||||
}
|
||||
if (search != nullptr) {
|
||||
CFRelease(search);
|
||||
}
|
||||
|
||||
CFRelease(keychain);
|
||||
CFRelease(search);
|
||||
return Status(0, "OK");
|
||||
}
|
||||
|
||||
QueryData genKeychainACLApps(QueryContext &context) {
|
||||
QueryData results;
|
||||
|
||||
SecKeychainSetUserInteractionAllowed(false);
|
||||
for (const auto &path : getKeychainPaths()) {
|
||||
std::vector<std::string> ls_results;
|
||||
auto list_status = listFilesInDirectory(path, ls_results, false);
|
||||
@ -344,11 +327,12 @@ QueryData genKeychainACLApps(QueryContext &context) {
|
||||
TLOG << "Checking directory: " << keychain;
|
||||
auto gen_status = genKeychainACLApps(keychain, results);
|
||||
if (!gen_status.ok()) {
|
||||
TLOG << "Could not list keychain from " << keychain << ": "
|
||||
TLOG << "Could not list items from " << keychain << ": "
|
||||
<< gen_status.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
SecKeychainSetUserInteractionAllowed(true);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
12
specs/darwin/app_schemes.table
Normal file
12
specs/darwin/app_schemes.table
Normal file
@ -0,0 +1,12 @@
|
||||
table_name("app_schemes")
|
||||
description("OS X application schemes and handlers (e.g., http, file, mailto.")
|
||||
schema([
|
||||
Column("scheme", TEXT, "Name of the scheme/protocol"),
|
||||
Column("handler", TEXT, "Application label for the handler"),
|
||||
Column("enabled", INTEGER, "1 if this handler is the OS default, else 0"),
|
||||
Column("external", INTEGER,
|
||||
"1 if this handler does NOT exist on OS X by default, else 0"),
|
||||
Column("protected", INTEGER,
|
||||
"1 if this handler is protected (reserved) by OS X, else 0"),
|
||||
])
|
||||
implementation("apps@genAppSchemes")
|
@ -5,7 +5,7 @@ schema([
|
||||
Column("package_filename", TEXT, "Filename of original .pkg file"),
|
||||
Column("version", TEXT, "Installed package version"),
|
||||
Column("location", TEXT, "Optional relative install path on volume"),
|
||||
Column("install_time", INTEGER, "Timestamp of install time"),
|
||||
Column("install_time", DOUBLE, "Timestamp of install time"),
|
||||
Column("installer_name", TEXT, "Name of installer process"),
|
||||
Column("path", TEXT, "Path of receipt plist",
|
||||
index=True, additional=True),
|
||||
|
@ -53,6 +53,7 @@ DATETIME = DataType("TEXT")
|
||||
INTEGER = DataType("INTEGER", "int")
|
||||
BIGINT = DataType("BIGINT", "long long int")
|
||||
UNSIGNED_BIGINT = DataType("UNSIGNED_BIGINT", "long long unsigned int")
|
||||
DOUBLE = DataType("DOUBLE", "double")
|
||||
|
||||
# Define table-category MACROS from the table specs
|
||||
UNKNOWN = "UNKNOWN"
|
||||
|
Loading…
Reference in New Issue
Block a user