chiark / gitweb /
journal: adjust audit log messages a bit
[elogind.git] / src / journal / journald-audit.c
index 0e1e8bd5d07ea6bb939552b2c56f3d0c6fba48a1..341d74815d5826116ef16b355e00a3695c375c62 100644 (file)
@@ -67,7 +67,7 @@ static int map_simple_field(const char *field, const char **p, struct iovec **io
         return 1;
 }
 
-static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+static int map_string_field_internal(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov, bool filter_printable) {
         _cleanup_free_ char *c = NULL;
         const char *s, *e;
         size_t l;
@@ -108,6 +108,7 @@ static int map_string_field(const char *field, const char **p, struct iovec **io
                 memcpy(c, field, l);
                 for (e = *p; *e != ' ' && *e != 0; e += 2) {
                         int a, b;
+                        uint8_t x;
 
                         a = unhexchar(e[0]);
                         if (a < 0)
@@ -117,10 +118,15 @@ static int map_string_field(const char *field, const char **p, struct iovec **io
                         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, allocated, l+2))
                                 return -ENOMEM;
 
-                        c[l++] = (char) ((uint8_t) a << 4 | (uint8_t) b);
+                        c[l++] = (char) x;
                 }
 
                 c[l] = 0;
@@ -140,6 +146,14 @@ static int map_string_field(const char *field, const char **p, struct iovec **io
         return 1;
 }
 
+static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+        return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, false);
+}
+
+static int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+        return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, true);
+}
+
 static int map_generic_field(const char *prefix, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
         const char *e, *f;
         char *c, *t;
@@ -158,7 +172,7 @@ static int map_generic_field(const char *prefix, const char **p, struct iovec **
                 if (!((*e >= 'a' && *e <= 'z') ||
                       (*e >= 'A' && *e <= 'Z') ||
                       (*e >= '0' && *e <= '9') ||
-                      (*e == '_')))
+                      *e == '_' || *e == '-'))
                         return 0;
         }
 
@@ -168,8 +182,18 @@ static int map_generic_field(const char *prefix, const char **p, struct iovec **
         c = alloca(strlen(prefix) + (e - *p) + 2);
 
         t = stpcpy(c, prefix);
-        for (f = *p; f < e; f++)
-                *(t++) = *f >= 'a' && *f <= 'z' ? ((*f - 'a') + 'A') : *f;
+        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 ++;
@@ -204,7 +228,7 @@ static const MapField map_fields_kernel[] = {
         { "subj=",      "_SELINUX_CONTEXT=",       map_simple_field },
         { "comm=",      "_COMM=",                  map_string_field },
         { "exe=",       "_EXE=",                   map_string_field },
-        { "proctitle=", "_CMDLINE=",               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
@@ -311,7 +335,7 @@ static int map_all_fields(
         }
 }
 
-static void process_audit_string(Server *s, int type, const char *data, size_t size, const struct timeval *tv) {
+static void process_audit_string(Server *s, int type, const char *data, size_t size) {
         _cleanup_free_ struct iovec *iov = NULL;
         size_t n_iov_allocated = 0;
         unsigned n_iov = 0, k;
@@ -321,7 +345,7 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
         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)];
-        const char *m;
+        char *m;
 
         assert(s);
 
@@ -340,7 +364,7 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
         if (!p)
                 return;
 
-        if (sscanf(p, "(%" PRIi64 ".%" PRIi64 ":%" PRIi64 "): %n",
+        if (sscanf(p, "(%" PRIi64 ".%" PRIi64 ":%" PRIi64 "):%n",
                    &seconds,
                    &msec,
                    &id,
@@ -348,6 +372,10 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
                 return;
 
         p += k;
+        p += strspn(p, WHITESPACE);
+
+        if (isempty(p))
+                return;
 
         n_iov_allocated = N_IOVEC_META_FIELDS + 5;
         iov = new(struct iovec, n_iov_allocated);
@@ -368,7 +396,8 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
         sprintf(id_field, "_AUDIT_ID=%" PRIu64, id);
         IOVEC_SET_STRING(iov[n_iov++], id_field);
 
-        m = strappenda("MESSAGE=", data);
+        m = alloca(strlen("MESSAGE=<audit-") + DECIMAL_STR_MAX(int) + strlen("> ") + strlen(p) + 1);
+        sprintf(m, "MESSAGE=<audit-%i> %s", type, p);
         IOVEC_SET_STRING(iov[n_iov++], m);
 
         z = n_iov;
@@ -380,7 +409,7 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
                 goto finish;
         }
 
-        server_dispatch_message(s, iov, n_iov, n_iov_allocated, NULL, tv, NULL, 0, NULL, LOG_NOTICE, 0);
+        server_dispatch_message(s, iov, n_iov, n_iov_allocated, NULL, NULL, NULL, 0, NULL, LOG_NOTICE, 0);
 
 finish:
         /* free() all entries that map_all_fields() added. All others
@@ -395,7 +424,6 @@ void server_process_audit_message(
                 const void *buffer,
                 size_t buffer_size,
                 const struct ucred *ucred,
-                const struct timeval *tv,
                 const union sockaddr_union *sa,
                 socklen_t salen) {
 
@@ -435,7 +463,7 @@ void server_process_audit_message(
         if (nl->nlmsg_type < AUDIT_FIRST_USER_MSG)
                 return;
 
-        process_audit_string(s, nl->nlmsg_type, NLMSG_DATA(nl), nl->nlmsg_len - ALIGN(sizeof(struct nlmsghdr)), tv);
+        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) {