From 9dfcd1a0e691c1cad34b168e27b3ed31ab6986cd Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Sun, 9 Feb 2014 16:09:48 +0000 Subject: GSSAPI key exchange support This patch has been rejected upstream: "None of the OpenSSH developers are in favour of adding this, and this situation has not changed for several years. This is not a slight on Simon's patch, which is of fine quality, but just that a) we don't trust GSSAPI implementations that much and b) we don't like adding new KEX since they are pre-auth attack surface. This one is particularly scary, since it requires hooks out to typically root-owned system resources." However, quite a lot of people rely on this in Debian, and it's better to have it merged into the main openssh package rather than having separate -krb5 packages (as we used to have). It seems to have a generally good security history. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2014-03-19 Patch-Name: gssapi.patch --- configure | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'configure') diff --git a/configure b/configure index d690393a3..b6b5b6d8d 100755 --- a/configure +++ b/configure @@ -7170,6 +7170,63 @@ $as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have the Security Authorization Session API" >&5 +$as_echo_n "checking if we have the Security Authorization Session API... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +SessionCreate(0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_use_security_session_api="yes" + +$as_echo "#define USE_SECURITY_SESSION_API 1" >>confdefs.h + + LIBS="$LIBS -framework Security" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + ac_cv_use_security_session_api="no" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have an in-memory credentials cache" >&5 +$as_echo_n "checking if we have an in-memory credentials cache... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +cc_context_t c; + (void) cc_initialize (&c, 0, NULL, NULL); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define USE_CCAPI 1" >>confdefs.h + + LIBS="$LIBS -framework Security" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + if test "x$ac_cv_use_security_session_api" = "xno"; then + as_fn_error $? "*** Need a security framework to use the credentials cache API ***" "$LINENO" 5 + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default" if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then : -- cgit v1.2.3 From 7a26d16efb4ee303c8d66ee82caf9d0686f4a074 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: 2014-03-20 Patch-Name: consolekit.patch --- Makefile.in | 3 +- configure | 132 +++++++++++++++++++++++++++++++ configure.ac | 25 ++++++ consolekit.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ consolekit.h | 24 ++++++ monitor.c | 42 ++++++++++ monitor.h | 2 + monitor_wrap.c | 30 ++++++++ monitor_wrap.h | 4 + session.c | 13 ++++ session.h | 6 ++ 11 files changed, 520 insertions(+), 1 deletion(-) create mode 100644 consolekit.c create mode 100644 consolekit.h (limited to 'configure') diff --git a/Makefile.in b/Makefile.in index ee1d2c3b8..3d96c0550 100644 --- a/Makefile.in +++ b/Makefile.in @@ -97,7 +97,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-capsicum.o + sandbox-seccomp-filter.o sandbox-capsicum.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 b6b5b6d8d..e2f12cdff 100755 --- a/configure +++ b/configure @@ -740,6 +740,7 @@ with_privsep_user with_sandbox with_selinux with_kerberos5 +with_consolekit with_privsep_path with_xauth enable_strip @@ -1432,6 +1433,7 @@ Optional Packages: --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum) --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 @@ -17217,6 +17219,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 @@ -19746,6 +19877,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 d235fb06b..86692714b 100644 --- a/configure.ac +++ b/configure.ac @@ -4072,6 +4072,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 @@ -4873,6 +4897,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 000000000..f1039e652 --- /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 000000000..8ce371690 --- /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 11eac63c2..7c105e687 100644 --- a/monitor.c +++ b/monitor.c @@ -97,6 +97,9 @@ #include "ssh2.h" #include "roaming.h" #include "authfd.h" +#ifdef USE_CONSOLEKIT +#include "consolekit.h" +#endif #ifdef GSSAPI static Gssctxt *gsscontext = NULL; @@ -187,6 +190,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 */ @@ -271,6 +278,9 @@ struct mon_table mon_dispatch_postauth20[] = { #ifdef SSH_AUDIT_EVENTS {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} }; @@ -313,6 +323,9 @@ struct mon_table mon_dispatch_postauth15[] = { #ifdef SSH_AUDIT_EVENTS {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} }; @@ -492,6 +505,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); @@ -2269,3 +2285,29 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) { #endif /* GSSAPI */ +#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 4d5e8fabe..10ba59ea9 100644 --- a/monitor.h +++ b/monitor.h @@ -70,6 +70,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 f75dc9d71..a8fb07b52 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1353,3 +1353,33 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) #endif /* GSSAPI */ +#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 9c2ee49ba..00e93fe9c 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -111,4 +111,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 6848df42f..9d43fc3c7 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 @@ -1160,6 +1161,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; @@ -1304,6 +1308,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 @@ -2353,6 +2362,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 ef6593c34..a6b69837b 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 { @@ -61,6 +63,10 @@ struct Session { char *name; char *val; } *env; + +#ifdef USE_CONSOLEKIT + struct _CkConnector *ckc; +#endif /* USE_CONSOLEKIT */ }; void do_authenticated(Authctxt *); -- cgit v1.2.3