#72 Build OpenSSH without libsystemd dependency, using reference implementation
Merged 2 months ago by dbelyavs. Opened 2 months ago by gordonmessmer.
rpms/ gordonmessmer/openssh sd-notify  into  rawhide

@@ -1,98 +0,0 @@ 

- commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31

- Author: Jakub Jelen <jjelen@redhat.com>

- Date:   Mon Nov 21 15:04:06 2016 +0100

- 

-     systemd stuff

- 

- diff --git a/configure.ac b/configure.ac

- index 2ffc369..162ce92 100644

- --- a/configure.ac

- +++ b/configure.ac

- @@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5],

-  AC_SUBST([K5LIBS])

-  AC_SUBST([CHANNELLIBS])

-  

- +# Check whether user wants systemd support

- +SYSTEMD_MSG="no"

- +AC_ARG_WITH(systemd,

- +	[  --with-systemd          Enable systemd support],

- +	[ if test "x$withval" != "xno" ; then

- +		AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])

- +		if test "$PKGCONFIG" != "no"; then

- +			AC_MSG_CHECKING([for libsystemd])

- +			if $PKGCONFIG --exists libsystemd; then

- +				SYSTEMD_CFLAGS=`$PKGCONFIG --cflags libsystemd`

- +				SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd`

- +				CPPFLAGS="$CPPFLAGS $SYSTEMD_CFLAGS"

- +				SSHDLIBS="$SSHDLIBS $SYSTEMD_LIBS"

- +				AC_MSG_RESULT([yes])

- +				AC_DEFINE(HAVE_SYSTEMD, 1, [Define if you want systemd support.])

- +				SYSTEMD_MSG="yes"

- +			else

- +				AC_MSG_RESULT([no])

- +			fi

- +		fi

- +	fi ]

- +)

- +

- +

-  # Looking for programs, paths and files

-  

-  PRIVSEP_PATH=/var/empty

- @@ -5097,6 +5121,7 @@ echo "                   libedit support: $LIBEDIT_MSG"

-  echo "  Solaris process contract support: $SPC_MSG"

-  echo "           Solaris project support: $SP_MSG"

-  echo "         Solaris privilege support: $SPP_MSG"

- +echo "                   systemd support: $SYSTEMD_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/contrib/sshd.service b/contrib/sshd.service

- new file mode 100644

- index 0000000..e0d4923

- --- /dev/null

- +++ b/contrib/sshd.service

- @@ -0,0 +1,16 @@

- +[Unit]

- +Description=OpenSSH server daemon

- +Documentation=man:sshd(8) man:sshd_config(5)

- +After=network.target

- +

- +[Service]

- +Type=notify

- +ExecStart=/usr/sbin/sshd -D $OPTIONS

- +ExecReload=/bin/kill -HUP $MAINPID

- +KillMode=process

- +Restart=on-failure

- +RestartPreventExitStatus=255

- +

- +[Install]

- +WantedBy=multi-user.target

- +

- diff --git a/sshd.c b/sshd.c

- index 816611c..b8b9d13 100644

- --- a/sshd.c

- +++ b/sshd.c

- @@ -85,6 +85,10 @@

-  #include <prot.h>

-  #endif

-  

- +#ifdef HAVE_SYSTEMD

- +#include <systemd/sd-daemon.h>

- +#endif

- +

-  #include "xmalloc.h"

-  #include "ssh.h"

-  #include "ssh2.h"

- @@ -1888,6 +1892,11 @@ main(int ac, char **av)

-  			}

-  		}

-  

- +#ifdef HAVE_SYSTEMD

- +		/* Signal systemd that we are ready to accept connections */

- +		sd_notify(0, "READY=1");

- +#endif

- +

-  		/* Accept a connection and return in a forked child */

-  		server_accept_loop(&sock_in, &sock_out,

-  		    &newsock, config_s);

file modified
+2 -2
@@ -2206,8 +2206,8 @@ 

   			close_listen_socks();

   			if (options.pid_file != NULL)

   				unlink(options.pid_file);

- @@ -2098,7 +2154,7 @@ main(int ac, char **av)

-  #endif

+ @@ -2189,7 +2189,7 @@

+  		}

   

   		/* Accept a connection and return in a forked child */

  -		server_accept_loop(&sock_in, &sock_out,

@@ -0,0 +1,201 @@ 

+ diff --git a/configure.ac b/configure.ac

+ index 379cd746b..15e2ecdb7 100644

+ --- a/configure.ac

+ +++ b/configure.ac

+ @@ -907,6 +907,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))

+  	AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])

+  	AC_DEFINE([USE_BTMP])

+  	AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer])

+ +	AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload])

+  	inet6_default_4in6=yes

+  	case `uname -r` in

+  	1.*|2.0.*)

+ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c

+ index 0457e28d0..df7290246 100644

+ --- a/openbsd-compat/port-linux.c

+ +++ b/openbsd-compat/port-linux.c

+ @@ -21,16 +21,23 @@

+  

+  #include "includes.h"

+  

+ -#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)

+ +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \

+ +    defined(SYSTEMD_NOTIFY)

+ +#include <sys/socket.h>

+ +#include <sys/un.h>

+ +

+  #include <errno.h>

+ +#include <inttypes.h>

+  #include <stdarg.h>

+  #include <string.h>

+  #include <stdio.h>

+  #include <stdlib.h>

+ +#include <time.h>

+  

+  #include "log.h"

+  #include "xmalloc.h"

+  #include "port-linux.h"

+ +#include "misc.h"

+  

+  #ifdef WITH_SELINUX

+  #include <selinux/selinux.h>

+ @@ -310,4 +317,90 @@ oom_adjust_restore(void)

+  	return;

+  }

+  #endif /* LINUX_OOM_ADJUST */

+ -#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */

+ +

+ +#ifdef SYSTEMD_NOTIFY

+ +

+ +static void ssh_systemd_notify(const char *, ...)

+ +    __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1)));

+ +

+ +static void

+ +ssh_systemd_notify(const char *fmt, ...)

+ +{

+ +	char *s = NULL;

+ +	const char *path;

+ +	struct stat sb;

+ +	struct sockaddr_un addr;

+ +	int fd = -1;

+ +	va_list ap;

+ +

+ +	if ((path = getenv("NOTIFY_SOCKET")) == NULL || strlen(path) == 0)

+ +		return;

+ +

+ +	va_start(ap, fmt);

+ +	xvasprintf(&s, fmt, ap);

+ +	va_end(ap);

+ +

+ +	/* Only AF_UNIX is supported, with path or abstract sockets */

+ +	if (path[0] != '/' && path[0] != '@') {

+ +		error_f("socket \"%s\" is not compatible with AF_UNIX", path);

+ +		goto out;

+ +	}

+ +

+ +	if (path[0] == '/' && stat(path, &sb) != 0) {

+ +		error_f("socket \"%s\" stat: %s", path, strerror(errno));

+ +		goto out;

+ +	}

+ +

+ +	memset(&addr, 0, sizeof(addr));

+ +	addr.sun_family = AF_UNIX;

+ +	if (strlcpy(addr.sun_path, path,

+ +	    sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {

+ +		error_f("socket path \"%s\" too long", path);

+ +		goto out;

+ +	}

+ +	/* Support for abstract socket */

+ +	if (addr.sun_path[0] == '@')

+ +		addr.sun_path[0] = 0;

+ +	if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) {

+ +		error_f("socket \"%s\": %s", path, strerror(errno));

+ +		goto out;

+ +	}

+ +	if (connect(fd, &addr, sizeof(addr)) != 0) {

+ +		error_f("socket \"%s\" connect: %s", path, strerror(errno));

+ +		goto out;

+ +	}

+ +	if (write(fd, s, strlen(s)) != (ssize_t)strlen(s)) {

+ +		error_f("socket \"%s\" write: %s", path, strerror(errno));

+ +		goto out;

+ +	}

+ +	debug_f("socket \"%s\" notified %s", path, s);

+ + out:

+ +	if (fd != -1)

+ +		close(fd);

+ +	free(s);

+ +}

+ +

+ +void

+ +ssh_systemd_notify_ready(void)

+ +{

+ +	ssh_systemd_notify("READY=1");

+ +}

+ +

+ +void

+ +ssh_systemd_notify_reload(void)

+ +{

+ +	struct timespec now;

+ +

+ +	monotime_ts(&now);

+ +	if (now.tv_sec < 0 || now.tv_nsec < 0) {

+ +		error_f("monotime returned negative value");

+ +		ssh_systemd_notify("RELOADING=1");

+ +	} else {

+ +		ssh_systemd_notify("RELOADING=1\nMONOTONIC_USEC=%llu",

+ +		    ((uint64_t)now.tv_sec * 1000000ULL) +

+ +		    ((uint64_t)now.tv_nsec / 1000ULL));

+ +	}

+ +}

+ +#endif /* SYSTEMD_NOTIFY */

+ +

+ +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST || SYSTEMD_NOTIFY */

+ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h

+ index 3c22a854d..14064f87d 100644

+ --- a/openbsd-compat/port-linux.h

+ +++ b/openbsd-compat/port-linux.h

+ @@ -30,4 +30,9 @@ void oom_adjust_restore(void);

+  void oom_adjust_setup(void);

+  #endif

+  

+ +#ifdef SYSTEMD_NOTIFY

+ +void ssh_systemd_notify_ready(void);

+ +void ssh_systemd_notify_reload(void);

+ +#endif

+ +

+  #endif /* ! _PORT_LINUX_H */

+ diff --git a/platform.c b/platform.c

+ index 4fe8744ee..9cf818153 100644

+ --- a/platform.c

+ +++ b/platform.c

+ @@ -44,6 +44,14 @@ platform_pre_listen(void)

+  #endif

+  }

+  

+ +void

+ +platform_post_listen(void)

+ +{

+ +#ifdef SYSTEMD_NOTIFY

+ +	ssh_systemd_notify_ready();

+ +#endif

+ +}

+ +

+  void

+  platform_pre_fork(void)

+  {

+ @@ -55,6 +63,9 @@ platform_pre_fork(void)

+  void

+  platform_pre_restart(void)

+  {

+ +#ifdef SYSTEMD_NOTIFY

+ +	ssh_systemd_notify_reload();

+ +#endif

+  #ifdef LINUX_OOM_ADJUST

+  	oom_adjust_restore();

+  #endif

+ diff --git a/platform.h b/platform.h

+ index 7fef8c983..5dec23276 100644

+ --- a/platform.h

+ +++ b/platform.h

+ @@ -21,6 +21,7 @@

+  void platform_pre_listen(void);

+  void platform_pre_fork(void);

+  void platform_pre_restart(void);

+ +void platform_post_listen(void);

+  void platform_post_fork_parent(pid_t child_pid);

+  void platform_post_fork_child(void);

+  int  platform_privileged_uidswap(void);

+ diff --git a/sshd.c b/sshd.c

+ index 9cbe92293..3c3f2dd6b 100644

+ --- a/sshd.c

+ +++ b/sshd.c

+ @@ -2077,6 +2077,8 @@ main(int ac, char **av)

+  		ssh_signal(SIGTERM, sigterm_handler);

+  		ssh_signal(SIGQUIT, sigterm_handler);

+  

+ +		platform_post_listen();

+ +

+  		/*

+  		 * Write out the pid file after the sigterm handler

+  		 * is setup and the listen sockets are bound

file modified
+5 -2
@@ -54,7 +54,7 @@ 

  Summary: An open source implementation of SSH protocol version 2

  Name: openssh

  Version: %{openssh_ver}

- Release: %{openssh_rel}%{?dist}.3

+ Release: %{openssh_rel}%{?dist}.4

  URL: http://www.openssh.com/portable.html

  #URL1: https://github.com/jbeverly/pam_ssh_agent_auth/

  Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
@@ -175,7 +175,7 @@ 

  # Move MAX_DISPLAYS to a configuration option (#1341302)

  Patch944: openssh-7.3p1-x11-max-displays.patch

  # Help systemd to track the running service

- Patch948: openssh-7.4p1-systemd.patch

+ Patch948: openssh-9.8p1-systemd.patch

  # Pass inetd flags for SELinux down to openbsd compat level

  Patch949: openssh-7.6p1-cleanup-selinux.patch

  # Sandbox adjustments for s390 and audit
@@ -740,6 +740,9 @@ 

  %endif

  

  %changelog

+ * Tue Apr 02 2024 Gordon Messmer <gordon.messmer@gmail.com> - 9.6p1-1.4

+ - Build OpenSSH without libsystemd dependency, using reference implementation

+ 

  * Wed Mar 13 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.3

  - Build OpenSSH without engine support

  - Make tests run at build phase (using parallel run mechanism by Alexander Sosedkin)

This change removes the dependency on libsystemd, replacing it with the reference implementation from:

https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Notes

Build succeeded.
https://fedora.softwarefactory-project.io/zuul/buildset/cf2abd1302cf40f38ac28eadf8192460

rebased onto c279fed7f75b769541781319d3fa890f51b593f1

2 months ago

OK. I've replaced the old patch with commit 08f579231cd38 from openssh-portable.

N/M. Build will fail, but I'll update the PR shortly.

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci
https://fedora.softwarefactory-project.io/zuul/buildset/102b036142104e75b849d7cf243648cd

rebased onto 031b4c6

2 months ago

Build succeeded.
https://fedora.softwarefactory-project.io/zuul/buildset/a5751a8e3441476ba74ba667d5fbd915

Shouldn't we explicitly define SYSTEMD_NOTIFY at the configure time?

Shouldn't we explicitly define SYSTEMD_NOTIFY at the configure time?

Not necessary anymore, I've changerd it to always built in when building for Linux given it has no external dependencies and the runtime is a no-op unless NOTIFY_SOCKET is defined in env

note the same could be done for libreswan that uses sd_notify(). As upstream we plan to do it, but we are probably too busy to do it within the next two weeks. patches without testcases welcomed :)

note the same could be done for libreswan

Would you prefer the reference implementation from https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Notes or something derived from OpenSSH's patch?

Pull-Request has been merged by dbelyavs

2 months ago

Merged. Many thanks for your contribution!