+++ /dev/null
-/* Copyright (c) 2012 Apple Inc. All Rights Reserved. */
-
-#include "mechanism.h"
-#include "authdb.h"
-#include "authutilities.h"
-#include "crc.h"
-#include "debugging.h"
-#include "server.h"
-#include "authitems.h"
-
-#define MECHANISM_ID "id"
-#define MECHANISM_PLUGIN "plugin"
-#define MECHANISM_PARAM "param"
-#define MECHANISM_PRIVILEGED "privileged"
-
-static const char SystemPlugins[] = "/System/Library/CoreServices/SecurityAgentPlugins";
-static const char LibraryPlugins[] = "/Library/Security/SecurityAgentPlugins";
-static const char BuiltinMechanismPrefix[] = "builtin";
-
-typedef struct _mechTypeItem
-{
- const char * name;
- uint64_t type;
-} mechTypeItem;
-
-static mechTypeItem mechTypeMap[] =
-{
- { "entitled", kMechanismTypeEntitled }
-};
-
-struct _mechanism_s {
- __AUTH_BASE_STRUCT_HEADER__;
-
- auth_items_t data;
-
- bool valid;
- char * string;
-
- uint64_t type;
-};
-
-static void
-_mechanism_finalize(CFTypeRef value)
-{
- mechanism_t mech = (mechanism_t)value;
-
- CFReleaseSafe(mech->data);
- free_safe(mech->string);
-}
-
-static Boolean
-_mechanism_equal(CFTypeRef value1, CFTypeRef value2)
-{
- mechanism_t mech1 = (mechanism_t)value1;
- mechanism_t mech2 = (mechanism_t)value2;
-
- if (mech1 == mech2) {
- return true;
- }
-
- if (!_compare_string(mechanism_get_plugin(mech1), mechanism_get_plugin(mech2))) {
- return false;
- }
-
- if (!_compare_string(mechanism_get_param(mech1), mechanism_get_param(mech2))) {
- return false;
- }
-
- return mechanism_is_privileged(mech1) == mechanism_is_privileged(mech2);
-}
-
-static CFStringRef
-_mechanism_copy_description(CFTypeRef value)
-{
- mechanism_t mech = (mechanism_t)value;
- return CFCopyDescription(mech->data);
-}
-
-static CFHashCode
-_mechanism_hash(CFTypeRef value)
-{
- uint64_t crc = crc64_init();
- mechanism_t mech = (mechanism_t)value;
-
- const char * str = mechanism_get_plugin(mech);
- crc = crc64_update(crc, str, strlen(str));
- str = mechanism_get_plugin(mech);
- crc = crc64_update(crc, str, strlen(str));
- bool priv = mechanism_is_privileged(mech);
- crc = crc64_update(crc, &priv, sizeof(priv));
- crc = crc64_final(crc);
-
- return crc;
-}
-
-AUTH_TYPE_INSTANCE(mechanism,
- .init = NULL,
- .copy = NULL,
- .finalize = _mechanism_finalize,
- .equal = _mechanism_equal,
- .hash = _mechanism_hash,
- .copyFormattingDesc = NULL,
- .copyDebugDesc = _mechanism_copy_description
- );
-
-static CFTypeID mechanism_get_type_id() {
- static CFTypeID type_id = _kCFRuntimeNotATypeID;
- static dispatch_once_t onceToken;
-
- dispatch_once(&onceToken, ^{
- type_id = _CFRuntimeRegisterClass(&_auth_type_mechanism);
- });
-
- return type_id;
-}
-
-static mechanism_t
-_mechanism_create()
-{
- mechanism_t mech = (mechanism_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, mechanism_get_type_id(), AUTH_CLASS_SIZE(mechanism), NULL);
- require(mech != NULL, done);
-
- mech->data = auth_items_create();
-
-done:
- return mech;
-}
-
-static void _mechanism_set_type(mechanism_t mech)
-{
- const char * plugin = mechanism_get_plugin(mech);
- const char * param = mechanism_get_param(mech);
- if (strncasecmp(plugin, BuiltinMechanismPrefix, sizeof(BuiltinMechanismPrefix)) == 0) {
- size_t n = sizeof(mechTypeMap)/sizeof(mechTypeItem);
- for (size_t i = 0; i < n; i++) {
- if (strcasecmp(mechTypeMap[i].name, param) == 0) {
- mech->type = mechTypeMap[i].type;
- break;
- }
- }
- }
-}
-
-mechanism_t
-mechanism_create_with_sql(auth_items_t sql)
-{
- mechanism_t mech = NULL;
- require(sql != NULL, done);
- require(auth_items_get_int64(sql, MECHANISM_ID) != 0, done);
-
- mech = _mechanism_create();
- require(mech != NULL, done);
-
- auth_items_copy(mech->data, sql);
-
- _mechanism_set_type(mech);
-
-done:
- return mech;
-}
-
-mechanism_t
-mechanism_create_with_string(const char * str, authdb_connection_t dbconn)
-{
- mechanism_t mech = NULL;
- require(str != NULL, done);
- require(strchr(str,':') != NULL, done);
-
- mech = _mechanism_create();
- require(mech != NULL, done);
-
- const char delimiters[] = ":,";
- size_t buf_len = strlen(str)+1;
- char * buf = (char*)calloc(1u, buf_len);
- strlcpy(buf, str, buf_len);
-
- char * tok = strtok(buf, delimiters);
- if (tok) {
- auth_items_set_string(mech->data, MECHANISM_PLUGIN, tok);
- }
- tok = strtok(NULL, delimiters);
- if (tok) {
- auth_items_set_string(mech->data, MECHANISM_PARAM, tok);
- }
- tok = strtok(NULL, delimiters);
- if (tok) {
- auth_items_set_int64(mech->data, MECHANISM_PRIVILEGED, strcasecmp("privileged", tok) == 0);
- }
- free(buf);
-
- if (dbconn) {
- mechanism_sql_fetch(mech, dbconn);
- }
-
- _mechanism_set_type(mech);
-
-done:
- return mech;
-}
-
-static
-bool _pluginExists(const char * plugin, const char * base)
-{
- bool result = false;
-
- require(plugin != NULL, done);
- require(base != NULL, done);
-
- char filePath[PATH_MAX];
- char realPath[PATH_MAX+1];
- snprintf(filePath, sizeof(filePath), "%s/%s.bundle", base, plugin);
-
- require(realpath(filePath, realPath) != NULL, done);
- require(strncmp(realPath, base, strlen(base)) == 0, done);
-
- if (access(filePath, F_OK) == 0) {
- result = true;
- }
-
-done:
- return result;
-}
-
-bool
-mechanism_exists(mechanism_t mech)
-{
- if (mech->valid) {
- return true;
- }
-
- const char * plugin = mechanism_get_plugin(mech);
- if (plugin == NULL) {
- return false;
- }
-
- if (strncasecmp(plugin, BuiltinMechanismPrefix, sizeof(BuiltinMechanismPrefix)) == 0) {
- mech->valid = true;
- return true;
- }
-
- if (_pluginExists(plugin, SystemPlugins)) {
- mech->valid = true;
- return true;
- }
-
- if (_pluginExists(plugin,LibraryPlugins)) {
- mech->valid = true;
- return true;
- }
-
- return false;
-}
-
-bool
-mechanism_sql_fetch(mechanism_t mech, authdb_connection_t dbconn)
-{
- __block bool result = false;
-
- authdb_step(dbconn, "SELECT id FROM mechanisms WHERE plugin = ? AND param = ? AND privileged = ? LIMIT 1", ^(sqlite3_stmt * stmt) {
- sqlite3_bind_text(stmt, 1, mechanism_get_plugin(mech), -1, NULL);
- sqlite3_bind_text(stmt, 2, mechanism_get_param(mech), -1, NULL);
- sqlite3_bind_int(stmt, 3, mechanism_is_privileged(mech));
- }, ^bool(auth_items_t data) {
- result = true;
- auth_items_copy(mech->data, data);
- return true;
- });
-
- return result;
-}
-
-bool
-mechanism_sql_commit(mechanism_t mech, authdb_connection_t dbconn)
-{
- bool result = false;
-
- result = authdb_step(dbconn, "INSERT INTO mechanisms VALUES (NULL,?,?,?)", ^(sqlite3_stmt *stmt) {
- sqlite3_bind_text(stmt, 1, mechanism_get_plugin(mech), -1, NULL);
- sqlite3_bind_text(stmt, 2, mechanism_get_param(mech), -1, NULL);
- sqlite3_bind_int(stmt, 3, mechanism_is_privileged(mech));
- }, NULL);
-
- return result;
-}
-
-const char *
-mechanism_get_string(mechanism_t mech)
-{
- if (!mech->string) {
- asprintf(&mech->string, "%s:%s%s", mechanism_get_plugin(mech), mechanism_get_param(mech), mechanism_is_privileged(mech) ? ",privileged" : "");
- }
-
- return mech->string;
-}
-
-int64_t
-mechanism_get_id(mechanism_t mech)
-{
- return auth_items_get_int64(mech->data, MECHANISM_ID);
-}
-
-const char *
-mechanism_get_plugin(mechanism_t mech)
-{
- return auth_items_get_string(mech->data, MECHANISM_PLUGIN);
-}
-
-const char *
-mechanism_get_param(mechanism_t mech)
-{
- return auth_items_get_string(mech->data, MECHANISM_PARAM);
-}
-
-bool
-mechanism_is_privileged(mechanism_t mech)
-{
- return auth_items_get_int64(mech->data, MECHANISM_PRIVILEGED);
-}
-
-uint64_t
-mechanism_get_type(mechanism_t mech)
-{
- return mech->type;
-}