void storage_invocation_initialize (GDBusConnection *connection, StorageClientFunc client_appeared, StorageClientFunc client_disappeared, gpointer user_data) { GObjectClass *object_class; GError *error = NULL; inv.client_appeared = client_appeared; inv.client_disappeared = client_disappeared; inv.client_user_data = user_data; inv.dbus_interface_skeleton_class = g_type_class_ref (G_TYPE_DBUS_INTERFACE_SKELETON); object_class = G_OBJECT_CLASS (inv.dbus_interface_skeleton_class); inv.overridden_constructor = object_class->constructor; object_class->constructor = hook_dbus_interface_skeleton_constructor; inv.clients = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, invocation_client_unref); g_dbus_connection_add_filter (connection, on_connection_filter, NULL, NULL); inv.authority = polkit_authority_get_sync (NULL, &error); if (error != NULL) { g_warning ("Couldn't connect to polkit: %s", error->message); g_error_free (error); } }
static void storage_daemon_constructed (GObject *object) { StorageDaemon *self = STORAGE_DAEMON (object); GError *error; G_OBJECT_CLASS (storage_daemon_parent_class)->constructed (object); storage_invocation_initialize (self->connection, on_client_appeared, on_client_disappeared, self); error = NULL; self->authority = polkit_authority_get_sync (NULL, &error); if (self->authority == NULL) { g_warning ("Error initializing polkit authority: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); } /* Yes, we use the same paths as the main udisks daemon on purpose */ self->object_manager = g_dbus_object_manager_server_new ("/org/freedesktop/UDisks2"); /* Export the ObjectManager */ g_dbus_object_manager_server_set_connection (self->object_manager, self->connection); storage_manager_new_async (on_manager_ready, self); }
static gboolean register_mechanism (GConfDefaults *mechanism) { GError *error = NULL; mechanism->priv->auth = polkit_authority_get_sync (NULL, NULL); error = NULL; mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); if (mechanism->priv->system_bus_connection == NULL) { if (error != NULL) { g_critical ("error getting system bus: %s", error->message); g_error_free (error); } goto error; } dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/", G_OBJECT (mechanism)); mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); start_killtimer (); return TRUE; error: return FALSE; }
/* * This handler is run in a separate thread, so all operations can be * synchronous. */ static gboolean on_authorize_method_check (GDBusInterfaceSkeleton *interface, GDBusMethodInvocation *invocation, EmerDaemon *daemon) { const gchar *method_name = g_dbus_method_invocation_get_method_name (invocation); const AuthorizedMethod *authorized_method = lookup_authorized_method (method_name); if (authorized_method == NULL) return TRUE; GError *error = NULL; PolkitAuthority *authority = polkit_authority_get_sync (NULL /*GCancellable*/, &error); if (authority == NULL) { g_critical ("Could not get PolicyKit authority: %s.", error->message); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } const gchar *sender_name = g_dbus_method_invocation_get_sender (invocation); PolkitSubject *subject = polkit_system_bus_name_new (sender_name); PolkitAuthorizationResult *result = polkit_authority_check_authorization_sync (authority, subject, authorized_method->method_full_name, NULL /*PolkitDetails*/, POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE, NULL /*GCancellable*/, &error); g_object_unref (authority); g_object_unref (subject); if (result == NULL) { g_critical ("Could not get PolicyKit authorization result: %s.", error->message); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } gboolean authorized = polkit_authorization_result_get_is_authorized (result); if (!authorized) g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_AUTH_FAILED, authorized_method->error_message); g_object_unref (result); return authorized; }
static PolkitResult do_check(PolkitSubject *subject, const char *action_id) { PolkitAuthority *authority; PolkitAuthorizationResult *auth_result; PolkitResult result = PolkitNo; GError *error = NULL; GCancellable * cancellable; cancellable = g_cancellable_new(); /* we ignore the error for now .. */ authority = polkit_authority_get_sync(cancellable, NULL); guint cancel_timeout = g_timeout_add(POLKIT_TIMEOUT * 1000, (GSourceFunc) do_cancel, cancellable); auth_result = polkit_authority_check_authorization_sync(authority, subject, action_id, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, cancellable, &error); g_object_unref(cancellable); g_object_unref(authority); g_source_remove(cancel_timeout); g_object_unref(subject); if (error) { g_error_free(error); return PolkitUnknown; } if (!auth_result) return PolkitUnknown; if (polkit_authorization_result_get_is_challenge(auth_result)) { /* Can't happen (happens only with * POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE flag) */ result = PolkitChallenge; goto out; } if (polkit_authorization_result_get_is_authorized(auth_result)) { result = PolkitYes; goto out; } out: g_object_unref(auth_result); return result; }
static void fprint_device_init(FprintDevice *device) { FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(device); priv->id = ++last_id; /* Setup PolicyKit */ priv->auth = polkit_authority_get_sync (NULL, NULL); priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); }
static PolkitAuthority * pk_authority_get (GError **error) { static PolkitAuthority *authority = NULL; if (authority == NULL) authority = polkit_authority_get_sync (NULL, error); /* Yes, ref every time; we want to keep the object alive */ g_warn_if_fail (authority); return authority ? g_object_ref (authority) : NULL; }
int main(void) { pid_t parent_pid; GInputStream *stdin_unix_stream; /* Nuke the environment to get a well-known and sanitized * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS * environment variable and similar. */ if (clearenv () != 0) { FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno)); return 1; } #if !GLIB_CHECK_VERSION(2,36,0) g_type_init(); #endif loop = g_main_loop_new(NULL, FALSE); authority = polkit_authority_get_sync(NULL, NULL); parent_pid = getppid (); if (parent_pid == 1) { FATAL_ERROR("Parent process was reaped by init(1)\n"); return 1; } /* Do what pkexec does */ subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ()); stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0); stdin_stream = g_data_input_stream_new(stdin_unix_stream); g_data_input_stream_set_newline_type(stdin_stream, G_DATA_STREAM_NEWLINE_TYPE_LF); g_clear_object(&stdin_unix_stream); g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL, stdin_read_complete, NULL); g_main_loop_run(loop); if (polkit_cancellable) g_clear_object(&polkit_cancellable); g_object_unref(stdin_stream); g_object_unref(authority); g_object_unref(subject); g_main_loop_unref(loop); return exit_status; }
static void mm_auth_provider_polkit_init (MMAuthProviderPolkit *self) { GError *error = NULL; self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), MM_TYPE_AUTH_PROVIDER_POLKIT, MMAuthProviderPolkitPrivate); self->priv->authority = polkit_authority_get_sync (NULL, &error); if (!self->priv->authority) { /* NOTE: we failed to create the polkit authority, but we still create * our AuthProvider. Every request will fail, though. */ mm_warn ("failed to create PolicyKit authority: '%s'", error ? error->message : "unknown"); g_clear_error (&error); } }
/** * on_bus_acquired: */ static void on_bus_acquired (GDBusConnection *connection, const gchar *name, LiHelperDaemon *helper) { LiProxyObjectSkeleton *object; LiProxyManager *mgr_bus; GError *error = NULL; g_print ("Acquired a message bus connection\n"); helper->authority = polkit_authority_get_sync (NULL, &error); g_assert_no_error (error); /* TODO: Meh... Needs smart error handling. */ helper->obj_manager = g_dbus_object_manager_server_new ("/org/freedesktop/Limba"); /* create the Manager object */ object = li_proxy_object_skeleton_new ("/org/freedesktop/Limba/Manager"); mgr_bus = li_proxy_manager_skeleton_new (); li_proxy_object_skeleton_set_manager (object, mgr_bus); g_object_unref (mgr_bus); g_signal_connect (mgr_bus, "handle-remove-software", G_CALLBACK (bus_manager_remove_software_cb), helper); g_signal_connect (mgr_bus, "handle-install-local", G_CALLBACK (bus_installer_install_local_cb), helper); g_signal_connect (mgr_bus, "handle-install", G_CALLBACK (bus_installer_install_cb), helper); /* export the object */ g_dbus_object_manager_server_export (helper->obj_manager, G_DBUS_OBJECT_SKELETON (object)); g_object_unref (object); g_dbus_object_manager_server_set_connection (helper->obj_manager, connection); }
static gboolean register_accounts_daemon (Daemon *daemon) { GError *error = NULL; daemon->priv->authority = polkit_authority_get_sync (NULL, &error); if (daemon->priv->authority == NULL) { if (error != NULL) { g_critical ("error getting polkit authority: %s", error->message); g_error_free (error); } goto error; } daemon->priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (daemon->priv->bus_connection == NULL) { if (error != NULL) { g_critical ("error getting system bus: %s", error->message); g_error_free (error); } goto error; } if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon), daemon->priv->bus_connection, "/org/freedesktop/Accounts", &error)) { if (error != NULL) { g_critical ("error exporting interface: %s", error->message); g_error_free (error); } goto error; } return TRUE; error: return FALSE; }
static gboolean send_dbus_message (const char *cookie, uid_t uid) { PolkitAuthority *authority = NULL; PolkitIdentity *identity = NULL; GError *error = NULL; gboolean ret; ret = FALSE; g_type_init (); authority = polkit_authority_get_sync (NULL, &error); if (!authority) { warnx ("couldn't contact polkit authority: %s", error->message); goto out; } identity = polkit_unix_user_new (uid); if (!polkit_authority_authentication_agent_response_sync (authority, cookie, identity, NULL, &error)) { warnx ("couldn't respond to polkit daemon: %s", error->message); goto out; } ret = TRUE; out: g_clear_error (&error); if (authority) g_object_unref (authority); if (identity) g_object_unref (identity); return ret; }
gpointer cockpit_polkit_agent_register (CockpitTransport *transport, GCancellable *cancellable) { PolkitAgentListener *listener = NULL; PolkitAuthority *authority = NULL; PolkitSubject *subject = NULL; GVariant *options; GLogLevelFlags fatal; GError *error = NULL; gpointer handle = NULL; guint handler = 0; gchar *string; authority = polkit_authority_get_sync (cancellable, &error); if (authority == NULL) { g_message ("couldn't get polkit authority: %s", error->message); goto out; } subject = polkit_unix_session_new_for_process_sync (getpid (), cancellable, &error); if (subject == NULL) { /* * This can happen if there's a race between the polkit request and closing of * Cockpit. So it's not unheard of. We can complain, but not too loudly. */ g_message ("couldn't create polkit session subject: %s", error->message); goto out; } listener = g_object_new (COCKPIT_TYPE_POLKIT_AGENT, "transport", transport, NULL); options = NULL; /* * HACK: Work around polkitagent warning: * * https://bugs.freedesktop.org/show_bug.cgi?id=78193 */ fatal = g_log_set_always_fatal (0); handler = g_log_set_handler (NULL, G_LOG_LEVEL_WARNING, cockpit_null_log_handler, NULL); handle = polkit_agent_listener_register_with_options (listener, POLKIT_AGENT_REGISTER_FLAGS_NONE, subject, NULL, options, cancellable, &error); g_log_set_always_fatal (fatal); g_log_remove_handler (NULL, handler); if (error != NULL) { if ((g_error_matches (error, POLKIT_ERROR, POLKIT_ERROR_FAILED) && error->message && strstr (error->message, "already exists")) || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { g_debug ("couldn't register polkit agent: %s", error->message); } else { g_dbus_error_strip_remote_error (error); g_message ("couldn't register polkit authentication agent: %s", error->message); } goto out; } string = polkit_subject_to_string (subject); g_debug ("registered polkit authentication agent for subject: %s", string); g_free (string); out: if (subject) g_object_unref (subject); if (authority) g_object_unref (authority); if (listener) g_object_unref (listener); g_clear_error (&error); return handle; }
int main (int argc, char *argv[]) { pid_t parent_pid; const gchar *action_id; GMainLoop *loop; PolkitSubject *subject; PolkitAuthority *authority; GCancellable *cancellable; g_type_init (); if (argc != 2) { g_printerr ("usage: %s <action_id>\n", argv[0]); return 1; } action_id = argv[1]; loop = g_main_loop_new (NULL, FALSE); authority = polkit_authority_get_sync (NULL, NULL); /* Typically mechanisms will use a PolkitSystemBusName since most * clients communicate with the mechanism via D-Bus. However for * this simple example we use the process id of the calling process. * * Note that if the parent was reaped we have to be careful not to * check if init(1) is authorized (it always is). */ parent_pid = getppid (); if (parent_pid == 1) { g_printerr ("Parent process was reaped by init(1)\n"); return 1; } subject = polkit_unix_process_new (parent_pid); cancellable = g_cancellable_new (); g_print ("Will cancel authorization check in 10 seconds\n"); /* Set up a 10 second timer to cancel the check */ g_timeout_add (10 * 1000, (GSourceFunc) do_cancel, cancellable); polkit_authority_check_authorization (authority, subject, action_id, NULL, /* PolkitDetails */ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, cancellable, (GAsyncReadyCallback) check_authorization_cb, loop); g_main_loop_run (loop); g_object_unref (authority); g_object_unref (subject); g_object_unref (cancellable); g_main_loop_unref (loop); return 0; }
int main (int argc, char **argv) { gint ret; GMainLoop *loop; PolkitAgentListener *listener; GError *error; g_type_init (); gtk_init (&argc, &argv); loop = NULL; authority = NULL; listener = NULL; session = NULL; ret = 1; bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR); #if HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif textdomain (GETTEXT_PACKAGE); loop = g_main_loop_new (NULL, FALSE); error = NULL; authority = polkit_authority_get_sync (NULL /* GCancellable* */, &error); if (authority == NULL) { g_warning ("Error getting authority: %s", error->message); g_error_free (error); goto out; } g_signal_connect (authority, "changed", G_CALLBACK (on_authority_changed), NULL); listener = polkit_mate_listener_new (); error = NULL; session = polkit_unix_session_new_for_process_sync (getpid (), NULL, &error); if (error != NULL) { g_warning ("Unable to determine the session we are in: %s", error->message); g_error_free (error); goto out; } error = NULL; if (!polkit_agent_register_listener (listener, session, "/org/mate/PolicyKit1/AuthenticationAgent", &error)) { g_printerr ("Cannot register authentication agent: %s\n", error->message); g_error_free (error); goto out; } update_temporary_authorization_icon (authority); g_main_loop_run (loop); ret = 0; out: if (authority != NULL) g_object_unref (authority); if (session != NULL) g_object_unref (session); if (listener != NULL) g_object_unref (listener); if (loop != NULL) g_main_loop_unref (loop); return ret; }
/** * cd_main_sender_authenticated: **/ gboolean cd_main_sender_authenticated (GDBusConnection *connection, const gchar *sender, const gchar *action_id, GError **error) { gboolean ret = FALSE; GError *error_local = NULL; guint uid; #ifdef USE_POLKIT PolkitAuthorizationResult *result = NULL; PolkitSubject *subject = NULL; PolkitAuthority *authority = NULL; #endif /* uid 0 is allowed to do all actions */ uid = cd_main_get_sender_uid (connection, sender, &error_local); if (uid == G_MAXUINT) { g_set_error (error, CD_CLIENT_ERROR, CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE, "could not get uid to authenticate %s: %s", action_id, error_local->message); g_error_free (error_local); goto out; } /* the root user can always do all actions */ if (uid == 0) { g_debug ("CdCommon: not checking %s for %s as uid 0", action_id, sender); ret = TRUE; goto out; } /* a client running as the daemon user may also do all actions */ if (uid == getuid ()) { g_debug ("CdCommon: not checking %s for %s as running as daemon user", action_id, sender); ret = TRUE; goto out; } #ifdef USE_POLKIT /* get authority */ authority = polkit_authority_get_sync (NULL, &error_local); if (authority == NULL) { g_set_error (error, CD_CLIENT_ERROR, CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE, "failed to get polkit authorit: %s", error_local->message); g_error_free (error_local); goto out; } /* do authorization async */ subject = polkit_system_bus_name_new (sender); result = polkit_authority_check_authorization_sync (authority, subject, action_id, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, NULL, &error_local); if (result == NULL) { g_set_error (error, CD_CLIENT_ERROR, CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE, "could not check %s for auth: %s", action_id, error_local->message); g_error_free (error_local); goto out; } /* did not auth */ if (!polkit_authorization_result_get_is_authorized (result)) { g_set_error (error, CD_CLIENT_ERROR, CD_CLIENT_ERROR_FAILED_TO_AUTHENTICATE, "failed to obtain %s auth", action_id); goto out; } #else g_warning ("CdCommon: not checking %s for %s as no PolicyKit support", action_id, sender); #endif /* success */ ret = TRUE; out: #ifdef USE_POLKIT if (authority != NULL) g_object_unref (authority); if (result != NULL) g_object_unref (result); if (subject != NULL) g_object_unref (subject); #endif return ret; }
int main (int argc, char **argv) { gchar exe_path[PATH_MAX+1]; ssize_t exe_path_len; gboolean replace; gboolean verbose; gboolean show_version; GBusNameOwnerFlags flags; GOptionContext *context; g_autoptr(GError) error = NULL; const GOptionEntry options[] = { { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "Replace old daemon.", NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Enable debug output.", NULL }, { "session", 0, 0, G_OPTION_ARG_NONE, &on_session_bus, "Run in session, not system scope (for tests).", NULL }, { "no-idle-exit", 0, 0, G_OPTION_ARG_NONE, &no_idle_exit, "Don't exit when idle.", NULL }, { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Show program version.", NULL}, { NULL } }; setlocale (LC_ALL, ""); g_setenv ("GIO_USE_VFS", "local", TRUE); g_set_prgname (argv[0]); g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL); context = g_option_context_new (""); g_option_context_set_summary (context, "Flatpak system helper"); g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); replace = FALSE; verbose = FALSE; show_version = FALSE; if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s", g_get_application_name(), error->message); g_printerr ("\n"); g_printerr ("Try \"%s --help\" for more information.", g_get_prgname ()); g_printerr ("\n"); g_option_context_free (context); return 1; } if (show_version) { g_print (PACKAGE_STRING "\n"); return 0; } if (verbose) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL); authority = polkit_authority_get_sync (NULL, &error); if (authority == NULL) { g_printerr ("Can't get polkit authority: %s\n", error->message); return 1; } exe_path_len = readlink ("/proc/self/exe", exe_path, sizeof (exe_path) - 1); if (exe_path_len > 0) { exe_path[exe_path_len] = 0; GFileMonitor *monitor; g_autoptr(GFile) exe = NULL; g_autoptr(GError) local_error = NULL; exe = g_file_new_for_path (exe_path); monitor = g_file_monitor_file (exe, G_FILE_MONITOR_NONE, NULL, &local_error); if (monitor == NULL) g_warning ("Failed to set watch on %s: %s", exe_path, error->message); else g_signal_connect (monitor, "changed", G_CALLBACK (binary_file_changed_cb), NULL); } flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; if (replace) flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; name_owner_id = g_bus_own_name (on_session_bus ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM, "org.freedesktop.Flatpak.SystemHelper", flags, on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); /* Ensure we don't idle exit */ schedule_idle_callback (); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); return 0; }