From 05609b1cb381eafb999214bf4a95138e63abdbf2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:09:57 +0000 Subject: Add support for registering ConsoleKit sessions on login Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1450 Last-Updated: 2013-09-14 Patch-Name: consolekit.patch --- Makefile.in | 3 +- configure | 132 +++++++++++++++++++++++++++++++ configure.ac | 25 ++++++ consolekit.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ consolekit.h | 24 ++++++ monitor.c | 43 +++++++++++ monitor.h | 2 + monitor_wrap.c | 31 ++++++++ monitor_wrap.h | 4 + session.c | 13 ++++ session.h | 6 ++ 11 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 consolekit.c create mode 100644 consolekit.h diff --git a/Makefile.in b/Makefile.in index f979926..b2dbead 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,7 +94,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o + sandbox-seccomp-filter.o \ + consolekit.o MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 diff --git a/configure b/configure index ceb1b5d..78bbcd0 100755 --- a/configure +++ b/configure @@ -738,6 +738,7 @@ with_privsep_user with_sandbox with_selinux with_kerberos5 +with_consolekit with_privsep_path with_xauth enable_strip @@ -1428,6 +1429,7 @@ Optional Packages: --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support + --with-consolekit Enable ConsoleKit support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) --with-xauth=PATH Specify path to xauth program --with-maildir=/path/to/mail Specify your system mail directory @@ -16375,6 +16377,135 @@ fi +# Check whether user wants ConsoleKit support +CONSOLEKIT_MSG="no" +LIBCK_CONNECTOR="" + +# Check whether --with-consolekit was given. +if test "${with_consolekit+set}" = set; then : + withval=$with_consolekit; if test "x$withval" != "xno" ; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKGCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKGCONFIG=$ac_cv_path_PKGCONFIG +if test -n "$PKGCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 +$as_echo "$PKGCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKGCONFIG"; then + ac_pt_PKGCONFIG=$PKGCONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKGCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG +if test -n "$ac_pt_PKGCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 +$as_echo "$ac_pt_PKGCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKGCONFIG" = x; then + PKGCONFIG="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKGCONFIG=$ac_pt_PKGCONFIG + fi +else + PKGCONFIG="$ac_cv_path_PKGCONFIG" +fi + + if test "$PKGCONFIG" != "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ck-connector" >&5 +$as_echo_n "checking for ck-connector... " >&6; } + if $PKGCONFIG --exists ck-connector; then + CKCON_CFLAGS=`$PKGCONFIG --cflags ck-connector` + CKCON_LIBS=`$PKGCONFIG --libs ck-connector` + CPPFLAGS="$CPPFLAGS $CKCON_CFLAGS" + SSHDLIBS="$SSHDLIBS $CKCON_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define USE_CONSOLEKIT 1" >>confdefs.h + + CONSOLEKIT_MSG="yes" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + fi + +fi + + # Looking for programs, paths and files PRIVSEP_PATH=/var/empty @@ -18902,6 +19033,7 @@ echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" +echo " ConsoleKit support: $CONSOLEKIT_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" diff --git a/configure.ac b/configure.ac index 4c1a658..d7d500a 100644 --- a/configure.ac +++ b/configure.ac @@ -3841,6 +3841,30 @@ AC_ARG_WITH([kerberos5], AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) +# Check whether user wants ConsoleKit support +CONSOLEKIT_MSG="no" +LIBCK_CONNECTOR="" +AC_ARG_WITH(consolekit, + [ --with-consolekit Enable ConsoleKit support], + [ if test "x$withval" != "xno" ; then + AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) + if test "$PKGCONFIG" != "no"; then + AC_MSG_CHECKING([for ck-connector]) + if $PKGCONFIG --exists ck-connector; then + CKCON_CFLAGS=`$PKGCONFIG --cflags ck-connector` + CKCON_LIBS=`$PKGCONFIG --libs ck-connector` + CPPFLAGS="$CPPFLAGS $CKCON_CFLAGS" + SSHDLIBS="$SSHDLIBS $CKCON_LIBS" + AC_MSG_RESULT([yes]) + AC_DEFINE(USE_CONSOLEKIT, 1, [Define if you want ConsoleKit support.]) + CONSOLEKIT_MSG="yes" + else + AC_MSG_RESULT([no]) + fi + fi + fi ] +) + # Looking for programs, paths and files PRIVSEP_PATH=/var/empty @@ -4641,6 +4665,7 @@ echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" +echo " ConsoleKit support: $CONSOLEKIT_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" diff --git a/consolekit.c b/consolekit.c new file mode 100644 index 0000000..f1039e6 --- /dev/null +++ b/consolekit.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2008 Colin Watson. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Loosely based on pam-ck-connector, which is: + * + * Copyright (c) 2007 David Zeuthen + * + * 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 "includes.h" + +#ifdef USE_CONSOLEKIT + +#include + +#include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" +#include "channels.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" +#include "session.h" +#include "consolekit.h" + +extern ServerOptions options; +extern u_int utmp_len; + +void +set_active(const char *cookie) +{ + DBusError err; + DBusConnection *connection; + DBusMessage *message = NULL, *reply = NULL; + char *sid; + DBusMessageIter iter, subiter; + const char *interface, *property; + dbus_bool_t active; + + dbus_error_init(&err); + connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err); + if (!connection) { + if (dbus_error_is_set(&err)) { + error("unable to open DBus connection: %s", + err.message); + dbus_error_free(&err); + } + goto out; + } + dbus_connection_set_exit_on_disconnect(connection, FALSE); + + message = dbus_message_new_method_call("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "GetSessionForCookie"); + if (!message) + goto out; + if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + if (dbus_error_is_set(&err)) { + error("unable to get current session: %s", + err.message); + dbus_error_free(&err); + } + goto out; + } + + dbus_error_init(&err); + reply = dbus_connection_send_with_reply_and_block(connection, message, + -1, &err); + if (!reply) { + if (dbus_error_is_set(&err)) { + error("unable to get current session: %s", + err.message); + dbus_error_free(&err); + } + goto out; + } + + dbus_error_init(&err); + if (!dbus_message_get_args(reply, &err, + DBUS_TYPE_OBJECT_PATH, &sid, + DBUS_TYPE_INVALID)) { + if (dbus_error_is_set(&err)) { + error("unable to get current session: %s", + err.message); + dbus_error_free(&err); + } + goto out; + } + dbus_message_unref(reply); + dbus_message_unref(message); + message = reply = NULL; + + message = dbus_message_new_method_call("org.freedesktop.ConsoleKit", + sid, "org.freedesktop.DBus.Properties", "Set"); + if (!message) + goto out; + interface = "org.freedesktop.ConsoleKit.Session"; + property = "active"; + if (!dbus_message_append_args(message, + DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) + goto out; + dbus_message_iter_init_append(message, &iter); + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, &subiter)) + goto out; + active = TRUE; + if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_BOOLEAN, + &active)) + goto out; + if (!dbus_message_iter_close_container(&iter, &subiter)) + goto out; + + dbus_error_init(&err); + reply = dbus_connection_send_with_reply_and_block(connection, message, + -1, &err); + if (!reply) { + if (dbus_error_is_set(&err)) { + error("unable to make current session active: %s", + err.message); + dbus_error_free(&err); + } + goto out; + } + +out: + if (reply) + dbus_message_unref(reply); + if (message) + dbus_message_unref(message); +} + +/* + * We pass display separately rather than using s->display because the + * latter is not available in the monitor when using privsep. + */ + +char * +consolekit_register(Session *s, const char *display) +{ + DBusError err; + const char *tty = s->tty; + const char *remote_host_name; + dbus_bool_t is_local = FALSE; + const char *cookie = NULL; + + if (s->ckc) { + debug("already registered with ConsoleKit"); + return xstrdup(ck_connector_get_cookie(s->ckc)); + } + + s->ckc = ck_connector_new(); + if (!s->ckc) { + error("ck_connector_new failed"); + return NULL; + } + + if (!tty) + tty = ""; + if (!display) + display = ""; + remote_host_name = get_remote_name_or_ip(utmp_len, options.use_dns); + if (!remote_host_name) + remote_host_name = ""; + + dbus_error_init(&err); + if (!ck_connector_open_session_with_parameters(s->ckc, &err, + "unix-user", &s->pw->pw_uid, + "display-device", &tty, + "x11-display", &display, + "remote-host-name", &remote_host_name, + "is-local", &is_local, + NULL)) { + if (dbus_error_is_set(&err)) { + debug("%s", err.message); + dbus_error_free(&err); + } else { + debug("insufficient privileges or D-Bus / ConsoleKit " + "not available"); + } + return NULL; + } + + debug("registered uid=%d on tty='%s' with ConsoleKit", + s->pw->pw_uid, s->tty); + + cookie = ck_connector_get_cookie(s->ckc); + set_active(cookie); + return xstrdup(cookie); +} + +void +consolekit_unregister(Session *s) +{ + if (s->ckc) { + debug("unregistering ConsoleKit session %s", + ck_connector_get_cookie(s->ckc)); + ck_connector_unref(s->ckc); + s->ckc = NULL; + } +} + +#endif /* USE_CONSOLEKIT */ diff --git a/consolekit.h b/consolekit.h new file mode 100644 index 0000000..8ce3716 --- /dev/null +++ b/consolekit.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008 Colin Watson. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef USE_CONSOLEKIT + +struct Session; + +char * consolekit_register(struct Session *, const char *); +void consolekit_unregister(struct Session *); + +#endif /* USE_CONSOLEKIT */ diff --git a/monitor.c b/monitor.c index e8d63eb..9bc4f0b 100644 --- a/monitor.c +++ b/monitor.c @@ -98,6 +98,9 @@ #include "jpake.h" #include "roaming.h" #include "authfd.h" +#ifdef USE_CONSOLEKIT +#include "consolekit.h" +#endif #ifdef GSSAPI static Gssctxt *gsscontext = NULL; @@ -193,6 +196,10 @@ int mm_answer_audit_command(int, Buffer *); static int monitor_read_log(struct monitor *); +#ifdef USE_CONSOLEKIT +int mm_answer_consolekit_register(int, Buffer *); +#endif + static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -285,6 +292,9 @@ struct mon_table mon_dispatch_postauth20[] = { {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, #endif +#ifdef USE_CONSOLEKIT + {MONITOR_REQ_CONSOLEKIT_REGISTER, 0, mm_answer_consolekit_register}, +#endif {0, 0, NULL} }; @@ -327,6 +337,9 @@ struct mon_table mon_dispatch_postauth15[] = { {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, #endif +#ifdef USE_CONSOLEKIT + {MONITOR_REQ_CONSOLEKIT_REGISTER, 0, mm_answer_consolekit_register}, +#endif {0, 0, NULL} }; @@ -514,6 +527,9 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); } +#ifdef USE_CONSOLEKIT + monitor_permit(mon_dispatch, MONITOR_REQ_CONSOLEKIT_REGISTER, 1); +#endif for (;;) monitor_read(pmonitor, mon_dispatch, NULL); @@ -2492,3 +2508,30 @@ mm_answer_jpake_check_confirm(int sock, Buffer *m) } #endif /* JPAKE */ + +#ifdef USE_CONSOLEKIT +int +mm_answer_consolekit_register(int sock, Buffer *m) +{ + Session *s; + char *tty, *display; + char *cookie = NULL; + + debug3("%s entering", __func__); + + tty = buffer_get_string(m, NULL); + display = buffer_get_string(m, NULL); + s = session_by_tty(tty); + if (s != NULL) + cookie = consolekit_register(s, display); + buffer_clear(m); + buffer_put_cstring(m, cookie != NULL ? cookie : ""); + mm_request_send(sock, MONITOR_ANS_CONSOLEKIT_REGISTER, m); + + free(cookie); + free(display); + free(tty); + + return (0); +} +#endif /* USE_CONSOLEKIT */ diff --git a/monitor.h b/monitor.h index 3c13706..cd83428 100644 --- a/monitor.h +++ b/monitor.h @@ -75,6 +75,8 @@ enum monitor_reqtype { MONITOR_REQ_AUTHROLE = 154, + MONITOR_REQ_CONSOLEKIT_REGISTER = 156, MONITOR_ANS_CONSOLEKIT_REGISTER = 157, + }; struct mm_master; diff --git a/monitor_wrap.c b/monitor_wrap.c index 69bc324..670b62d 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1516,3 +1516,34 @@ mm_jpake_check_confirm(const BIGNUM *k, return success; } #endif /* JPAKE */ + +#ifdef USE_CONSOLEKIT +char * +mm_consolekit_register(Session *s, const char *display) +{ + Buffer m; + char *cookie; + + debug3("%s entering", __func__); + + if (s->ttyfd == -1) + return NULL; + buffer_init(&m); + buffer_put_cstring(&m, s->tty); + buffer_put_cstring(&m, display != NULL ? display : ""); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_CONSOLEKIT_REGISTER, &m); + buffer_clear(&m); + + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_CONSOLEKIT_REGISTER, &m); + cookie = buffer_get_string(&m, NULL); + buffer_free(&m); + + /* treat empty cookie as missing cookie */ + if (strlen(cookie) == 0) { + free(cookie); + cookie = NULL; + } + return (cookie); +} +#endif /* USE_CONSOLEKIT */ diff --git a/monitor_wrap.h b/monitor_wrap.h index 4d12e29..360fb9f 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -131,4 +131,8 @@ void *mm_zalloc(struct mm_master *, u_int, u_int); void mm_zfree(struct mm_master *, void *); void mm_init_compression(struct mm_master *); +#ifdef USE_CONSOLEKIT +char *mm_consolekit_register(struct Session *, const char *); +#endif /* USE_CONSOLEKIT */ + #endif /* _MM_WRAP_H_ */ diff --git a/session.c b/session.c index b4d74d9..15bdb1b 100644 --- a/session.c +++ b/session.c @@ -92,6 +92,7 @@ #include "kex.h" #include "monitor_wrap.h" #include "sftp.h" +#include "consolekit.h" #if defined(KRB5) && defined(USE_AFS) #include @@ -1132,6 +1133,9 @@ do_setup_env(Session *s, const char *shell) #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) char *path = NULL; #endif +#ifdef USE_CONSOLEKIT + const char *ckcookie = NULL; +#endif /* USE_CONSOLEKIT */ /* Initialize the environment. */ envsize = 100; @@ -1276,6 +1280,11 @@ do_setup_env(Session *s, const char *shell) child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif +#ifdef USE_CONSOLEKIT + ckcookie = PRIVSEP(consolekit_register(s, s->display)); + if (ckcookie) + child_set_env(&env, &envsize, "XDG_SESSION_COOKIE", ckcookie); +#endif /* USE_CONSOLEKIT */ #ifdef USE_PAM /* * Pull in any environment variables that may have @@ -2320,6 +2329,10 @@ session_pty_cleanup2(Session *s) debug("session_pty_cleanup: session %d release %s", s->self, s->tty); +#ifdef USE_CONSOLEKIT + consolekit_unregister(s); +#endif /* USE_CONSOLEKIT */ + /* Record that the user has logged out. */ if (s->pid != 0) record_logout(s->pid, s->tty, s->pw->pw_name); diff --git a/session.h b/session.h index cb4f196..7e51b6a 100644 --- a/session.h +++ b/session.h @@ -26,6 +26,8 @@ #ifndef SESSION_H #define SESSION_H +struct _CkConnector; + #define TTYSZ 64 typedef struct Session Session; struct Session { @@ -60,6 +62,10 @@ struct Session { char *name; char *val; } *env; + +#ifdef USE_CONSOLEKIT + struct _CkConnector *ckc; +#endif /* USE_CONSOLEKIT */ }; void do_authenticated(Authctxt *);