/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include "sd-device.h"
#include "sd-daemon.h"

#include "alloc-util.h"
#include "bus-util.h"
#include "daemon-util.h"
#include "fd-util.h"
#include "logind-session-dbus.h"
#include "logind-session-device.h"
#include "missing_drm.h"
#include "missing_input.h"
#include "parse-util.h"

enum SessionDeviceNotifications {
        SESSION_DEVICE_RESUME,
        SESSION_DEVICE_TRY_PAUSE,
        SESSION_DEVICE_PAUSE,
        SESSION_DEVICE_RELEASE,
};

static int session_device_notify(SessionDevice *sd, enum SessionDeviceNotifications type) {
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
        _cleanup_free_ char *path = NULL;
        const char *t = NULL;
        uint32_t major, minor;
        int r;

        assert(sd);

        major = major(sd->dev);
        minor = minor(sd->dev);

        if (!sd->session->controller)
                return 0;

        path = session_bus_path(sd->session);
        if (!path)
                return -ENOMEM;

        r = sd_bus_message_new_signal(
                        sd->session->manager->bus,
                        &m, path,
                        "org.freedesktop.login1.Session",
                        type == SESSION_DEVICE_RESUME ? "ResumeDevice" : "PauseDevice");
        if (!m)
                return r;

        r = sd_bus_message_set_destination(m, sd->session->controller);
        if (r < 0)
                return r;

        switch (type) {

        case SESSION_DEVICE_RESUME:
                r = sd_bus_message_append(m, "uuh", major, minor, sd->fd);
                if (r < 0)
                        return r;
                break;

        case SESSION_DEVICE_TRY_PAUSE:
                t = "pause";
                break;

        case SESSION_DEVICE_PAUSE:
                t = "force";
                break;

        case SESSION_DEVICE_RELEASE:
                t = "gone";
                break;

        default:
                return -EINVAL;
        }

        if (t) {
                r = sd_bus_message_append(m, "uus", major, minor, t);
                if (r < 0)
                        return r;
        }

        return sd_bus_send(sd->session->manager->bus, m, NULL);
}

static void sd_eviocrevoke(int fd) {
        static bool warned = false;

        assert(fd >= 0);

        if (ioctl(fd, EVIOCREVOKE, NULL) < 0) {

                if (errno == EINVAL && !warned) {
                        log_warning_errno(errno, "Kernel does not support evdev-revocation: %m");
                        warned = true;
                }
        }
}

static int sd_drmsetmaster(int fd) {
        assert(fd >= 0);
        return RET_NERRNO(ioctl(fd, DRM_IOCTL_SET_MASTER, 0));
}

static int sd_drmdropmaster(int fd) {
        assert(fd >= 0);
        return RET_NERRNO(ioctl(fd, DRM_IOCTL_DROP_MASTER, 0));
}

static int session_device_open(SessionDevice *sd, bool active) {
        int fd, r;

        assert(sd);
        assert(sd->type != DEVICE_TYPE_UNKNOWN);
        assert(sd->node);

        /* open device and try to get a udev_device from it */
        fd = open(sd->node, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
        if (fd < 0)
                return -errno;

        switch (sd->type) {

        case DEVICE_TYPE_DRM:
                if (active) {
                        /* Weird legacy DRM semantics might return an error even though we're master. No way to detect
                         * that so fail at all times and let caller retry in inactive state. */
                        r = sd_drmsetmaster(fd);
                        if (r < 0) {
                                (void) close_nointr(fd);
                                return r;
                        }
                } else
                        /* DRM-Master is granted to the first user who opens a device automatically (ughh,
                         * racy!). Hence, we just drop DRM-Master in case we were the first. */
                        (void) sd_drmdropmaster(fd);
                break;

        case DEVICE_TYPE_EVDEV:
                if (!active)
                        sd_eviocrevoke(fd);
                break;

        case DEVICE_TYPE_UNKNOWN:
        default:
                /* fallback for devices without synchronizations */
                break;
        }

        return fd;
}

static int session_device_start(SessionDevice *sd) {
        int r;

        assert(sd);
        assert(session_is_active(sd->session));

        if (sd->active)
                return 0;

        switch (sd->type) {

        case DEVICE_TYPE_DRM:
                if (sd->fd < 0)
                        return log_error_errno(SYNTHETIC_ERRNO(EBADF),
                                               "Failed to re-activate DRM fd, as the fd was lost (maybe logind restart went wrong?)");

                /* Device is kept open. Simply call drmSetMaster() and hope there is no-one else. In case it fails, we
                 * keep the device paused. Maybe at some point we have a drmStealMaster(). */
                r = sd_drmsetmaster(sd->fd);
                if (r < 0)
                        return r;
                break;

        case DEVICE_TYPE_EVDEV:
                /* Evdev devices are revoked while inactive. Reopen it and we are fine. */
                r = session_device_open(sd, true);
                if (r < 0)
                        return r;

                /* For evdev devices, the file descriptor might be left uninitialized. This might happen while resuming
                 * into a session and logind has been restarted right before. */
                close_and_replace(sd->fd, r);
                break;

        case DEVICE_TYPE_UNKNOWN:
        default:
                /* fallback for devices without synchronizations */
                break;
        }

        sd->active = true;
        return 0;
}

static void session_device_stop(SessionDevice *sd) {
        assert(sd);

        if (!sd->active)
                return;

        switch (sd->type) {

        case DEVICE_TYPE_DRM:
                if (sd->fd < 0) {
                        log_error("Failed to de-activate DRM fd, as the fd was lost (maybe logind restart went wrong?)");
                        return;
                }

                /* On DRM devices we simply drop DRM-Master but keep it open.
                 * This allows the user to keep resources allocated. The
                 * CAP_SYS_ADMIN restriction to DRM-Master prevents users from
                 * circumventing this. */
                sd_drmdropmaster(sd->fd);
                break;

        case DEVICE_TYPE_EVDEV:
                /* Revoke access on evdev file-descriptors during deactivation.
                 * This will basically prevent any operations on the fd and
                 * cannot be undone. Good side is: it needs no CAP_SYS_ADMIN
                 * protection this way. */
                sd_eviocrevoke(sd->fd);
                break;

        case DEVICE_TYPE_UNKNOWN:
        default:
                /* fallback for devices without synchronization */
                break;
        }

        sd->active = false;
}

static DeviceType detect_device_type(sd_device *dev) {
        const char *sysname, *subsystem;
        DeviceType type = DEVICE_TYPE_UNKNOWN;

        if (sd_device_get_sysname(dev, &sysname) < 0 ||
            sd_device_get_subsystem(dev, &subsystem) < 0)
                return type;

        if (streq(subsystem, "drm")) {
                if (startswith(sysname, "card"))
                        type = DEVICE_TYPE_DRM;
        } else if (streq(subsystem, "input")) {
                if (startswith(sysname, "event"))
                        type = DEVICE_TYPE_EVDEV;
        }

        return type;
}

static int session_device_verify(SessionDevice *sd) {
        _cleanup_(sd_device_unrefp) sd_device *p = NULL;
        const char *sp, *node;
        sd_device *dev;
        int r;

        r = sd_device_new_from_devnum(&p, 'c', sd->dev);
        if (r < 0)
                return r;

        dev = p;

        if (sd_device_get_syspath(dev, &sp) < 0 ||
            sd_device_get_devname(dev, &node) < 0)
                return -EINVAL;

        /* detect device type so we can find the correct sysfs parent */
        sd->type = detect_device_type(dev);
        if (sd->type == DEVICE_TYPE_UNKNOWN)
                return -ENODEV;

        else if (sd->type == DEVICE_TYPE_EVDEV) {
                /* for evdev devices we need the parent node as device */
                if (sd_device_get_parent_with_subsystem_devtype(p, "input", NULL, &dev) < 0)
                        return -ENODEV;
                if (sd_device_get_syspath(dev, &sp) < 0)
                        return -ENODEV;

        } else if (sd->type != DEVICE_TYPE_DRM)
                /* Prevent opening unsupported devices. Especially devices of
                 * subsystem "input" must be opened via the evdev node as
                 * we require EVIOCREVOKE. */
                return -ENODEV;

        /* search for an existing seat device and return it if available */
        sd->device = hashmap_get(sd->session->manager->devices, sp);
        if (!sd->device) {
                /* The caller might have gotten the udev event before we were
                 * able to process it. Hence, fake the "add" event and let the
                 * logind-manager handle the new device. */
                r = manager_process_seat_device(sd->session->manager, dev);
                if (r < 0)
                        return r;

                /* if it's still not available, then the device is invalid */
                sd->device = hashmap_get(sd->session->manager->devices, sp);
                if (!sd->device)
                        return -ENODEV;
        }

        if (sd->device->seat != sd->session->seat)
                return -EPERM;

        sd->node = strdup(node);
        if (!sd->node)
                return -ENOMEM;

        return 0;
}

int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **out) {
        SessionDevice *sd;
        int r;

        assert(s);
        assert(out);

        if (!s->seat)
                return -EPERM;

        sd = new0(SessionDevice, 1);
        if (!sd)
                return -ENOMEM;

        sd->session = s;
        sd->dev = dev;
        sd->fd = -EBADF;
        sd->type = DEVICE_TYPE_UNKNOWN;

        r = session_device_verify(sd);
        if (r < 0)
                goto error;

        r = hashmap_put(s->devices, &sd->dev, sd);
        if (r < 0)
                goto error;

        if (open_device) {
                /* Open the device for the first time. We need a valid fd to pass back
                 * to the caller. If the session is not active, this _might_ immediately
                 * revoke access and thus invalidate the fd. But this is still needed
                 * to pass a valid fd back. */
                sd->active = session_is_active(s);
                r = session_device_open(sd, sd->active);
                if (r < 0) {
                        /* EINVAL _may_ mean a master is active; retry inactive */
                        if (sd->active && r == -EINVAL) {
                                sd->active = false;
                                r = session_device_open(sd, false);
                        }
                        if (r < 0)
                                goto error;
                }
                sd->fd = r;
        }

        LIST_PREPEND(sd_by_device, sd->device->session_devices, sd);

        *out = sd;
        return 0;

error:
        hashmap_remove(s->devices, &sd->dev);
        free(sd->node);
        free(sd);
        return r;
}

void session_device_free(SessionDevice *sd) {
        assert(sd);

        /* Make sure to remove the pushed fd. */
        if (sd->pushed_fd)
                (void) notify_remove_fd_warnf("session-%s-device-%u-%u", sd->session->id, major(sd->dev), minor(sd->dev));

        session_device_stop(sd);
        session_device_notify(sd, SESSION_DEVICE_RELEASE);
        safe_close(sd->fd);

        LIST_REMOVE(sd_by_device, sd->device->session_devices, sd);

        hashmap_remove(sd->session->devices, &sd->dev);

        free(sd->node);
        free(sd);
}

void session_device_complete_pause(SessionDevice *sd) {
        SessionDevice *iter;

        if (!sd->active)
                return;

        session_device_stop(sd);

        /* if not all devices are paused, wait for further completion events */
        HASHMAP_FOREACH(iter, sd->session->devices)
                if (iter->active)
                        return;

        /* complete any pending session switch */
        seat_complete_switch(sd->session->seat);
}

void session_device_resume_all(Session *s) {
        SessionDevice *sd;

        assert(s);

        HASHMAP_FOREACH(sd, s->devices) {
                if (sd->active)
                        continue;

                if (session_device_start(sd) < 0)
                        continue;
                if (session_device_save(sd) < 0)
                        continue;

                session_device_notify(sd, SESSION_DEVICE_RESUME);
        }
}

void session_device_pause_all(Session *s) {
        SessionDevice *sd;

        assert(s);

        HASHMAP_FOREACH(sd, s->devices) {
                if (!sd->active)
                        continue;

                session_device_stop(sd);
                session_device_notify(sd, SESSION_DEVICE_PAUSE);
        }
}

unsigned session_device_try_pause_all(Session *s) {
        unsigned num_pending = 0;
        SessionDevice *sd;

        assert(s);

        HASHMAP_FOREACH(sd, s->devices) {
                if (!sd->active)
                        continue;

                session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE);
                num_pending++;
        }

        return num_pending;
}

int session_device_save(SessionDevice *sd) {
        const char *id;
        int r;

        assert(sd);

        /* Store device fd in PID1. It will send it back to us on restart so revocation will continue to work. To make
         * things simple, send fds for all type of devices even if they don't support the revocation mechanism so we
         * don't have to handle them differently later.
         *
         * Note: for device supporting revocation, PID1 will drop a stored fd automatically if the corresponding device
         * is revoked. */

        if (sd->pushed_fd)
                return 0;

        /* Session ID does not contain separators. */
        id = sd->session->id;
        assert(*(id + strcspn(id, "-\n")) == '\0');

        r = notify_push_fdf(sd->fd, "session-%s-device-%u-%u", id, major(sd->dev), minor(sd->dev));
        if (r < 0)
                return r;

        sd->pushed_fd = true;
        return 1;
}

void session_device_attach_fd(SessionDevice *sd, int fd, bool active) {
        assert(fd >= 0);
        assert(sd);
        assert(sd->fd < 0);
        assert(!sd->active);

        sd->fd = fd;
        sd->pushed_fd = true;
        sd->active = active;
}
