From a96dfc70985480b22a1f8b98548267f2b5bccc74 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Fri, 23 Jul 2021 11:36:56 -0500 Subject: [PATCH] launchers: remove launchers Moving forward we're going to be supporting libseat and logind as our only launchers. We're doing this to reduce our maintenance burden, and security impact. Libseat supports all our existing use cases, and seatd can replace weston-launch so we no longer have to carry a setuid-root program. This patch removes weston-launch, and launcher-direct, leaving only libseat and logind. Signed-off-by: Derek Foreman --- .gitlab-ci.yml | 2 - .gitlab-ci/build-deps.sh | 5 +- README.md | 12 - doc/sphinx/toc/running-weston.rst | 7 +- libweston/backend-drm/drm.c | 7 +- libweston/backend-fbdev/fbdev.c | 5 +- libweston/launcher-direct.c | 370 ------------ libweston/launcher-impl.h | 2 - libweston/launcher-util.c | 2 - libweston/launcher-weston-launch.c | 396 ------------- libweston/meson.build | 21 - libweston/weston-launch.c | 917 ----------------------------- libweston/weston-launch.h | 51 -- man/weston-bindings.man | 1 - man/weston-drm.man | 28 - man/weston.ini.man | 5 +- man/weston.man | 12 +- meson.build | 4 + meson_options.txt | 7 - 19 files changed, 16 insertions(+), 1838 deletions(-) delete mode 100644 libweston/launcher-direct.c delete mode 100644 libweston/launcher-weston-launch.c delete mode 100644 libweston/weston-launch.c delete mode 100644 libweston/weston-launch.h diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e68b5741..46239fca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -284,7 +284,6 @@ aarch64-debian-container_prep: -Dtest-skip-is-failure=true -Dlauncher-libseat=true -Ddeprecated-backend-fbdev=true - -Ddeprecated-weston-launch=true after_script: - ninja -C "$BUILDDIR" coverage-html > "$BUILDDIR/meson-logs/ninja-coverage-html.txt" - ninja -C "$BUILDDIR" coverage-xml @@ -338,7 +337,6 @@ docs-build: -Dpipewire=false -Dwerror=true -Dlauncher-libseat=true - -Ddeprecated-weston-launch=true x86_64-debian-no-gl-build: extends: diff --git a/.gitlab-ci/build-deps.sh b/.gitlab-ci/build-deps.sh index 67e06701..158ff7c4 100755 --- a/.gitlab-ci/build-deps.sh +++ b/.gitlab-ci/build-deps.sh @@ -143,9 +143,8 @@ ninja ${NINJAFLAGS} -C build install cd .. rm -rf pipewire-src -# seatd lets us avoid the pain of handling VTs manually through weston-launch -# or open-coding TTY assignment within Weston. We use this for our tests using -# the DRM backend. +# seatd lets us avoid the pain of open-coding TTY assignment within Weston. +# We use this for our tests using the DRM backend. git clone --depth=1 --branch 0.6.1 https://git.sr.ht/~kennylevinsen/seatd cd seatd meson build -Dauto_features=disabled \ diff --git a/README.md b/README.md index 77552ca6..2d093825 100644 --- a/README.md +++ b/README.md @@ -93,13 +93,6 @@ the available configuration options and display backends. It can also be configured through a file on disk; more information on this can be found through `man weston.ini`. -In some special cases, such as when running remotely or without logind's session -control, Weston may not be able to run directly from a text console. In these -situations, you can instead execute the `weston-launch` helper, which will gain -privileged access to input and output devices by running as root, then granting -access to the main Weston binary running as your user. Running Weston this way -is not recommended unless necessary. - Documentation ============= @@ -308,11 +301,6 @@ Details: - xwayland ??? -- weston-launch is still with libweston even though it can only launch - Weston and nothing else. We would like to allow it to launch any compositor, - but since it gives by design root access to input devices and DRM, how can - we restrict it to intended programs? - There are still many more details to be decided. diff --git a/doc/sphinx/toc/running-weston.rst b/doc/sphinx/toc/running-weston.rst index e14ec55d..715bff42 100644 --- a/doc/sphinx/toc/running-weston.rst +++ b/doc/sphinx/toc/running-weston.rst @@ -91,17 +91,14 @@ You can start Weston from a VT assuming that there's a seat manager supported by backend to be used by ``libseat`` can optionally be selected with ``$LIBSEAT_BACKEND``. If ``libseat`` and ``seatd`` are both installed, but ``seatd`` is not already running, it can be started with ``sudo -- seatd -g -video``. If no seat manager supported by ``libseat`` is available, you can use -the ``weston-launch`` application that can handle VT switching. +video``. Another way of launching Weston is via ssh or a serial terminal. The simplest option here is to use the ``libseat`` launcher with ``seatd``. The process for setting that up is identical to the one described above, where one just need to ensure that ``seatd`` is running with the appropriate arguments, after which one can just run ``weston``. Another option, is to rely on logind and start weston -as systemd user service: :ref:`weston-user-service`. Alternatively and as a last -resort, one can run Weston as root, specifying the tty to use on the command -line: If TTY 2 is active, one would run ``weston --tty 2`` as root. +as systemd user service: :ref:`weston-user-service`. Running Weston on a different seat on a stand-alone back-end ------------------------------------------------------------ diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index be647deb..387184ef 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -3017,13 +3017,12 @@ drm_backend_create(struct weston_compositor *compositor, if (parse_gbm_format(config->gbm_format, DRM_FORMAT_XRGB8888, &b->gbm_format) < 0) goto err_compositor; - /* Check if we run drm-backend using weston-launch */ + /* Check if we run drm-backend using a compatible launcher */ compositor->launcher = weston_launcher_connect(compositor, config->tty, seat_id, true); if (compositor->launcher == NULL) { - weston_log("fatal: drm backend should be run using " - "weston-launch binary, or your system should " - "provide the logind D-Bus API.\n"); + weston_log("fatal: your system should either provide the " + "logind D-Bus API, or use seatd.\n"); goto err_compositor; } diff --git a/libweston/backend-fbdev/fbdev.c b/libweston/backend-fbdev/fbdev.c index 7dfea6fb..38a9b4c3 100644 --- a/libweston/backend-fbdev/fbdev.c +++ b/libweston/backend-fbdev/fbdev.c @@ -926,9 +926,8 @@ fbdev_backend_create(struct weston_compositor *compositor, compositor->launcher = weston_launcher_connect(compositor, param->tty, seat_id, false); if (!compositor->launcher) { - weston_log("fatal: fbdev backend should be run using " - "weston-launch binary, or your system should " - "provide the logind D-Bus API.\n"); + weston_log("fatal: your system should either provide the " + "logind D-Bus API, or use seatd.\n"); goto out_udev; } diff --git a/libweston/launcher-direct.c b/libweston/launcher-direct.c deleted file mode 100644 index c04ba857..00000000 --- a/libweston/launcher-direct.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright © 2012 Benjamin Franzke - * Copyright © 2013 Intel Corporation - * - * 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 (including the - * next paragraph) 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 "config.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "launcher-impl.h" - -#define DRM_MAJOR 226 - -#ifndef KDSKBMUTE -#define KDSKBMUTE 0x4B51 -#endif - -/* major()/minor() */ -#ifdef MAJOR_IN_MKDEV -#include -#endif -#ifdef MAJOR_IN_SYSMACROS -#include -#endif - -#ifdef BUILD_DRM_COMPOSITOR - -#include - -static inline int -is_drm_master(int drm_fd) -{ - drm_magic_t magic; - - return drmGetMagic(drm_fd, &magic) == 0 && - drmAuthMagic(drm_fd, magic) == 0; -} - -#else - -static inline int -drmDropMaster(int drm_fd) -{ - return 0; -} - -static inline int -drmSetMaster(int drm_fd) -{ - return 0; -} - -static inline int -is_drm_master(int drm_fd) -{ - return 0; -} - -#endif - -struct launcher_direct { - struct weston_launcher base; - struct weston_compositor *compositor; - int kb_mode, tty, drm_fd; - struct wl_event_source *vt_source; -}; - -static int -vt_handler(int signal_number, void *data) -{ - struct launcher_direct *launcher = data; - struct weston_compositor *compositor = launcher->compositor; - - if (compositor->session_active) { - compositor->session_active = false; - wl_signal_emit(&compositor->session_signal, compositor); - drmDropMaster(launcher->drm_fd); - ioctl(launcher->tty, VT_RELDISP, 1); - } else { - ioctl(launcher->tty, VT_RELDISP, VT_ACKACQ); - drmSetMaster(launcher->drm_fd); - compositor->session_active = true; - wl_signal_emit(&compositor->session_signal, compositor); - } - - return 1; -} - -static int -setup_tty(struct launcher_direct *launcher, int tty) -{ - struct wl_event_loop *loop; - struct vt_mode mode = { 0 }; - struct stat buf; - char tty_device[32] =""; - int ret, kd_mode; - - if (geteuid() != 0) - return -1; - - if (tty == 0) { - launcher->tty = dup(tty); - if (launcher->tty == -1) { - weston_log("couldn't dup stdin: %s\n", - strerror(errno)); - return -1; - } - } else { - snprintf(tty_device, sizeof tty_device, "/dev/tty%d", tty); - launcher->tty = open(tty_device, O_RDWR | O_CLOEXEC); - if (launcher->tty == -1) { - weston_log("couldn't open tty %s: %s\n", tty_device, - strerror(errno)); - return -1; - } - } - - if (fstat(launcher->tty, &buf) == -1 || - major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) { - weston_log("%s not a vt\n", tty_device); - weston_log("if running weston from ssh, " - "use --tty to specify a tty\n"); - goto err_close; - } - - ret = ioctl(launcher->tty, KDGETMODE, &kd_mode); - if (ret) { - weston_log("failed to get VT mode: %s\n", strerror(errno)); - return -1; - } - if (kd_mode != KD_TEXT) { - weston_log("%s is already in graphics mode, " - "is another display server running?\n", tty_device); - } - - ioctl(launcher->tty, VT_ACTIVATE, minor(buf.st_rdev)); - ioctl(launcher->tty, VT_WAITACTIVE, minor(buf.st_rdev)); - - if (ioctl(launcher->tty, KDGKBMODE, &launcher->kb_mode)) { - weston_log("failed to read keyboard mode: %s\n", - strerror(errno)); - goto err_close; - } - - if (ioctl(launcher->tty, KDSKBMUTE, 1) && - ioctl(launcher->tty, KDSKBMODE, K_OFF)) { - weston_log("failed to set K_OFF keyboard mode: %s\n", - strerror(errno)); - goto err_close; - } - - ret = ioctl(launcher->tty, KDSETMODE, KD_GRAPHICS); - if (ret) { - weston_log("failed to set KD_GRAPHICS mode on tty: %s\n", - strerror(errno)); - goto err_close; - } - - /* - * SIGRTMIN is used as global VT-acquire+release signal. Note that - * SIGRT* must be tested on runtime, as their exact values are not - * known at compile-time. POSIX requires 32 of them to be available. - */ - if (SIGRTMIN > SIGRTMAX) { - weston_log("not enough RT signals available: %u-%u\n", - SIGRTMIN, SIGRTMAX); - ret = -EINVAL; - goto err_close; - } - - mode.mode = VT_PROCESS; - mode.relsig = SIGRTMIN; - mode.acqsig = SIGRTMIN; - if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) { - weston_log("failed to take control of vt handling\n"); - goto err_close; - } - - loop = wl_display_get_event_loop(launcher->compositor->wl_display); - launcher->vt_source = - wl_event_loop_add_signal(loop, SIGRTMIN, vt_handler, launcher); - if (!launcher->vt_source) { - weston_log("failed to add SIGRTMIN signal\n"); - goto err_close; - } - - return 0; - - err_close: - close(launcher->tty); - return -1; -} - -static int -launcher_direct_open(struct weston_launcher *launcher_base, const char *path, int flags) -{ - struct launcher_direct *launcher = wl_container_of(launcher_base, launcher, base); - struct stat s; - int fd; - - fd = open(path, flags | O_CLOEXEC); - if (fd == -1) { - weston_log("couldn't open: %s! error=%s\n", path, strerror(errno)); - return -1; - } - - if (geteuid() != 0) { - weston_log("WARNING! Succeeded opening %s as non-root user." - " This implies your device can be spied on.\n", - path); - } - - if (fstat(fd, &s) == -1) { - weston_log("couldn't fstat: %s! error=%s\n", path, strerror(errno)); - close(fd); - return -1; - } - - if (major(s.st_rdev) == DRM_MAJOR) { - launcher->drm_fd = fd; - if (!is_drm_master(fd)) { - weston_log("drm fd not master\n"); - close(fd); - return -1; - } - } - - return fd; -} - -static void -launcher_direct_close(struct weston_launcher *launcher_base, int fd) -{ - close(fd); -} - -static void -launcher_direct_restore(struct weston_launcher *launcher_base) -{ - struct launcher_direct *launcher = wl_container_of(launcher_base, launcher, base); - struct vt_mode mode = { 0 }; - - if (ioctl(launcher->tty, KDSKBMUTE, 0) && - ioctl(launcher->tty, KDSKBMODE, launcher->kb_mode)) - weston_log("failed to restore kb mode: %s\n", - strerror(errno)); - - if (ioctl(launcher->tty, KDSETMODE, KD_TEXT)) - weston_log("failed to set KD_TEXT mode on tty: %s\n", - strerror(errno)); - - /* We have to drop master before we switch the VT back in - * VT_AUTO, so we don't risk switching to a VT with another - * display server, that will then fail to set drm master. */ - drmDropMaster(launcher->drm_fd); - - mode.mode = VT_AUTO; - if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) - weston_log("could not reset vt handling! error=%s\n", - strerror(errno)); -} - -static int -launcher_direct_activate_vt(struct weston_launcher *launcher_base, int vt) -{ - struct launcher_direct *launcher = wl_container_of(launcher_base, launcher, base); - return ioctl(launcher->tty, VT_ACTIVATE, vt); -} - -static int -launcher_direct_connect(struct weston_launcher **out, struct weston_compositor *compositor, - int tty, const char *seat_id, bool sync_drm) -{ - struct launcher_direct *launcher; - struct stat buf; - - launcher = zalloc(sizeof(*launcher)); - if (launcher == NULL) { - weston_log("failed to alloc for launcher\n"); - return -ENOMEM; - } - - launcher->base.iface = &launcher_direct_iface; - launcher->compositor = compositor; - - /* Checking the existance of /dev/tty0 and verifying it's a TTY - * device, as kernels compiled with CONFIG_VT=0 do not create these - * devices. */ - if (stat("/dev/tty0", &buf) == 0 && - strcmp("seat0", seat_id) == 0 && major(buf.st_rdev) == TTY_MAJOR) { - if (setup_tty(launcher, tty) == -1) { - free(launcher); - return -1; - } - } else { - launcher->tty = -1; - } - - * (struct launcher_direct **) out = launcher; - return 0; -} - -static void -launcher_direct_destroy(struct weston_launcher *launcher_base) -{ - struct launcher_direct *launcher = wl_container_of(launcher_base, launcher, base); - - if (launcher->tty >= 0) { - launcher_direct_restore(&launcher->base); - wl_event_source_remove(launcher->vt_source); - close(launcher->tty); - } - - free(launcher); -} - -static int -launcher_direct_get_vt(struct weston_launcher *base) -{ - struct launcher_direct *launcher = wl_container_of(base, launcher, base); - struct stat s; - if (fstat(launcher->tty, &s) < 0) { - weston_log("couldn't fstat launcher tty: %s\n", strerror(errno)); - return -1; - } - - return minor(s.st_rdev); -} - -const struct launcher_interface launcher_direct_iface = { - .name = "direct", - .connect = launcher_direct_connect, - .destroy = launcher_direct_destroy, - .open = launcher_direct_open, - .close = launcher_direct_close, - .activate_vt = launcher_direct_activate_vt, - .get_vt = launcher_direct_get_vt, -}; diff --git a/libweston/launcher-impl.h b/libweston/launcher-impl.h index 6bcbbc54..26038998 100644 --- a/libweston/launcher-impl.h +++ b/libweston/launcher-impl.h @@ -47,5 +47,3 @@ struct weston_launcher { extern const struct launcher_interface launcher_libseat_iface; extern const struct launcher_interface launcher_logind_iface; -extern const struct launcher_interface launcher_weston_launch_iface; -extern const struct launcher_interface launcher_direct_iface; diff --git a/libweston/launcher-util.c b/libweston/launcher-util.c index b2219b68..9f5ce243 100644 --- a/libweston/launcher-util.c +++ b/libweston/launcher-util.c @@ -43,8 +43,6 @@ static const struct launcher_interface *ifaces[] = { #ifdef HAVE_SYSTEMD_LOGIN &launcher_logind_iface, #endif - &launcher_weston_launch_iface, - &launcher_direct_iface, NULL, }; diff --git a/libweston/launcher-weston-launch.c b/libweston/launcher-weston-launch.c deleted file mode 100644 index 109ac486..00000000 --- a/libweston/launcher-weston-launch.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright © 2012 Benjamin Franzke - * Copyright © 2013 Intel Corporation - * - * 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 (including the - * next paragraph) 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 "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "weston-launch.h" -#include "launcher-impl.h" -#include "shared/string-helpers.h" - -#define DRM_MAJOR 226 - -#ifndef KDSKBMUTE -#define KDSKBMUTE 0x4B51 -#endif - -#ifdef BUILD_DRM_COMPOSITOR - -#include - -#else - -static inline int -drmDropMaster(int drm_fd) -{ - return 0; -} - -static inline int -drmSetMaster(int drm_fd) -{ - return 0; -} - -#endif - -/* major()/minor() */ -#ifdef MAJOR_IN_MKDEV -#include -#endif -#ifdef MAJOR_IN_SYSMACROS -#include -#endif - -union cmsg_data { unsigned char b[4]; int fd; }; - -struct launcher_weston_launch { - struct weston_launcher base; - struct weston_compositor *compositor; - int fd; - struct wl_event_source *source; - - int kb_mode, tty, drm_fd; - int deferred_deactivate; -}; - -static ssize_t -launcher_weston_launch_send(int sockfd, void *buf, size_t buflen) -{ - ssize_t len; - - do { - len = send(sockfd, buf, buflen, 0); - } while (len < 0 && errno == EINTR); - - return len; -} - -static void -handle_deactivate(struct launcher_weston_launch *launcher) -{ - int reply; - - launcher->compositor->session_active = false; - wl_signal_emit(&launcher->compositor->session_signal, - launcher->compositor); - - reply = WESTON_LAUNCHER_DEACTIVATE_DONE; - launcher_weston_launch_send(launcher->fd, &reply, sizeof reply); -} - -static void -idle_deactivate(void *data) -{ - struct launcher_weston_launch *launcher = data; - - if (launcher->deferred_deactivate) { - launcher->deferred_deactivate = 0; - handle_deactivate((struct launcher_weston_launch*)data); - } -} - -static int -launcher_weston_launch_open(struct weston_launcher *launcher_base, - const char *path, int flags) -{ - struct launcher_weston_launch *launcher = wl_container_of(launcher_base, launcher, base); - int n; - struct msghdr msg; - struct cmsghdr *cmsg; - struct iovec iov; - union cmsg_data *data; - char control[CMSG_SPACE(sizeof data->fd)]; - ssize_t len; - struct weston_launcher_open *message; - struct { int id; int ret; } event; - - n = sizeof(*message) + strlen(path) + 1; - message = malloc(n); - if (!message) - return -1; - - message->header.opcode = WESTON_LAUNCHER_OPEN; - message->flags = flags; - strcpy(message->path, path); - - launcher_weston_launch_send(launcher->fd, message, n); - free(message); - - memset(&msg, 0, sizeof msg); - iov.iov_base = &event; - iov.iov_len = sizeof event; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = control; - - while (1) { - msg.msg_controllen = sizeof control; - - do { - len = recvmsg(launcher->fd, &msg, MSG_CMSG_CLOEXEC); - } while (len < 0 && errno == EINTR); - - // Only OPEN_REPLY and up to one DEACTIVATE message should be possible here - if ((len == sizeof event) && (event.id == WESTON_LAUNCHER_OPEN_REPLY)) - break; - - if ((len == sizeof event.id) && (event.id == WESTON_LAUNCHER_DEACTIVATE) && (launcher->deferred_deactivate == 0)) { - wl_event_loop_add_idle(wl_display_get_event_loop(launcher->compositor->wl_display), idle_deactivate, launcher); - launcher->deferred_deactivate = 1; - } else { - weston_log("unexpected event %d (len=%zd) from weston-launch\n", event.id, len); - return -1; - } - } - - if (event.ret < 0) - return -1; - - cmsg = CMSG_FIRSTHDR(&msg); - if (!cmsg || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { - fprintf(stderr, "invalid control message\n"); - return -1; - } - - data = (union cmsg_data *) CMSG_DATA(cmsg); - if (data->fd == -1) { - fprintf(stderr, "missing drm fd in socket request\n"); - return -1; - } - - return data->fd; -} - -static void -launcher_weston_launch_close(struct weston_launcher *launcher_base, int fd) -{ - close(fd); -} - -static void -launcher_weston_launch_restore(struct weston_launcher *launcher_base) -{ - struct launcher_weston_launch *launcher = wl_container_of(launcher_base, launcher, base); - struct vt_mode mode = { 0 }; - - if (ioctl(launcher->tty, KDSKBMUTE, 0) && - ioctl(launcher->tty, KDSKBMODE, launcher->kb_mode)) - weston_log("failed to restore kb mode: %s\n", - strerror(errno)); - - if (ioctl(launcher->tty, KDSETMODE, KD_TEXT)) - weston_log("failed to set KD_TEXT mode on tty: %s\n", - strerror(errno)); - - /* We have to drop master before we switch the VT back in - * VT_AUTO, so we don't risk switching to a VT with another - * display server, that will then fail to set drm master. */ - drmDropMaster(launcher->drm_fd); - - mode.mode = VT_AUTO; - if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) - weston_log("could not reset vt handling\n"); -} - -static int -launcher_weston_launch_data(int fd, uint32_t mask, void *data) -{ - struct launcher_weston_launch *launcher = data; - int len, ret; - - if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) { - weston_log("launcher socket closed, exiting\n"); - /* Normally the weston-launch will reset the tty, but - * in this case it died or something, so do it here so - * we don't end up with a stuck vt. */ - launcher_weston_launch_restore(&launcher->base); - exit(-1); - } - - if (launcher->deferred_deactivate) { - launcher->deferred_deactivate = 0; - handle_deactivate(launcher); - return 1; - } - - do { - len = recv(launcher->fd, &ret, sizeof ret, 0); - } while (len < 0 && errno == EINTR); - - switch (ret) { - case WESTON_LAUNCHER_ACTIVATE: - launcher->compositor->session_active = true; - wl_signal_emit(&launcher->compositor->session_signal, - launcher->compositor); - break; - case WESTON_LAUNCHER_DEACTIVATE: - handle_deactivate(launcher); - break; - default: - weston_log("unexpected event from weston-launch\n"); - break; - } - - return 1; -} - -static int -launcher_weston_launch_activate_vt(struct weston_launcher *launcher_base, int vt) -{ - struct launcher_weston_launch *launcher = wl_container_of(launcher_base, launcher, base); - return ioctl(launcher->tty, VT_ACTIVATE, vt); -} - -static int -launcher_weston_environment_get_fd(const char *env) -{ - char *e; - int fd, flags; - - e = getenv(env); - if (!e || !safe_strtoint(e, &fd)) { - weston_log("could not get launcher fd from env\n"); - return -1; - } - - flags = fcntl(fd, F_GETFD); - if (flags == -1) { - weston_log("could not get fd flags!, env: %s, error: %s\n", - env, strerror(errno)); - return -1; - } - - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); - unsetenv(env); - - return fd; -} - - -static int -launcher_weston_launch_connect(struct weston_launcher **out, struct weston_compositor *compositor, - int tty, const char *seat_id, bool sync_drm) -{ - struct launcher_weston_launch *launcher; - struct wl_event_loop *loop; - - launcher = malloc(sizeof *launcher); - if (launcher == NULL) - return -ENOMEM; - - launcher->base.iface = &launcher_weston_launch_iface; - launcher->compositor = compositor; - launcher->drm_fd = -1; - launcher->deferred_deactivate = 0; - launcher->fd = launcher_weston_environment_get_fd("WESTON_LAUNCHER_SOCK"); - if (launcher->fd == -1) { - free(launcher); - return -1; - } - - launcher->tty = launcher_weston_environment_get_fd("WESTON_TTY_FD"); - /* We don't get a chance to read out the original kb - * mode for the tty, so just hard code K_UNICODE here - * in case we have to clean if weston-launch dies. */ - launcher->kb_mode = K_UNICODE; - - loop = wl_display_get_event_loop(compositor->wl_display); - launcher->source = wl_event_loop_add_fd(loop, launcher->fd, - WL_EVENT_READABLE, - launcher_weston_launch_data, - launcher); - if (launcher->source == NULL) { - free(launcher); - weston_log("failed to get weston-launcher socket fd event source\n"); - return -ENOMEM; - } - - * (struct launcher_weston_launch **) out = launcher; - - return 0; -} - -static void -launcher_weston_launch_destroy(struct weston_launcher *launcher_base) -{ - struct launcher_weston_launch *launcher = wl_container_of(launcher_base, launcher, base); - - if (launcher->fd != -1) { - close(launcher->fd); - wl_event_source_remove(launcher->source); - } else { - launcher_weston_launch_restore(&launcher->base); - } - - if (launcher->tty >= 0) - close(launcher->tty); - - free(launcher); -} - -static int -launcher_weston_launch_get_vt(struct weston_launcher *base) -{ - struct launcher_weston_launch *launcher = wl_container_of(base, launcher, base); - struct stat s; - if (fstat(launcher->tty, &s) < 0) { - weston_log("could not fstat launcher tty: %s\n", strerror(errno)); - return -1; - } - - return minor(s.st_rdev); -} - -const struct launcher_interface launcher_weston_launch_iface = { - .name = "weston_launch", - .connect = launcher_weston_launch_connect, - .destroy = launcher_weston_launch_destroy, - .open = launcher_weston_launch_open, - .close = launcher_weston_launch_close, - .activate_vt = launcher_weston_launch_activate_vt, - .get_vt = launcher_weston_launch_get_vt, -}; diff --git a/libweston/meson.build b/libweston/meson.build index e7afabbc..ca660e9a 100644 --- a/libweston/meson.build +++ b/libweston/meson.build @@ -143,9 +143,7 @@ pkgconfig.generate( ) srcs_session_helper = [ - 'launcher-direct.c', 'launcher-util.c', - 'launcher-weston-launch.c', ] deps_session_helper = [ dep_libweston_private_h ] @@ -222,25 +220,6 @@ dep_vertex_clipping = declare_dependency( include_directories: include_directories('.') ) -if get_option('deprecated-weston-launch') - warning('weston-launch is deprecated and will be removed in a future release. Please migrate to libseat and seatd-launch.') - dep_pam = cc.find_library('pam') - - if not cc.has_function('pam_open_session', dependencies: dep_pam) - error('pam_open_session not found for weston-launch') - endif - - executable( - 'weston-launch', - 'weston-launch.c', - dependencies: [dep_pam, systemd_dep, dep_libdrm], - include_directories: common_inc, - install: true - ) - - meson.add_install_script('echo', 'REMINDER: You are installing weston-launch, please make it setuid-root.') -endif - subdir('color-lcms') subdir('renderer-gl') subdir('backend-drm') diff --git a/libweston/weston-launch.c b/libweston/weston-launch.c deleted file mode 100644 index c43ed7b2..00000000 --- a/libweston/weston-launch.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * Copyright © 2012 Benjamin Franzke - * - * 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 (including the - * next paragraph) 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 "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifdef HAVE_SYSTEMD_LOGIN -#include -#endif - -#include "weston-launch.h" - -#define DRM_MAJOR 226 - -#ifndef KDSKBMUTE -#define KDSKBMUTE 0x4B51 -#endif - -#ifndef EVIOCREVOKE -#define EVIOCREVOKE _IOW('E', 0x91, int) -#endif - -#define MAX_ARGV_SIZE 256 - -#ifdef BUILD_DRM_COMPOSITOR - -#include - -#else - -static inline int -drmDropMaster(int drm_fd) -{ - return 0; -} - -static inline int -drmSetMaster(int drm_fd) -{ - return 0; -} - -#endif - -/* major()/minor() */ -#ifdef MAJOR_IN_MKDEV -# include -#endif -#ifdef MAJOR_IN_SYSMACROS -# include -#endif - -struct weston_launch { - struct pam_conv pc; - pam_handle_t *ph; - int tty; - int ttynr; - int sock[2]; - int drm_fd; - int last_input_fd; - int kb_mode; - struct passwd *pw; - - int signalfd; - - pid_t child; - int verbose; - char *new_user; -}; - -union cmsg_data { unsigned char b[4]; int fd; }; - -static gid_t * -read_groups(int *ngroups) -{ - int n; - gid_t *groups; - - n = getgroups(0, NULL); - - if (n < 0) { - fprintf(stderr, "Unable to retrieve groups: %s\n", - strerror(errno)); - return NULL; - } - - groups = malloc(n * sizeof(gid_t)); - if (!groups) - return NULL; - - if (getgroups(n, groups) < 0) { - fprintf(stderr, "Unable to retrieve groups: %s\n", - strerror(errno)); - free(groups); - return NULL; - } - - *ngroups = n; - return groups; -} - -static bool -weston_launch_allowed(struct weston_launch *wl) -{ - struct group *gr; - gid_t *groups; - int ngroups; -#ifdef HAVE_SYSTEMD_LOGIN - char *session, *seat; - int err; -#endif - - if (getuid() == 0) - return true; - - gr = getgrnam("weston-launch"); - if (gr) { - groups = read_groups(&ngroups); - if (groups && ngroups > 0) { - while (ngroups--) { - if (groups[ngroups] == gr->gr_gid) { - free(groups); - return true; - } - } - free(groups); - } - } - -#ifdef HAVE_SYSTEMD_LOGIN - err = sd_pid_get_session(getpid(), &session); - if (err == 0 && session) { - if (sd_session_is_active(session) && - sd_session_get_seat(session, &seat) == 0) { - free(seat); - free(session); - return true; - } - free(session); - } -#endif - - return false; -} - -static int -pam_conversation_fn(int msg_count, - const struct pam_message **messages, - struct pam_response **responses, - void *user_data) -{ - return PAM_SUCCESS; -} - -static int -setup_pam(struct weston_launch *wl) -{ - int err; - - wl->pc.conv = pam_conversation_fn; - wl->pc.appdata_ptr = wl; - - err = pam_start("login", wl->pw->pw_name, &wl->pc, &wl->ph); - if (err != PAM_SUCCESS) { - fprintf(stderr, "failed to start pam transaction: %d: %s\n", - err, pam_strerror(wl->ph, err)); - return -1; - } - - err = pam_set_item(wl->ph, PAM_TTY, ttyname(wl->tty)); - if (err != PAM_SUCCESS) { - fprintf(stderr, "failed to set PAM_TTY item: %d: %s\n", - err, pam_strerror(wl->ph, err)); - return -1; - } - - err = pam_open_session(wl->ph, 0); - if (err != PAM_SUCCESS) { - fprintf(stderr, "failed to open pam session: %d: %s\n", - err, pam_strerror(wl->ph, err)); - return -1; - } - - return 0; -} - -static int -setup_launcher_socket(struct weston_launch *wl) -{ - if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, wl->sock) < 0) { - fprintf(stderr, "weston: socketpair failed: %s\n", - strerror(errno)); - return -1; - } - - if (fcntl(wl->sock[0], F_SETFD, FD_CLOEXEC) < 0) { - fprintf(stderr, "weston: fcntl failed: %s\n", - strerror(errno)); - return -1; - } - - return 0; -} - -static int -setup_signals(struct weston_launch *wl) -{ - int ret; - sigset_t mask; - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_handler = SIG_DFL; - sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; - ret = sigaction(SIGCHLD, &sa, NULL); - assert(ret == 0); - - sa.sa_handler = SIG_IGN; - sa.sa_flags = 0; - sigaction(SIGHUP, &sa, NULL); - - ret = sigemptyset(&mask); - assert(ret == 0); - sigaddset(&mask, SIGCHLD); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGUSR1); - sigaddset(&mask, SIGUSR2); - ret = sigprocmask(SIG_BLOCK, &mask, NULL); - assert(ret == 0); - - wl->signalfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); - if (wl->signalfd < 0) - return -errno; - - return 0; -} - -static void -setenv_fd(const char *env, int fd) -{ - char buf[32]; - - snprintf(buf, sizeof buf, "%d", fd); - setenv(env, buf, 1); -} - -static int -open_tty_by_number(int ttynr) -{ - int ret; - char filename[16]; - - ret = snprintf(filename, sizeof filename, "/dev/tty%d", ttynr); - if (ret < 0) - return -1; - - return open(filename, O_RDWR | O_NOCTTY); -} - -static int -send_reply(struct weston_launch *wl, int reply) -{ - int len; - - do { - len = send(wl->sock[0], &reply, sizeof reply, 0); - } while (len < 0 && errno == EINTR); - - return len; -} - -static int -handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len) -{ - int fd = -1, ret = -1; - char control[CMSG_SPACE(sizeof(fd))]; - struct cmsghdr *cmsg; - struct stat s; - struct msghdr nmsg; - struct iovec iov; - struct weston_launcher_open *message; - union cmsg_data *data; - - message = msg->msg_iov->iov_base; - if ((size_t)len < sizeof(*message)) - goto err0; - - /* Ensure path is null-terminated */ - ((char *) message)[len-1] = '\0'; - - fd = open(message->path, message->flags); - if (fd < 0) { - fprintf(stderr, "Error opening device %s: %s\n", - message->path, strerror(errno)); - goto err0; - } - - if (fstat(fd, &s) < 0) { - close(fd); - fd = -1; - fprintf(stderr, "Failed to stat %s\n", message->path); - goto err0; - } - - if (major(s.st_rdev) != INPUT_MAJOR && - major(s.st_rdev) != DRM_MAJOR) { - close(fd); - fd = -1; - fprintf(stderr, "Device %s is not an input or drm device\n", - message->path); - goto err0; - } - -err0: - memset(&nmsg, 0, sizeof nmsg); - nmsg.msg_iov = &iov; - nmsg.msg_iovlen = 1; - if (fd != -1) { - nmsg.msg_control = control; - nmsg.msg_controllen = sizeof control; - cmsg = CMSG_FIRSTHDR(&nmsg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); - data = (union cmsg_data *) CMSG_DATA(cmsg); - data->fd = fd; - nmsg.msg_controllen = cmsg->cmsg_len; - ret = 0; - } - struct { int reply_id; int ret; } reply_iov_data = { WESTON_LAUNCHER_OPEN_REPLY, ret }; - iov.iov_base = &reply_iov_data; - iov.iov_len = sizeof reply_iov_data; - - if (wl->verbose) - fprintf(stderr, "weston-launch: opened %s: ret: %d, fd: %d\n", - message->path, ret, fd); - do { - len = sendmsg(wl->sock[0], &nmsg, 0); - } while (len < 0 && errno == EINTR); - - if (len < 0) - return -1; - - if (fd != -1 && major(s.st_rdev) == DRM_MAJOR) - wl->drm_fd = fd; - if (fd != -1 && major(s.st_rdev) == INPUT_MAJOR && - wl->last_input_fd < fd) - wl->last_input_fd = fd; - - return 0; -} - -static void -close_input_fds(struct weston_launch *wl) -{ - struct stat s; - int fd; - - for (fd = 3; fd <= wl->last_input_fd; fd++) { - if (fstat(fd, &s) == 0 && major(s.st_rdev) == INPUT_MAJOR) { - /* EVIOCREVOKE may fail if the kernel doesn't - * support it, but all we can do is ignore it. */ - ioctl(fd, EVIOCREVOKE, 0); - close(fd); - } - } -} - -static int -handle_socket_msg(struct weston_launch *wl) -{ - char control[CMSG_SPACE(sizeof(int))]; - char buf[BUFSIZ]; - struct msghdr msg; - struct iovec iov; - int ret = -1; - ssize_t len; - struct weston_launcher_message *message; - - memset(&msg, 0, sizeof(msg)); - iov.iov_base = buf; - iov.iov_len = sizeof buf; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = control; - msg.msg_controllen = sizeof control; - - do { - len = recvmsg(wl->sock[0], &msg, 0); - } while (len < 0 && errno == EINTR); - - if (len < 1) - return -1; - - message = (void *) buf; - switch (message->opcode) { - case WESTON_LAUNCHER_OPEN: - ret = handle_open(wl, &msg, len); - break; - case WESTON_LAUNCHER_DEACTIVATE_DONE: - close_input_fds(wl); - drmDropMaster(wl->drm_fd); - ioctl(wl->tty, VT_RELDISP, 1); - break; - } - - return ret; -} - -static void -quit(struct weston_launch *wl, int status) -{ - struct vt_mode mode = { 0 }; - int err; - int oldtty; - - close(wl->signalfd); - close(wl->sock[0]); - - if (wl->new_user) { - err = pam_close_session(wl->ph, 0); - if (err) - fprintf(stderr, "pam_close_session failed: %d: %s\n", - err, pam_strerror(wl->ph, err)); - pam_end(wl->ph, err); - } - - /* - * Get a fresh handle to the tty as the previous one is in - * hang-up state since weston (the controlling process for - * the tty) exit at this point. Reopen before closing the - * file descriptor to avoid a potential race condition. - * - * A similar fix exists in logind, see: - * https://github.com/systemd/systemd/pull/990 - */ - oldtty = wl->tty; - wl->tty = open_tty_by_number(wl->ttynr); - close(oldtty); - - if (ioctl(wl->tty, KDSKBMUTE, 0) && - ioctl(wl->tty, KDSKBMODE, wl->kb_mode)) - fprintf(stderr, "failed to restore keyboard mode: %s\n", - strerror(errno)); - - if (ioctl(wl->tty, KDSETMODE, KD_TEXT)) - fprintf(stderr, "failed to set KD_TEXT mode on tty: %s\n", - strerror(errno)); - - /* We have to drop master before we switch the VT back in - * VT_AUTO, so we don't risk switching to a VT with another - * display server, that will then fail to set drm master. */ - drmDropMaster(wl->drm_fd); - - mode.mode = VT_AUTO; - if (ioctl(wl->tty, VT_SETMODE, &mode) < 0) - fprintf(stderr, "could not reset vt handling\n"); - - if (wl->tty != STDIN_FILENO) - close(wl->tty); - - exit(status); -} - -static int -handle_signal(struct weston_launch *wl) -{ - struct signalfd_siginfo sig; - int pid, status, ret; - - if (read(wl->signalfd, &sig, sizeof sig) != sizeof sig) { - fprintf(stderr, "weston: reading signalfd failed: %s\n", - strerror(errno)); - return -1; - } - - switch (sig.ssi_signo) { - case SIGCHLD: - pid = waitpid(-1, &status, 0); - if (pid == wl->child) { - wl->child = 0; - if (WIFEXITED(status)) - ret = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - /* - * If weston dies because of signal N, we - * return 10+N. This is distinct from - * weston-launch dying because of a signal - * (128+N). - */ - ret = 10 + WTERMSIG(status); - else - ret = 0; - quit(wl, ret); - } - break; - case SIGTERM: - case SIGINT: - if (!wl->child) - break; - - if (wl->verbose) - fprintf(stderr, "weston-launch: sending %s to pid %d\n", - strsignal(sig.ssi_signo), wl->child); - - kill(wl->child, sig.ssi_signo); - break; - case SIGUSR1: - send_reply(wl, WESTON_LAUNCHER_DEACTIVATE); - break; - case SIGUSR2: - ioctl(wl->tty, VT_RELDISP, VT_ACKACQ); - drmSetMaster(wl->drm_fd); - send_reply(wl, WESTON_LAUNCHER_ACTIVATE); - break; - default: - return -1; - } - - return 0; -} - -static int -setup_tty(struct weston_launch *wl, const char *tty) -{ - struct stat buf; - struct vt_mode mode = { 0 }; - char *t; - - if (!wl->new_user) { - wl->tty = STDIN_FILENO; - } else if (tty) { - t = ttyname(STDIN_FILENO); - if (t && strcmp(t, tty) == 0) - wl->tty = STDIN_FILENO; - else - wl->tty = open(tty, O_RDWR | O_NOCTTY); - } else { - int tty0 = open("/dev/tty0", O_WRONLY | O_CLOEXEC); - - if (tty0 < 0) { - fprintf(stderr, "weston: could not open tty0: %s\n", - strerror(errno)); - return -1; - } - - if (ioctl(tty0, VT_OPENQRY, &wl->ttynr) < 0 || wl->ttynr == -1) - { - fprintf(stderr, "weston: failed to find non-opened console: %s\n", - strerror(errno)); - return -1; - } - - wl->tty = open_tty_by_number(wl->ttynr); - close(tty0); - } - - if (wl->tty < 0) { - fprintf(stderr, "weston: failed to open tty: %s\n", - strerror(errno)); - return -1; - } - - if (fstat(wl->tty, &buf) == -1 || - major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) { - fprintf(stderr, "weston: weston-launch must be run from a virtual terminal\n"); - return -1; - } - - if (!wl->new_user || tty) { - if (fstat(wl->tty, &buf) < 0) { - fprintf(stderr, "weston: stat %s failed: %s\n", tty, - strerror(errno)); - return -1; - } - - if (major(buf.st_rdev) != TTY_MAJOR) { - fprintf(stderr, - "weston: invalid tty device: %s\n", tty); - return -1; - } - - wl->ttynr = minor(buf.st_rdev); - } - - if (ioctl(wl->tty, VT_ACTIVATE, wl->ttynr) < 0) { - fprintf(stderr, - "weston: failed to activate VT: %s\n", - strerror(errno)); - return -1; - } - - if (ioctl(wl->tty, VT_WAITACTIVE, wl->ttynr) < 0) { - fprintf(stderr, - "weston: failed to wait for VT to be active: %s\n", - strerror(errno)); - return -1; - } - - if (ioctl(wl->tty, KDGKBMODE, &wl->kb_mode)) { - fprintf(stderr, - "weston: failed to get current keyboard mode: %s\n", - strerror(errno)); - return -1; - } - - if (ioctl(wl->tty, KDSKBMUTE, 1) && - ioctl(wl->tty, KDSKBMODE, K_OFF)) { - fprintf(stderr, - "weston: failed to set K_OFF keyboard mode: %s\n", - strerror(errno)); - return -1; - } - - if (ioctl(wl->tty, KDSETMODE, KD_GRAPHICS)) { - fprintf(stderr, - "weston: failed to set KD_GRAPHICS mode on tty: %s\n", - strerror(errno)); - return -1; - } - - mode.mode = VT_PROCESS; - mode.relsig = SIGUSR1; - mode.acqsig = SIGUSR2; - if (ioctl(wl->tty, VT_SETMODE, &mode) < 0) { - fprintf(stderr, - "weston: failed to take control of vt handling %s\n", - strerror(errno)); - return -1; - } - - return 0; -} - -static int -setup_session(struct weston_launch *wl, char **child_argv) -{ - char **env; - char *term; - int i; - - if (wl->tty != STDIN_FILENO) { - if (setsid() < 0) { - fprintf(stderr, "weston: setsid failed %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - if (ioctl(wl->tty, TIOCSCTTY, 0) < 0) { - fprintf(stderr, "TIOCSCTTY failed - tty is in use %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - } - - term = getenv("TERM"); - clearenv(); - if (term) - setenv("TERM", term, 1); - setenv("USER", wl->pw->pw_name, 1); - setenv("LOGNAME", wl->pw->pw_name, 1); - setenv("HOME", wl->pw->pw_dir, 1); - setenv("SHELL", wl->pw->pw_shell, 1); - - env = pam_getenvlist(wl->ph); - if (env) { - for (i = 0; env[i]; ++i) { - if (putenv(env[i]) != 0) - fprintf(stderr, "putenv %s failed\n", env[i]); - } - free(env); - } - - /* - * We open a new session, so it makes sense - * to run a new login shell - */ - child_argv[0] = "/bin/sh"; - child_argv[1] = "-l"; - child_argv[2] = "-c"; - child_argv[3] = "exec " BINDIR "/weston \"$@\""; - child_argv[4] = "weston"; - return 5; -} - -static void -drop_privileges(struct weston_launch *wl) -{ - if (setgid(wl->pw->pw_gid) < 0 || -#ifdef HAVE_INITGROUPS - initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 || -#endif - setuid(wl->pw->pw_uid) < 0) { - fprintf(stderr, "weston: dropping privileges failed %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } -} - -static void -launch_compositor(struct weston_launch *wl, int argc, char *argv[]) -{ - char *child_argv[MAX_ARGV_SIZE]; - sigset_t mask; - int o, i; - - if (wl->verbose) - printf("weston-launch: spawned weston with pid: %d\n", getpid()); - if (wl->new_user) { - o = setup_session(wl, child_argv); - } else { - child_argv[0] = BINDIR "/weston"; - o = 1; - } - for (i = 0; i < argc; ++i) - child_argv[o + i] = argv[i]; - child_argv[o + i] = NULL; - - if (geteuid() == 0) - drop_privileges(wl); - - setenv_fd("WESTON_TTY_FD", wl->tty); - setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]); - - unsetenv("DISPLAY"); - - /* Do not give our signal mask to the new process. */ - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGCHLD); - sigaddset(&mask, SIGINT); - sigprocmask(SIG_UNBLOCK, &mask, NULL); - - - execv(child_argv[0], child_argv); - fprintf(stderr, "weston: exec failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); -} - -static void -help(const char *name) -{ - fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name); - fprintf(stderr, " -u, --user Start session as specified username,\n" - " e.g. -u joe, requires root.\n"); - fprintf(stderr, " -t, --tty Start session on alternative tty,\n" - " e.g. -t /dev/tty4, requires -u option.\n"); - fprintf(stderr, " -v, --verbose Be verbose\n"); - fprintf(stderr, " -h, --help Display this help message\n"); -} - -int -main(int argc, char *argv[]) -{ - struct weston_launch wl; - int i, c; - char *tty = NULL; - struct option opts[] = { - { "user", required_argument, NULL, 'u' }, - { "tty", required_argument, NULL, 't' }, - { "verbose", no_argument, NULL, 'v' }, - { "help", no_argument, NULL, 'h' }, - { 0, 0, NULL, 0 } - }; - - memset(&wl, 0, sizeof wl); - - while ((c = getopt_long(argc, argv, "u:t:vh", opts, &i)) != -1) { - switch (c) { - case 'u': - wl.new_user = optarg; - if (getuid() != 0) { - fprintf(stderr, "weston: Permission denied. -u allowed for root only\n"); - exit(EXIT_FAILURE); - } - break; - case 't': - tty = optarg; - break; - case 'v': - wl.verbose = 1; - break; - case 'h': - help("weston-launch"); - exit(EXIT_FAILURE); - default: - exit(EXIT_FAILURE); - } - } - - if ((argc - optind) > (MAX_ARGV_SIZE - 6)) { - fprintf(stderr, - "weston: Too many arguments to pass to weston: %s\n", - strerror(E2BIG)); - exit(EXIT_FAILURE); - } - - if (tty && !wl.new_user) { - fprintf(stderr, "weston: -t/--tty option requires -u/--user option as well\n"); - exit(EXIT_FAILURE); - } - - if (wl.new_user) - wl.pw = getpwnam(wl.new_user); - else - wl.pw = getpwuid(getuid()); - if (wl.pw == NULL) { - fprintf(stderr, "weston: failed to get username: %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - - if (!weston_launch_allowed(&wl)) { - fprintf(stderr, "Permission denied. You should either:\n" -#ifdef HAVE_SYSTEMD_LOGIN - " - run from an active and local (systemd) session.\n" -#else - " - enable systemd session support for weston-launch.\n" -#endif - " - or add yourself to the 'weston-launch' group.\n"); - exit(EXIT_FAILURE); - } - - if (setup_tty(&wl, tty) < 0) - exit(EXIT_FAILURE); - - if (wl.new_user && setup_pam(&wl) < 0) - exit(EXIT_FAILURE); - - if (setup_launcher_socket(&wl) < 0) - exit(EXIT_FAILURE); - - if (setup_signals(&wl) < 0) - exit(EXIT_FAILURE); - - wl.child = fork(); - if (wl.child == -1) { - fprintf(stderr, "weston: fork failed %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - if (wl.child == 0) - launch_compositor(&wl, argc - optind, argv + optind); - - close(wl.sock[1]); - - while (1) { - struct pollfd fds[2]; - int n; - - fds[0].fd = wl.sock[0]; - fds[0].events = POLLIN; - fds[1].fd = wl.signalfd; - fds[1].events = POLLIN; - - n = poll(fds, 2, -1); - if (n < 0) { - fprintf(stderr, "poll failed: %s\n", strerror(errno)); - return -1; - } - if (fds[0].revents & POLLIN) - handle_socket_msg(&wl); - if (fds[1].revents) - handle_signal(&wl); - } - - return 0; -} diff --git a/libweston/weston-launch.h b/libweston/weston-launch.h deleted file mode 100644 index 72954019..00000000 --- a/libweston/weston-launch.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright © 2012 Benjamin Franzke - * - * 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 (including the - * next paragraph) 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. - */ - -#ifndef _WESTON_LAUNCH_H_ -#define _WESTON_LAUNCH_H_ - -enum weston_launcher_opcode { - WESTON_LAUNCHER_OPEN, -}; - -enum weston_launcher_event { - WESTON_LAUNCHER_ACTIVATE, - WESTON_LAUNCHER_DEACTIVATE, - WESTON_LAUNCHER_DEACTIVATE_DONE, - // This event is followed by an fd handle - WESTON_LAUNCHER_OPEN_REPLY, -}; - -struct weston_launcher_message { - int opcode; -}; - -struct weston_launcher_open { - struct weston_launcher_message header; - int flags; - char path[0]; -}; - -#endif diff --git a/man/weston-bindings.man b/man/weston-bindings.man index fac38be0..2e47ccc9 100644 --- a/man/weston-bindings.man +++ b/man/weston-bindings.man @@ -165,7 +165,6 @@ Enable repaint debugging for pixman: .SH "SEE ALSO" .BR weston (1), -.BR weston-launch (1), .BR weston-drm (7), .BR weston.ini (5), .BR xkeyboard-config (7) diff --git a/man/weston-drm.man b/man/weston-drm.man index 01a336e1..ced4f106 100644 --- a/man/weston-drm.man +++ b/man/weston-drm.man @@ -2,8 +2,6 @@ .SH NAME weston-drm \- the DRM backend for Weston .SH SYNOPSIS -.B weston-launch -.LP .B weston --backend=drm-backend.so . .\" *************************************************************** @@ -33,19 +31,6 @@ the first DRM device returned by .BR udev (7). Combining multiple graphics devices is not supported yet. -The DRM backend relies on -.B weston-launch -for managing input device access and DRM master status, so that -.B weston -can be run without root privileges. On switching away from the -virtual terminal (VT) hosting Weston, all input devices are closed and -the DRM master capability is dropped, so that other servers, -including -.BR Xorg (1), -can run on other VTs. On switching back to Weston's VT, input devices -and DRM master are re-acquired through the parent process -.BR weston-launch . - The DRM backend also supports virtual outputs that are transmitted over an RTP session as a series of JPEG images (RTP payload type 26) to a remote client. Virtual outputs are configured in the @@ -218,23 +203,10 @@ The minimum libinput verbosity level to be printed to Weston's log. Valid values are .BR debug ", " info ", and " error ". Default is " info . .TP -.B WESTON_TTY_FD -The file descriptor (integer) of the opened tty where -.B weston -will run. Set by -.BR weston-launch . -.TP -.B WESTON_LAUNCHER_SOCK -The file descriptor (integer) where -.B weston-launch -is listening. Automatically set by -.BR weston-launch . -.TP .B XDG_SEAT The seat Weston will start on, unless overridden on the command line. . .\" *************************************************************** .SH "SEE ALSO" .BR weston (1) -.\".BR weston-launch (1), .\".BR weston.ini (5) diff --git a/man/weston.ini.man b/man/weston.ini.man index 9f97a90c..98403e48 100644 --- a/man/weston.ini.man +++ b/man/weston.ini.man @@ -482,10 +482,7 @@ currently only recognized by the drm and x11 backends. .BI "name=" name sets a name for the output (string). The backend uses the name to identify the output. All X11 output names start with a letter X. All -Wayland output names start with the letters WL. The available -output names for DRM backend are listed in the -.B "weston-launch(1)" -output. +Wayland output names start with the letters WL. Examples of usage: .PP .RS 10 diff --git a/man/weston.man b/man/weston.man index c453a7d3..584bfb5a 100644 --- a/man/weston.man +++ b/man/weston.man @@ -17,14 +17,6 @@ Weston supports fundamentally different graphical user interface paradigms via shell plugins. Two plugins are provided: the desktop shell, and the tablet shell. -When weston is started as the first windowing system (i.e. not under X nor -under another Wayland server), it should be done with the command -.B weston-launch -to set up proper privileged access to devices. If your system supports -the logind D-Bus API and the support has been built into weston as well, -it is possible to start weston with just -.BR weston . - Weston also supports X clients via .BR XWayland ", see below." . @@ -361,9 +353,9 @@ http://wayland.freedesktop.org/ .\" *************************************************************** .SH EXAMPLES .IP "Launch Weston with the DRM backend on a VT" -weston-launch +weston .IP "Launch Weston with the DRM backend and XWayland support" -weston-launch -- --xwayland +weston --xwayland .IP "Launch Weston (wayland-1) nested in another Weston instance (wayland-0)" WAYLAND_DISPLAY=wayland-0 weston -Swayland-1 .IP "From an X terminal, launch Weston with the x11 backend" diff --git a/meson.build b/meson.build index d761903e..210bfa39 100644 --- a/meson.build +++ b/meson.build @@ -27,6 +27,10 @@ else error('Bad versions in meson.build: libweston_major is too low') endif +if not (get_option('launcher-logind') or get_option('launcher-libseat')) + error('At least one launcher must be enabled') +endif + dir_prefix = get_option('prefix') dir_bin = join_paths(dir_prefix, get_option('bindir')) dir_data = join_paths(dir_prefix, get_option('datadir')) diff --git a/meson_options.txt b/meson_options.txt index 8a527d74..453715cb 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -65,13 +65,6 @@ option( description: 'Weston renderer: EGL / OpenGL ES 2.x' ) -option( - 'deprecated-weston-launch', - type: 'boolean', - value: false, - description: 'Deprecated weston launcher for systems without logind' -) - option( 'xwayland', type: 'boolean',