Skip to content

Commit

Permalink
Share the TTY device with systemd-logind
Browse files Browse the repository at this point in the history
  • Loading branch information
thkukuk committed May 28, 2024
1 parent 8054b90 commit c0335fe
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ GSSLIBS=@GSSLIBS@
SSHDLIBS=@SSHDLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
LIBSYSTEMD=@LIBSYSTEMD@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
Expand Down Expand Up @@ -218,7 +219,7 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)

sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS)
$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS)
$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBSYSTEMD)

scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
Expand Down
41 changes: 41 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,47 @@ AC_ARG_WITH([libedit],
fi ]
)

# 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)],
Expand Down
92 changes: 92 additions & 0 deletions loginrec.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@
# include <util.h>
#endif

#ifdef USE_LOGIND
# include <systemd/sd-bus.h>
#endif

/**
** prototypes for helper functions in this file
**/
Expand All @@ -200,6 +204,9 @@ void construct_utmp(struct logininfo *li, struct utmp *ut);
void set_utmpx_time(struct logininfo *li, struct utmpx *ut);
void construct_utmpx(struct logininfo *li, struct utmpx *ut);
#endif
#ifdef USE_LOGIND
int logind_set_tty(struct logininfo *li);
#endif

int utmp_write_entry(struct logininfo *li);
int utmpx_write_entry(struct logininfo *li);
Expand Down Expand Up @@ -467,6 +474,9 @@ login_write(struct logininfo *li)
#ifdef USE_WTMPX
wtmpx_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,
Expand Down Expand Up @@ -1409,6 +1419,88 @@ wtmpx_get_entry(struct logininfo *li)
}
#endif /* USE_WTMPX */

#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)
return (0);

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
**/
Expand Down

0 comments on commit c0335fe

Please sign in to comment.