openssh/logind_set_tty.patch
Antonio Larrosa fef1b16e66 - Drop most of openssh-6.6p1-keycat.patch (actually, it was just
commented out). The keycat binary isn't really installed nor
  supported, so we can drop it, except for the code that is used
  by other SELinux patches, which is what I kept from that patch
  (boo#1229072).
- Add patch submitted to upstream to fix RFC4256 implementation
  so that keyboard-interactive authentication method can send
  instructions and sshd shows them to users even before a prompt
  is requested. This fixes MFA push notifications (boo#1229010).
  * 0001-auth-pam-Immediately-report-instructions-to-clients-and-fix-handling-in-ssh-client.patch

OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=274
2024-09-12 10:24:41 +00:00

201 lines
5.3 KiB
Diff

diff --git a/Makefile.in b/Makefile.in
index f0ea07e7b..35dcf45f1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -56,6 +56,7 @@ SSHDLIBS=@SSHDLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
LIBWTMPDB=@LIBWTMPDB@
+LIBSYSTEMD=@LIBSYSTEMD@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
@@ -208,7 +209,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) $(LIBWTMPDB) $(LIBSYSTEMD)
sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS)
$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
diff --git a/configure.ac b/configure.ac
index a12c6f7ad..860df3379 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1789,6 +1789,47 @@ AC_ARG_WITH([wtmpdb],
)
+# Check whether user wants logind/set tty support
+AC_ARG_WITH([logind],
+ [ --with-logind[[=PATH]] Enable logind support for sshd],
+ [ if test "x$withval" != "xno" ; then
+ if test "x$withval" = "xyes" ; then
+ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
+ if test "x$PKGCONFIG" != "xno"; then
+ AC_MSG_CHECKING([if $PKGCONFIG knows about libsystemd])
+ if "$PKGCONFIG" libsystemd; then
+ AC_MSG_RESULT([yes])
+ use_pkgconfig_for_libsystemd=yes
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ else
+ CPPFLAGS="$CPPFLAGS -I${withval}/include"
+ if test -n "${rpath_opt}"; then
+ LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
+ else
+ LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+ fi
+ fi
+ if test "x$use_pkgconfig_for_libsystemd" = "xyes"; then
+ LIBSYSTEMD=`$PKGCONFIG --libs libsystemd`
+ CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libsystemd`"
+ else
+ LIBSYSTEMD="-lsystemd"
+ fi
+ OTHERLIBS=`echo $LIBSYSTEMD | sed 's/-lsystemd//'`
+ AC_CHECK_LIB([systemd], [sd_bus_open_system],
+ [ AC_DEFINE([USE_LOGIND], [1], [Use systemd-logind])
+ AC_SUBST([LIBSYSTEMD])
+ ],
+ [ AC_MSG_ERROR([libsystemd not found]) ],
+ [ $OTHERLIBS ]
+ )
+ fi ]
+)
+
+
AUDIT_MODULE=none
AC_ARG_WITH([audit],
[ --with-audit=module Enable audit support (modules=debug,bsm,linux)],
diff --git a/loginrec.c b/loginrec.c
index 86caf83b2..8b413190b 100644
--- a/loginrec.c
+++ b/loginrec.c
@@ -191,6 +191,10 @@
# include <wtmpdb.h>
#endif
+#ifdef USE_LOGIND
+# include <systemd/sd-bus.h>
+#endif
+
/**
** prototypes for helper functions in this file
**/
@@ -214,6 +218,9 @@ int syslogin_write_entry(struct logininfo *li);
#ifdef USE_WTMPDB
int wtmpdb_write_entry(struct logininfo *li);
#endif
+#ifdef USE_LOGIND
+int logind_set_tty(struct logininfo *li);
+#endif
int getlast_entry(struct logininfo *li);
int lastlog_get_entry(struct logininfo *li);
@@ -477,6 +484,9 @@ login_write(struct logininfo *li)
#ifdef USE_WTMPDB
wtmpdb_write_entry(li);
#endif
+#ifdef USE_LOGIND
+ logind_set_tty(li);
+#endif
#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
if (li->type == LTYPE_LOGIN &&
!sys_auth_record_login(li->username,li->hostname,li->line,
@@ -1476,6 +1486,91 @@ wtmpdb_write_entry(struct logininfo *li)
}
#endif
+#ifdef USE_LOGIND
+#define DBUS_DESTINATION "org.freedesktop.login1"
+#define DBUS_PATH_ID "/org/freedesktop/login1/session/auto"
+#define DBUS_INTERFACE "org.freedesktop.login1.Session"
+#define DBUS_PATH "/org/freedesktop/login1/session/%s"
+
+static int
+logind_perform_login(struct logininfo *li)
+{
+ sd_bus *bus = NULL;
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ char *session_id = NULL;
+ char *dbus_path;
+ const char *tty;
+ char buf[PATH_MAX];
+ int r;
+ int fd;
+
+ if (sd_bus_open_system(&bus) < 0)
+ {
+ logit("logind: canot open dbus");
+ return (0);
+ }
+
+ if (sd_bus_get_property_string(bus, DBUS_DESTINATION,
+ DBUS_PATH_ID, DBUS_INTERFACE,
+ "Id", &error, &session_id) < 0)
+ {
+ logit("logind: cannot get session ID");
+ return (0);
+ }
+
+ if (strncmp(li->line, "/dev/", 5) != 0)
+ snprintf (buf, sizeof(buf), "/dev/%s", li->line);
+ else
+ tty = li->line;
+
+ fd = open(tty, O_RDWR|O_CLOEXEC|O_NOCTTY);
+
+ if (asprintf (&dbus_path, DBUS_PATH, session_id) < 0)
+ return (0);
+
+ if (sd_bus_call_method(bus, DBUS_DESTINATION, dbus_path,
+ DBUS_INTERFACE, "TakeControl", &error, NULL,
+ "b", 1) < 0) {
+ logit("logind: cannot take control");
+ free(dbus_path);
+ return (0);
+ }
+
+ if ((r = sd_bus_call_method(bus, DBUS_DESTINATION, dbus_path,
+ DBUS_INTERFACE, "SetTTY", &error, NULL,
+ "h", fd)) < 0) {
+ if (r != -EBADR) /* logind does not support "SetTTY" */
+ logit("logind: cannot set TTY(%s, %s): %s", session_id, tty, strerror(-r));
+ free(dbus_path);
+ return (0);
+ }
+
+ free(dbus_path);
+
+ if (sd_bus_flush(bus) < 0) {
+ sd_bus_unref(bus);
+ return (0);
+ }
+
+ sd_bus_unref(bus);
+ return (1);
+}
+
+int
+logind_set_tty(struct logininfo *li)
+{
+ switch(li->type) {
+ case LTYPE_LOGIN:
+ return (logind_perform_login(li));
+ case LTYPE_LOGOUT:
+ return (1);
+ default:
+ logit("%s: invalid type field", __func__);
+ return (0);
+ }
+}
+#endif
+
/**
** Low-level libutil login() functions