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

#include <malloc.h>

#include "alloc-util.h"
#include "audit-type.h"
#include "errno-util.h"
#include "fd-util.h"
#include "hexdecoct.h"
#include "io-util.h"
#include "journald-audit.h"
#include "missing_audit.h"
#include "string-util.h"

typedef struct MapField {
        const char *audit_field;
        const char *journal_field;
        int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov);
} MapField;

static int map_simple_field(
                const char *field,
                const char **p,
                struct iovec **iov,
                size_t *n_iov) {

        _cleanup_free_ char *c = NULL;
        size_t l = 0;
        const char *e;

        assert(field);
        assert(p);
        assert(iov);
        assert(n_iov);

        l = strlen(field);
        c = malloc(l + 1);
        if (!c)
                return -ENOMEM;

        memcpy(c, field, l);
        for (e = *p; !IN_SET(*e, 0, ' '); e++) {
                if (!GREEDY_REALLOC(c, l+2))
                        return -ENOMEM;

                c[l++] = *e;
        }

        c[l] = 0;

        if (!GREEDY_REALLOC(*iov, *n_iov + 1))
                return -ENOMEM;

        (*iov)[(*n_iov)++] = IOVEC_MAKE(c, l);

        *p = e;
        c = NULL;

        return 1;
}

static int map_string_field_internal(
                const char *field,
                const char **p,
                struct iovec **iov,
                size_t *n_iov,
                bool filter_printable) {

        _cleanup_free_ char *c = NULL;
        const char *s, *e;
        size_t l;

        assert(field);
        assert(p);
        assert(iov);
        assert(n_iov);

        /* The kernel formats string fields in one of two formats. */

        if (**p == '"') {
                /* Normal quoted syntax */
                s = *p + 1;
                e = strchr(s, '"');
                if (!e)
                        return 0;

                l = strlen(field) + (e - s);
                c = malloc(l+1);
                if (!c)
                        return -ENOMEM;

                *((char*) mempcpy(stpcpy(c, field), s, e - s)) = 0;

                e += 1;

        } else if (unhexchar(**p) >= 0) {
                /* Hexadecimal escaping */
                l = strlen(field);
                c = malloc(l + 2);
                if (!c)
                        return -ENOMEM;

                memcpy(c, field, l);
                for (e = *p; !IN_SET(*e, 0, ' '); e += 2) {
                        int a, b;
                        uint8_t x;

                        a = unhexchar(e[0]);
                        if (a < 0)
                                return 0;

                        b = unhexchar(e[1]);
                        if (b < 0)
                                return 0;

                        x = ((uint8_t) a << 4 | (uint8_t) b);

                        if (filter_printable && x < (uint8_t) ' ')
                                x = (uint8_t) ' ';

                        if (!GREEDY_REALLOC(c, l+2))
                                return -ENOMEM;

                        c[l++] = (char) x;
                }

                c[l] = 0;
        } else
                return 0;

        if (!GREEDY_REALLOC(*iov, *n_iov + 1))
                return -ENOMEM;

        (*iov)[(*n_iov)++] = IOVEC_MAKE(c, l);

        *p = e;
        c = NULL;

        return 1;
}

static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov) {
        return map_string_field_internal(field, p, iov, n_iov, false);
}

static int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov) {
        return map_string_field_internal(field, p, iov, n_iov, true);
}

static int map_generic_field(
                const char *prefix,
                const char **p,
                struct iovec **iov,
                size_t *n_iov) {

        const char *e, *f;
        char *c, *t;
        int r;

        /* Implements fallback mappings for all fields we don't know */

        for (e = *p; e < *p + 16; e++) {

                if (IN_SET(*e, 0, ' '))
                        return 0;

                if (*e == '=')
                        break;

                if (!((*e >= 'a' && *e <= 'z') ||
                      (*e >= 'A' && *e <= 'Z') ||
                      (*e >= '0' && *e <= '9') ||
                      IN_SET(*e, '_', '-')))
                        return 0;
        }

        if (e <= *p || e >= *p + 16)
                return 0;

        c = newa(char, strlen(prefix) + (e - *p) + 2);

        t = stpcpy(c, prefix);
        for (f = *p; f < e; f++) {
                char x;

                if (*f >= 'a' && *f <= 'z')
                        x = (*f - 'a') + 'A'; /* uppercase */
                else if (*f == '-')
                        x = '_'; /* dashes → underscores */
                else
                        x = *f;

                *(t++) = x;
        }
        strcpy(t, "=");

        e++;

        r = map_simple_field(c, &e, iov, n_iov);
        if (r < 0)
                return r;

        *p = e;
        return r;
}

/* Kernel fields are those occurring in the audit string before
 * msg='. All of these fields are trusted, hence carry the "_" prefix.
 * We try to translate the fields we know into our native names. The
 * other's are generically mapped to _AUDIT_FIELD_XYZ= */
static const MapField map_fields_kernel[] = {

        /* First, we map certain well-known audit fields into native
         * well-known fields */
        { "pid=",       "_PID=",              map_simple_field },
        { "ppid=",      "_PPID=",             map_simple_field },
        { "uid=",       "_UID=",              map_simple_field },
        { "euid=",      "_EUID=",             map_simple_field },
        { "fsuid=",     "_FSUID=",            map_simple_field },
        { "gid=",       "_GID=",              map_simple_field },
        { "egid=",      "_EGID=",             map_simple_field },
        { "fsgid=",     "_FSGID=",            map_simple_field },
        { "tty=",       "_TTY=",              map_simple_field },
        { "ses=",       "_AUDIT_SESSION=",    map_simple_field },
        { "auid=",      "_AUDIT_LOGINUID=",   map_simple_field },
        { "subj=",      "_SELINUX_CONTEXT=",  map_simple_field },
        { "comm=",      "_COMM=",             map_string_field },
        { "exe=",       "_EXE=",              map_string_field },
        { "proctitle=", "_CMDLINE=",          map_string_field_printable },

        /* Some fields don't map to native well-known fields. However,
         * we know that they are string fields, hence let's undo
         * string field escaping for them, though we stick to the
         * generic field names. */
        { "path=",      "_AUDIT_FIELD_PATH=", map_string_field },
        { "dev=",       "_AUDIT_FIELD_DEV=",  map_string_field },
        { "name=",      "_AUDIT_FIELD_NAME=", map_string_field },
        {}
};

/* Userspace fields are those occurring in the audit string after
 * msg='. All of these fields are untrusted, hence carry no "_"
 * prefix. We map the fields we don't know to AUDIT_FIELD_XYZ= */
static const MapField map_fields_userspace[] = {
        { "cwd=",       "AUDIT_FIELD_CWD=",   map_string_field },
        { "cmd=",       "AUDIT_FIELD_CMD=",   map_string_field },
        { "acct=",      "AUDIT_FIELD_ACCT=",  map_string_field },
        { "exe=",       "AUDIT_FIELD_EXE=",   map_string_field },
        { "comm=",      "AUDIT_FIELD_COMM=",  map_string_field },
        {}
};

static int map_all_fields(
                const char *p,
                const MapField map_fields[],
                const char *prefix,
                bool handle_msg,
                struct iovec **iov,
                size_t *n_iov) {

        int r;

        assert(p);
        assert(iov);
        assert(n_iov);

        for (;;) {
                bool mapped = false;
                const MapField *m;
                const char *v;

                p += strspn(p, WHITESPACE);

                if (*p == 0)
                        return 0;

                if (handle_msg) {
                        v = startswith(p, "msg='");
                        if (v) {
                                _cleanup_free_ char *c = NULL;
                                const char *e;

                                /* Userspace message. It's enclosed in
                                   simple quotation marks, is not
                                   escaped, but the last field in the
                                   line, hence let's remove the
                                   quotation mark, and apply the
                                   userspace mapping instead of the
                                   kernel mapping. */

                                e = endswith(v, "'");
                                if (!e)
                                        return 0; /* don't continue splitting up if the final quotation mark is missing */

                                c = strndup(v, e - v);
                                if (!c)
                                        return -ENOMEM;

                                return map_all_fields(c, map_fields_userspace, "AUDIT_FIELD_", false, iov, n_iov);
                        }
                }

                /* Try to map the kernel fields to our own names */
                for (m = map_fields; m->audit_field; m++) {
                        v = startswith(p, m->audit_field);
                        if (!v)
                                continue;

                        r = m->map(m->journal_field, &v, iov, n_iov);
                        if (r < 0)
                                return log_debug_errno(r, "Failed to parse audit array: %m");

                        if (r > 0) {
                                mapped = true;
                                p = v;
                                break;
                        }
                }

                if (!mapped) {
                        r = map_generic_field(prefix, &p, iov, n_iov);
                        if (r < 0)
                                return log_debug_errno(r, "Failed to parse audit array: %m");

                        if (r == 0)
                                /* Couldn't process as generic field, let's just skip over it */
                                p += strcspn(p, WHITESPACE);
                }
        }
}

void process_audit_string(Server *s, int type, const char *data, size_t size) {
        size_t n_iov = 0, z;
        _cleanup_free_ struct iovec *iov = NULL;
        uint64_t seconds, msec, id;
        const char *p, *type_name;
        char id_field[sizeof("_AUDIT_ID=") + DECIMAL_STR_MAX(uint64_t)],
             type_field[sizeof("_AUDIT_TYPE=") + DECIMAL_STR_MAX(int)],
             source_time_field[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)];
        char *m, *type_field_name;
        int k;

        assert(s);

        if (size <= 0)
                return;

        if (!data)
                return;

        /* Note that the input buffer is NUL terminated, but let's
         * check whether there is a spurious NUL byte */
        if (memchr(data, 0, size))
                return;

        p = startswith(data, "audit");
        if (!p)
                return;

        k = 0;
        if (sscanf(p, "(%" PRIu64 ".%" PRIu64 ":%" PRIu64 "):%n",
                   &seconds,
                   &msec,
                   &id,
                   &k) != 3 || k == 0)
                return;

        p += k;
        p += strspn(p, WHITESPACE);

        if (isempty(p))
                return;

        iov = new(struct iovec, N_IOVEC_META_FIELDS + 8);
        if (!iov) {
                log_oom();
                return;
        }

        iov[n_iov++] = IOVEC_MAKE_STRING("_TRANSPORT=audit");

        sprintf(source_time_field, "_SOURCE_REALTIME_TIMESTAMP=%" PRIu64,
                (usec_t) seconds * USEC_PER_SEC + (usec_t) msec * USEC_PER_MSEC);
        iov[n_iov++] = IOVEC_MAKE_STRING(source_time_field);

        sprintf(type_field, "_AUDIT_TYPE=%i", type);
        iov[n_iov++] = IOVEC_MAKE_STRING(type_field);

        sprintf(id_field, "_AUDIT_ID=%" PRIu64, id);
        iov[n_iov++] = IOVEC_MAKE_STRING(id_field);

        assert_cc(4 == LOG_FAC(LOG_AUTH));
        iov[n_iov++] = IOVEC_MAKE_STRING("SYSLOG_FACILITY=4");
        iov[n_iov++] = IOVEC_MAKE_STRING("SYSLOG_IDENTIFIER=audit");

        type_name = audit_type_name_alloca(type);

        type_field_name = strjoina("_AUDIT_TYPE_NAME=", type_name);
        iov[n_iov++] = IOVEC_MAKE_STRING(type_field_name);

        m = strjoina("MESSAGE=", type_name, " ", p);
        iov[n_iov++] = IOVEC_MAKE_STRING(m);

        z = n_iov;

        map_all_fields(p, map_fields_kernel, "_AUDIT_FIELD_", true, &iov, &n_iov);

        if (!GREEDY_REALLOC(iov, n_iov + N_IOVEC_META_FIELDS)) {
                log_oom();
                goto finish;
        }

        server_dispatch_message(s, iov, n_iov, MALLOC_ELEMENTSOF(iov), NULL, NULL, LOG_NOTICE, 0);

finish:
        /* free() all entries that map_all_fields() added. All others
         * are allocated on the stack or are constant. */

        for (; z < n_iov; z++)
                free(iov[z].iov_base);
}

void server_process_audit_message(
                Server *s,
                const void *buffer,
                size_t buffer_size,
                const struct ucred *ucred,
                const union sockaddr_union *sa,
                socklen_t salen) {

        const struct nlmsghdr *nl = buffer;

        assert(s);

        if (buffer_size < ALIGN(sizeof(struct nlmsghdr)))
                return;

        assert(buffer);

        /* Filter out fake data */
        if (!sa ||
            salen != sizeof(struct sockaddr_nl) ||
            sa->nl.nl_family != AF_NETLINK ||
            sa->nl.nl_pid != 0) {
                log_debug("Audit netlink message from invalid sender.");
                return;
        }

        if (!ucred || ucred->pid != 0) {
                log_debug("Audit netlink message with invalid credentials.");
                return;
        }

        if (!NLMSG_OK(nl, buffer_size)) {
                log_error("Audit netlink message truncated.");
                return;
        }

        /* Ignore special Netlink messages */
        if (IN_SET(nl->nlmsg_type, NLMSG_NOOP, NLMSG_ERROR))
                return;

        /* Except AUDIT_USER, all messages below AUDIT_FIRST_USER_MSG are control messages, let's ignore those */
        if (nl->nlmsg_type < AUDIT_FIRST_USER_MSG && nl->nlmsg_type != AUDIT_USER)
                return;

        process_audit_string(s, nl->nlmsg_type, NLMSG_DATA(nl), nl->nlmsg_len - ALIGN(sizeof(struct nlmsghdr)));
}

static int enable_audit(int fd, bool b) {
        struct {
                union {
                        struct nlmsghdr header;
                        uint8_t header_space[NLMSG_HDRLEN];
                };
                struct audit_status body;
        } _packed_ request = {
                .header.nlmsg_len = NLMSG_LENGTH(sizeof(struct audit_status)),
                .header.nlmsg_type = AUDIT_SET,
                .header.nlmsg_flags = NLM_F_REQUEST,
                .header.nlmsg_seq = 1,
                .header.nlmsg_pid = 0,
                .body.mask = AUDIT_STATUS_ENABLED,
                .body.enabled = b,
        };
        union sockaddr_union sa = {
                .nl.nl_family = AF_NETLINK,
                .nl.nl_pid = 0,
        };
        struct iovec iovec = {
                .iov_base = &request,
                .iov_len = NLMSG_LENGTH(sizeof(struct audit_status)),
        };
        struct msghdr mh = {
                .msg_iov = &iovec,
                .msg_iovlen = 1,
                .msg_name = &sa.sa,
                .msg_namelen = sizeof(sa.nl),
        };

        ssize_t n;

        n = sendmsg(fd, &mh, MSG_NOSIGNAL);
        if (n < 0)
                return -errno;
        if (n != NLMSG_LENGTH(sizeof(struct audit_status)))
                return -EIO;

        /* We don't wait for the result here, we can't do anything
         * about it anyway */

        return 0;
}

int server_open_audit(Server *s) {
        int r;

        if (s->audit_fd < 0) {
                static const union sockaddr_union sa = {
                        .nl.nl_family = AF_NETLINK,
                        .nl.nl_pid    = 0,
                        .nl.nl_groups = AUDIT_NLGRP_READLOG,
                };

                s->audit_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
                if (s->audit_fd < 0) {
                        if (ERRNO_IS_NOT_SUPPORTED(errno))
                                log_debug("Audit not supported in the kernel.");
                        else
                                log_warning_errno(errno, "Failed to create audit socket, ignoring: %m");

                        return 0;
                }

                if (bind(s->audit_fd, &sa.sa, sizeof(sa.nl)) < 0) {
                        log_warning_errno(errno,
                                          "Failed to join audit multicast group. "
                                          "The kernel is probably too old or multicast reading is not supported. "
                                          "Ignoring: %m");
                        s->audit_fd = safe_close(s->audit_fd);
                        return 0;
                }
        } else
                (void) fd_nonblock(s->audit_fd, true);

        r = setsockopt_int(s->audit_fd, SOL_SOCKET, SO_PASSCRED, true);
        if (r < 0)
                return log_error_errno(r, "Failed to set SO_PASSCRED on audit socket: %m");

        r = sd_event_add_io(s->event, &s->audit_event_source, s->audit_fd, EPOLLIN, server_process_datagram, s);
        if (r < 0)
                return log_error_errno(r, "Failed to add audit fd to event loop: %m");

        if (s->set_audit >= 0) {
                /* We are listening now, try to enable audit if configured so */
                r = enable_audit(s->audit_fd, s->set_audit);
                if (r < 0)
                        log_warning_errno(r, "Failed to issue audit enable call: %m");
                else if (s->set_audit > 0)
                        log_debug("Auditing in kernel turned on.");
                else
                        log_debug("Auditing in kernel turned off.");
        }

        return 0;
}
