diff options
Diffstat (limited to 'libck-connector')
-rw-r--r-- | libck-connector/Makefile.am | 22 | ||||
-rw-r--r-- | libck-connector/ck-connector.c | 381 | ||||
-rw-r--r-- | libck-connector/ck-connector.h | 122 | ||||
-rw-r--r-- | libck-connector/ck-connector.pc.in | 9 |
4 files changed, 534 insertions, 0 deletions
diff --git a/libck-connector/Makefile.am b/libck-connector/Makefile.am new file mode 100644 index 0000000..80a4e2b --- /dev/null +++ b/libck-connector/Makefile.am @@ -0,0 +1,22 @@ + +INCLUDES = $(LIBDBUS_CFLAGS) + +slib_LTLIBRARIES=libck-connector.la +slibdir=/lib +libck_connectorincludedir=$(includedir)/ConsoleKit/ck-connector +libck_connectorinclude_HEADERS = ck-connector.h +libck_connector_la_SOURCES = ck-connector.c ck-connector.h + +# soname management for libck-connector +LIBCKCON_LT_CURRENT=0 +LIBCKCON_LT_REVISION=0 +LIBCKCON_LT_AGE=0 + +libck_connector_la_LIBADD = $(LIBDBUS_LIBS) +libck_connector_la_LDFLAGS = -version-info $(LIBCKCON_LT_CURRENT):$(LIBCKCON_LT_REVISION):$(LIBCKCON_LT_AGE) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ck-connector.pc + +clean-local : + rm -f *~ diff --git a/libck-connector/ck-connector.c b/libck-connector/ck-connector.c new file mode 100644 index 0000000..b22f76c --- /dev/null +++ b/libck-connector/ck-connector.c @@ -0,0 +1,381 @@ +/* + * ck-connector.c : Code for login managers to register with ConsoleKit. + * + * Copyright (c) 2007 David Zeuthen <davidz@redhat.com> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <dbus/dbus.h> + +#include "ck-connector.h" + +static dbus_bool_t +add_param_int32 (DBusMessageIter *iter_array, const char *key, dbus_int32_t value) +{ + DBusMessageIter iter_struct; + DBusMessageIter iter_variant; + + if (!dbus_message_iter_open_container (iter_array, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct)) + goto oom; + if (!dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key)) + goto oom; + if (!dbus_message_iter_open_container (&iter_struct, + DBUS_TYPE_VARIANT, + DBUS_TYPE_INT32_AS_STRING, + &iter_variant)) + goto oom; + if (!dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_INT32, &value)) + goto oom; + if (!dbus_message_iter_close_container (&iter_struct, &iter_variant)) + goto oom; + if (!dbus_message_iter_close_container (iter_array, &iter_struct)) + goto oom; + + return TRUE; +oom: + return FALSE; +} + +static dbus_bool_t +add_param_string (DBusMessageIter *iter_array, const char *key, const char *value) +{ + DBusMessageIter iter_struct; + DBusMessageIter iter_variant; + + if (!dbus_message_iter_open_container (iter_array, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct)) + goto oom; + if (!dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key)) + goto oom; + if (!dbus_message_iter_open_container (&iter_struct, + DBUS_TYPE_VARIANT, + DBUS_TYPE_STRING_AS_STRING, + &iter_variant)) + goto oom; + if (!dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_STRING, &value)) + goto oom; + if (!dbus_message_iter_close_container (&iter_struct, &iter_variant)) + goto oom; + if (!dbus_message_iter_close_container (iter_array, &iter_struct)) + goto oom; + + return TRUE; +oom: + return FALSE; +} + +static dbus_bool_t +add_param_bool (DBusMessageIter *iter_array, const char *key, dbus_bool_t value) +{ + DBusMessageIter iter_struct; + DBusMessageIter iter_variant; + + if (!dbus_message_iter_open_container (iter_array, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct)) + goto oom; + if (!dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key)) + goto oom; + if (!dbus_message_iter_open_container (&iter_struct, + DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, + &iter_variant)) + goto oom; + if (!dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_BOOLEAN, &value)) + goto oom; + if (!dbus_message_iter_close_container (&iter_struct, &iter_variant)) + goto oom; + if (!dbus_message_iter_close_container (iter_array, &iter_struct)) + goto oom; + + return TRUE; +oom: + return FALSE; +} + + +struct CKConnector_s +{ + char *cookie; + dbus_bool_t session_created; + DBusConnection *con; +}; + +CKConnector* +ckc_new (void) +{ + CKConnector *ckc; + + ckc = calloc (1, sizeof (CKConnector)); + if (ckc == NULL) + goto oom; + ckc->con = NULL; + ckc->cookie = NULL; + ckc->session_created = FALSE; +oom: + return ckc; +}; + +dbus_bool_t +ckc_create_local_session2 (CKConnector *ckc) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + dbus_bool_t ret; + char *cookie; + + reply = NULL; + message = NULL; + ret = FALSE; + + dbus_error_init (&error); + ckc->con = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); + if (ckc->con == NULL) { + goto out; + } + dbus_connection_set_exit_on_disconnect (ckc->con, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "OpenSession"); + if (message == NULL) + goto out; + + reply = dbus_connection_send_with_reply_and_block (ckc->con, message, -1, &error); + if (reply == NULL) { + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + } + + if (!dbus_message_get_args (reply, + &error, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + } + + ckc->cookie = strdup (cookie); + if (ckc->cookie == NULL) + goto out; + + ckc->session_created = TRUE; + ret = TRUE; + +out: + if (reply != NULL) + dbus_message_unref (reply); + + if (message != NULL) + dbus_message_unref (message); + + return ret; +} + +dbus_bool_t +ckc_create_local_session (CKConnector *ckc, uid_t user, const char *tty, const char *x11_display) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_array; + dbus_bool_t ret; + char *cookie; + + reply = NULL; + message = NULL; + ret = FALSE; + + dbus_error_init (&error); + ckc->con = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); + if (ckc->con == NULL) { + goto out; + } + dbus_connection_set_exit_on_disconnect (ckc->con, FALSE); + + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "OpenSessionWithParameters"); + if (message == NULL) + goto out; + + dbus_message_iter_init_append (message, &iter); + if (!dbus_message_iter_open_container (&iter, + DBUS_TYPE_ARRAY, + "(sv)", + &iter_array)) + goto out; + + if (!add_param_string (&iter_array, "host-name", "localhost")) + goto out; + if (!add_param_string (&iter_array, "display-device", tty)) + goto out; + if (x11_display != NULL) + if (!add_param_string (&iter_array, "x11-display", x11_display)) + goto out; + if (!add_param_int32 (&iter_array, "user", user)) + goto out; + if (!add_param_bool (&iter_array, "is-local", TRUE)) + goto out; + + if (!dbus_message_iter_close_container (&iter, &iter_array)) + goto out; + + reply = dbus_connection_send_with_reply_and_block (ckc->con, message, -1, &error); + if (reply == NULL) { + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + } + + if (!dbus_message_get_args (reply, + &error, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + } + + ckc->cookie = strdup (cookie); + if (ckc->cookie == NULL) + goto out; + + ckc->session_created = TRUE; + ret = TRUE; + +out: + if (reply != NULL) + dbus_message_unref (reply); + + if (message != NULL) + dbus_message_unref (message); + + return ret; +} + +char * +ckc_get_cookie (CKConnector *ckc) +{ + if (!ckc->session_created) + return NULL; + else + return ckc->cookie; +} + +dbus_bool_t +ckc_close_session (CKConnector *ckc) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + dbus_bool_t ret; + dbus_bool_t session_closed; + + reply = NULL; + message = NULL; + ret = FALSE; + if (!ckc->session_created || ckc->cookie == NULL) + goto out; + + dbus_error_init (&error); + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "CloseSession"); + if (message == NULL) + goto out; + + if (!dbus_message_append_args (message, + DBUS_TYPE_STRING, &(ckc->cookie), + DBUS_TYPE_INVALID)) + goto out; + + reply = dbus_connection_send_with_reply_and_block (ckc->con, message, -1, &error); + if (reply == NULL) { + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + } + + if (!dbus_message_get_args (reply, + &error, + DBUS_TYPE_BOOLEAN, &session_closed, + DBUS_TYPE_INVALID)) { + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + } + + if (!session_closed) + goto out; + + ckc->session_created = FALSE; + ret = TRUE; + +out: + if (reply != NULL) + dbus_message_unref (reply); + + if (message != NULL) + dbus_message_unref (message); + + return ret; + +} + +void +ckc_free (CKConnector *ckc) +{ + if (ckc->con != NULL) { + /* it's a private connection so it's all good */ + dbus_connection_close (ckc->con); + } + if (ckc->cookie != NULL) { + free (ckc->cookie); + } + free (ckc); +} diff --git a/libck-connector/ck-connector.h b/libck-connector/ck-connector.h new file mode 100644 index 0000000..e92712d --- /dev/null +++ b/libck-connector/ck-connector.h @@ -0,0 +1,122 @@ +/* + * ck-connector.h : Code for login managers to register with ConsoleKit. + * + * Copyright (c) 2007 David Zeuthen <davidz@redhat.com> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CK_CONNECTOR_H +#define CK_CONNECTOR_H + +#include <sys/types.h> +#include <dbus/dbus.h> + +struct CKConnecter_s; +typedef struct CKConnector_s CKConnector; + +/* Allocates a new CKConnector instance. + * + * Returns NULL on OOM */ +CKConnector *ckc_new (void); + +/* Connects to the D-Bus system bus daemon and issues the method call + * OpenSessionWithParameters on the ConsoleKit manager interface. The + * connection to the bus is private. + * + * The only parameter that is optional is x11_display - it may be set + * to NULL if there is no X11 server associated with the session. + * + * Returns FALSE on OOM, if the system bus daemon is not running, if + * the ConsoleKit daemon is not running or if the caller doesn't have + * sufficient privileges. + */ +dbus_bool_t ckc_create_local_session (CKConnector *ckc, uid_t user, const char *tty, const char *x11_display); + +dbus_bool_t ckc_create_local_session2 (CKConnector *ckc); + +/* Gets the cookie that should be set as XDG_SESSION_COOKIE in the + * users environment. + * + * Returns NULL unless ckc_create_local_session() succeeded + */ +char *ckc_get_cookie (CKConnector *ckc); + +/* Issues the CloseSession method call on the ConsoleKit manager + * interface. + * + * Returns FALSE on OOM, if the system bus daemon is not running, if + * the ConsoleKit daemon is not running, if the caller doesn't have + * sufficient privilege or if ckc_create_local_session() wasn't + * successfully invoked. + */ +dbus_bool_t ckc_close_session (CKConnector *ckc); + +/* Frees all resources allocated and disconnects from the system + * message bus. + */ +void ckc_free (CKConnector *ckc); + +/* example code: + +#include <stdio.h> +#include <stdlib.h> +#include "ck-connector.h" + +int +main (int argc, char *argv[]) +{ + CKConnector *ckc; + + ckc = ckc_new (); + if (ckc == NULL) { + printf ("OOM creating CKConnector\n"); + goto out; + } + + if (!ckc_create_local_session (ckc, 500, "/dev/tty2", ":1")) { + printf ("cannot create CK session: OOM, D-Bus system bus not available,\n" + "ConsoleKit not available or insufficient privileges.\n"); + goto out; + } + + printf ("Session cookie is '%s'\n", ckc_get_cookie (ckc)); + sleep (20); + + if (!ckc_close_session (ckc)) { + printf ("Cannot close CK session: OOM, D-Bus system bus not available,\n" + "ConsoleKit not available or insufficient privileges.\n"); + goto out; + } + +out: + if (ckc != NULL) { + ckc_free (ckc); + } +} + +*/ + +#endif /* CK_CONNECTOR_H */ + + + diff --git a/libck-connector/ck-connector.pc.in b/libck-connector/ck-connector.pc.in new file mode 100644 index 0000000..e3f00cd --- /dev/null +++ b/libck-connector/ck-connector.pc.in @@ -0,0 +1,9 @@ +libdir=/lib +includedir=@prefix@/include + +Name: ck-connector +Description: Library for connecting new sessions to ConsoleKit +Version: @VERSION@ +Requires: dbus-1 +Libs: -L${libdir} -lck-connector +Cflags: -I${includedir}/ConsoleKit/ck-connector |