Skip to content

Commit

Permalink
ssh: Replace cockpit-ssh with cockpit.beiboot with the pybridge
Browse files Browse the repository at this point in the history
cockpit.beiboot has feature parity with cockpit-ssh. Entirely stop
building and shipping cockpit-ssh with the pybridge, and use
cockpit.beiboot by default for direct remote SSH logins from the login
page.

This gets rid of the libssh build dependency everywhere except RHEL 8.

Drop the `Provides: cockpit-ssh` from Debian. No package ever related to
that virtual package name, and it's meaningless these days.

Change ws' detection of remote login availability to `type cockpit-bridge`
with the pybridge, as the existence of cockpit-ssh is not relevant any
more. This is much cheaper than actually trying to run the bridge with
`--version` or call Python to check the module. We still need to do
this, as a system could only have the cockpit-ws package installed
but not cockpit-bridge.

https://issues.redhat.com/browse/COCKPIT-1029
  • Loading branch information
martinpitt committed Oct 6, 2023
1 parent cfcd08f commit 88c969d
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 26 deletions.
14 changes: 8 additions & 6 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,20 @@ if test "$enable_polkit" != 'no'; then
fi
AC_MSG_RESULT(${enable_polkit:=yes})

# --disable-ssh
AC_MSG_CHECKING([whether to build cockpit-ssh])
AC_ARG_ENABLE(ssh, AS_HELP_STRING([--disable-ssh], [Disable cockpit-ssh build and libssh dependency]))
AM_CONDITIONAL(WITH_COCKPIT_SSH, test "$enable_ssh" != "no")
AC_MSG_RESULT(${enable_ssh:=yes})

# --enable-old-bridge
AC_MSG_CHECKING([whether to install the old C cockpit-bridge])
AC_ARG_ENABLE(old_bridge, AS_HELP_STRING([--enable-old-bridge], [Install old C cockpit-bridge]))
AM_CONDITIONAL(WITH_OLD_BRIDGE, test "$enable_old_bridge" = "yes")
AC_MSG_RESULT(${enable_old_bridge:=no})
if test "$enable_old_bridge" != 'no'; then
AC_DEFINE([WITH_OLD_BRIDGE], 1, [Whether to build with old C cockpit-bridge])
fi

# --disable-ssh
AC_MSG_CHECKING([whether to build cockpit-ssh (only with --enable-old-bridge)])
AC_ARG_ENABLE(ssh, AS_HELP_STRING([--disable-ssh], [Disable cockpit-ssh build and libssh dependency]))
AM_CONDITIONAL(WITH_COCKPIT_SSH, test "$enable_ssh" != "no")
AC_MSG_RESULT(${enable_ssh:=${enable_old_bridge}})

# pkg-config
GLIB_API_VERSION="GLIB_VERSION_2_56"
Expand Down
8 changes: 3 additions & 5 deletions containers/ws/cockpit-auth-ssh-key
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
# by cockpit-ws. It asks for authentication from cockpit-ws and expects
# to receive a basic auth header in response. If COCKPIT_SSH_KEY_PATH is set
# we will try to decrypt the key with the given password. If successful
# we send the decrypted key to cockpit-ws for use with cockpit-ssh.
# Once finished we exec cockpit-ssh to actually establish the ssh connection.
# we send the decrypted key to cockpit-ws for use with ssh.
# Once finished we exec cockpit.beiboot to actually establish the ssh connection.
# All communication with cockpit-ws happens on stdin and stdout using the
# cockpit protocol
# (https://github.com/cockpit-project/cockpit/blob/main/doc/protocol.md)
Expand All @@ -33,8 +33,6 @@ import subprocess
import sys
import time

COCKPIT_SSH_COMMAND = "/usr/libexec/cockpit-ssh"


def usage():
print("usage", sys.argv[0], "[user@]host[:port]", file=sys.stderr)
Expand Down Expand Up @@ -189,7 +187,7 @@ def main(args):
{"password": "denied"})
return

os.execlpe(COCKPIT_SSH_COMMAND, COCKPIT_SSH_COMMAND, host, os.environ)
os.execlpe("python3", "python3", "-m", "cockpit.beiboot", host, os.environ)


if __name__ == '__main__':
Expand Down
2 changes: 2 additions & 0 deletions src/ssh/Makefile-ssh.am
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
if WITH_OLD_BRIDGE
if WITH_COCKPIT_SSH

# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -84,3 +85,4 @@ update-known-hosts:
$(srcdir)/src/ssh/mock_known_hosts

endif
endif
8 changes: 6 additions & 2 deletions src/ws/cockpitauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@

/* Some tunables that can be set from tests */
const gchar *cockpit_ws_session_program = LIBEXECDIR "/cockpit-session";
const gchar *cockpit_ws_ssh_program = LIBEXECDIR "/cockpit-ssh";
const gchar *cockpit_ws_ssh_program =
#ifdef WITH_OLD_BRIDGE
LIBEXECDIR "/cockpit-ssh";
#else
"/usr/bin/env python3 -m cockpit.beiboot";
#endif

/* Timeout of authenticated session when no connections */
guint cockpit_ws_service_idle = 15;
Expand Down Expand Up @@ -1047,7 +1052,6 @@ cockpit_session_launch (CockpitAuth *self,
return NULL;
}

/* this might be unset, which means "allow if cockpit-ssh is installed"; if it isn't, this will fail later on */
if (host && !cockpit_conf_bool ("WebService", "LoginTo", TRUE)) {
g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
"Direct remote login is disabled");
Expand Down
26 changes: 23 additions & 3 deletions src/ws/cockpithandlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,29 @@ add_page_to_environment (JsonObject *object,

if (page_login_to < 0)
{
page_login_to = cockpit_conf_bool ("WebService", "LoginTo",
g_file_test (cockpit_ws_ssh_program,
G_FILE_TEST_IS_EXECUTABLE));
gboolean have_ssh;
#ifdef WITH_OLD_BRIDGE
/* with C bridge, cockpit-ssh is a separate optional component */
have_ssh = g_file_test (cockpit_ws_ssh_program, G_FILE_TEST_IS_EXECUTABLE);
#else
/* with Py bridge, cockpit.beiboot is part of cockpit-bridge package */
gint status;
GError *error = NULL;
if (g_spawn_sync (NULL,
(gchar * []){ "type", "cockpit-bridge", NULL },
NULL,
G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
NULL, NULL, NULL, NULL, &status, &error))
{
have_ssh = status == 0;
}
else
{
g_warning ("Failed to check for cockpit-bridge, disabling remote logins: %s", error->message);
have_ssh = FALSE;
}
#endif
page_login_to = cockpit_conf_bool ("WebService", "LoginTo", have_ssh);
}

require_host = is_cockpit_client || cockpit_conf_bool ("WebService", "RequireHost", FALSE);
Expand Down
4 changes: 0 additions & 4 deletions test/verify/check-static-login
Original file line number Diff line number Diff line change
Expand Up @@ -967,10 +967,6 @@ matchrule = <SUBJECT>^DC=LAN,DC=COCKPIT,CN=alice$
# this matches our bots test VMs
my_ip = "172.27.0.15"

m.write("/etc/cockpit/cockpit.conf", """
[Ssh-Login]
Command = /usr/bin/env python3 -m cockpit.beiboot
""", append=True)
m.start_cockpit()

def try_login(user, password, server=None, expect_hostkey=False):
Expand Down
2 changes: 1 addition & 1 deletion test/verify/check-ws-bastion
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class TestWsBastionContainer(testlib.MachineCase):
"-v /root/known_hosts:/etc/ssh/ssh_known_hosts:ro,Z "
"-v /root/id_bastion:/id_bastion:ro,Z "
"-e COCKPIT_SSH_KEY_PATH=/id_bastion "
"-e G_MESSAGES_DEBUG=cockpit-ssh "
"-e COCKPIT_DEBUG=cockpit.beiboot "
"localhost/cockpit/ws")
m.execute("until curl --fail --head -k https://localhost:9090/; do sleep 1; done")

Expand Down
5 changes: 2 additions & 3 deletions tools/cockpit.spec
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ BuildRequires: libappstream-glib-devel
%else
BuildRequires: gettext >= 0.21
%endif
%if 0%{?build_basic}
%if 0%{?build_basic} && 0%{?enable_old_bridge}
BuildRequires: libssh-devel >= 0.8.5
%endif
BuildRequires: openssl-devel
Expand Down Expand Up @@ -227,8 +227,8 @@ echo %{buildroot}%{_datadir}/polkit-1/actions/org.cockpit-project.cockpit-bridge
%if 0%{?enable_old_bridge} && 0%{?build_basic}
echo '%dir %{_datadir}/cockpit/ssh' >> base.list
find %{buildroot}%{_datadir}/cockpit/ssh -type f >> base.list
%endif
echo '%{_libexecdir}/cockpit-ssh' >> base.list
%endif

echo '%dir %{_datadir}/cockpit/pcp' > pcp.list
find %{buildroot}%{_datadir}/cockpit/pcp -type f >> pcp.list
Expand Down Expand Up @@ -356,7 +356,6 @@ troubleshooting, interactive command-line sessions, and more.
%package bridge
Summary: Cockpit bridge server-side component
Requires: glib-networking
Provides: cockpit-ssh = %{version}-%{release}
# 233 dropped jquery.js, pages started to bundle it (commit 049e8b8dce)
Conflicts: cockpit-dashboard < 233
Conflicts: cockpit-networkmanager < 233
Expand Down
1 change: 0 additions & 1 deletion tools/debian/cockpit-bridge.install
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
etc/cockpit/machines.d
usr/bin/cockpit-bridge
usr/lib/cockpit/cockpit-askpass
usr/lib/cockpit/cockpit-ssh
usr/lib/python*
usr/share/cockpit/base1/
usr/share/man/man1/cockpit-bridge.1
Expand Down
1 change: 0 additions & 1 deletion tools/debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Build-Depends: debhelper-compat (= 13),
dh-python,
gettext (>= 0.19.7),
gettext (>= 0.21) | appstream,
libssh-dev (>= 0.8.5),
zlib1g-dev,
libkrb5-dev (>= 1.11),
libxslt1-dev,
Expand Down

0 comments on commit 88c969d

Please sign in to comment.