Hello,
the attached patch implements TTY audit log data interpretation: it
turns
data=627F6361740D6964202D610D6C73202D6C202F626F090D10202D6C72740D0110011B661B640B202D6C7274156364202D1B7F6364207E6D69096C69096F090D6C730D126370201B3E63640D6C730D726D20627A496D09757F0D6364202D0D12637020051B7F626F09766D6C0937090D6364202F626F090D126D6B696E6974720D04
into
"b",backspace,"cat",ret,"id -a",ret,"ls -l /bo",tab,ret,^P,"
-lrt",ret,^A,^P,^A,esc,"f",esc,"d",^K," -lrt",^U,"cd
-",esc,backspace,"cd ~mi",tab,"li",tab,"o",tab,ret,"ls",ret,^R,"cp
",esc,">cd",ret,"ls",ret,"rm bzIm",tab,"u",backspace,ret,"cd
-",ret,^R,"cp
",^E,esc,backspace,"bo",tab,"vml",tab,"7",tab,ret,"cd
/bo",tab,ret,^R,"mkinitr",ret,^D
(Usually, bash would be patched to emit an USER_TTY record for each
command line, and each USER_TTY record causes emitting a TTY record for
the collected data. This record was created without a patched bash, so
it contains all commands in the session.)
So far the patch supports only a few basic control sequences (arrow and
function keys with no modifiers). Before I add many more, I have a few
questions:
* Is it OK to hard-code the control sequences in the library?
Would it be preferable store them in a separate file instead,
letting end-users add or modify control sequences?
* How to share the code with src/ausearch-report.c? Copying the
code is ugly; reasonable options are
* move the data interpretation code to libaudit (either
only TTY audit interpretation, or all of it)
* link ausearch to libauparse
* Is there any reason to support conflicting terminal types (e.g.
something other than vt100-like terminals)? Are there conflicts
in the control sequences emitted by commonly used terminal
emulators?
Thank you,
Mirek
Index: auparse/auparse-defs.h
===================================================================
--- auparse/auparse-defs.h (revision 108)
+++ auparse/auparse-defs.h (working copy)
@@ -77,7 +77,7 @@
AUPARSE_TYPE_SOCKADDR, AUPARSE_TYPE_FLAGS, AUPARSE_TYPE_PROMISC,
AUPARSE_TYPE_CAPABILITY, AUPARSE_TYPE_SUCCESS, AUPARSE_TYPE_A0,
AUPARSE_TYPE_A1, AUPARSE_TYPE_A2, AUPARSE_TYPE_SIGNAL,
- AUPARSE_TYPE_LIST } auparse_type_t;
+ AUPARSE_TYPE_LIST, AUPARSE_TYPE_TTY_DATA } auparse_type_t;
#ifdef __cplusplus
}
Index: auparse/interpret.c
===================================================================
--- auparse/interpret.c (revision 108)
+++ auparse/interpret.c (working copy)
@@ -79,7 +79,7 @@
* This function will take a pointer to a 2 byte Ascii character buffer and
* return the actual hex value.
*/
-static unsigned char x2c(unsigned char *buf)
+static unsigned char x2c(const unsigned char *buf)
{
static const char AsciiArray[17] = "0123456789ABCDEF";
char *ptr;
@@ -95,8 +95,18 @@
return total;
}
+static int is_hex_string(const char *str)
+{
+ while (*str) {
+ if (!isxdigit(*str))
+ return 0;
+ str++;
+ }
+ return 1;
+}
+
/* returns a freshly malloc'ed and converted buffer */
-const char *au_unescape(char *buf)
+char *au_unescape(char *buf)
{
int len, i;
char saved, *str, *ptr = buf;
@@ -852,6 +862,134 @@
return out;
}
+struct string_buf {
+ char *buf; /* NULL if was ever out of memory */
+ size_t allocated;
+ size_t pos;
+};
+
+/* Append c to buf. */
+static void append_char(struct string_buf *buf, char c)
+{
+ if (buf->buf == NULL)
+ return;
+ if (buf->pos == buf->allocated) {
+ char *p;
+
+ buf->allocated *= 2;
+ p = realloc(buf->buf, buf->allocated);
+ if (p == NULL) {
+ free(buf->buf);
+ buf->buf = NULL;
+ return;
+ }
+ buf->buf = p;
+ }
+ buf->buf[buf->pos] = c;
+ buf->pos++;
+}
+
+/* Represent c as a character within a quoted string, and append it to buf. */
+static void tty_append_printable_char(struct string_buf *buf, unsigned char c)
+{
+ if (c < 0x20 || c > 0x7E) {
+ append_char(buf, '\\');
+ append_char(buf, '0' + ((c >> 6) & 07));
+ append_char(buf, '0' + ((c >> 3) & 07));
+ append_char(buf, '0' + (c & 07));
+ } else {
+ if (c == '\\' || c == '"')
+ append_char(buf, '\\');
+ append_char(buf, c);
+ }
+}
+
+/* Search for a name of a sequence of TTY bytes.
+ If found, return the name and advance *INPUT. Return NULL otherwise. */
+static const char *tty_find_named_key(unsigned char **input, size_t input_len)
+{
+ /* NUL-terminated list of (sequence, NUL, name, NUL) entries.
+ First match wins, even if a longer match were possible later */
+ static const unsigned char named_keys[] =
+#define E(SEQ, NAME) SEQ "\0" NAME "\0"
+#include "tty_named_keys.h"
+#undef E
+ "\0";
+
+ unsigned char *src;
+ const unsigned char *nk;
+
+ src = *input;
+ if (*src >= ' ' && *src != 0x7F)
+ return NULL; /* Fast path */
+ nk = named_keys;
+ do {
+ const unsigned char *p;
+ size_t nk_len;
+
+ p = strchr(nk, '\0');
+ nk_len = p - nk;
+ if (nk_len <= input_len && memcmp(src, nk, nk_len) == 0) {
+ *input += nk_len;
+ return p + 1;
+ }
+ nk = strchr(p + 1, '\0') + 1;
+ } while (*nk != '\0');
+ return NULL;
+}
+
+static const char *print_tty_data(const char *raw_data)
+{
+ struct string_buf buf;
+ int in_printable;
+ unsigned char *data, *data_pos, *data_end;
+
+ if (!is_hex_string(raw_data))
+ return strdup(raw_data);
+ data = au_unescape((char *)raw_data);
+ if (data == NULL)
+ return NULL;
+ data_end = data + strlen(raw_data) / 2;
+
+ buf.allocated = 10;
+ buf.buf = malloc(buf.allocated); /* NULL handled in append_char() */
+ buf.pos = 0;
+ in_printable = 0;
+ data_pos = data;
+ while (data_pos < data_end) {
+ /* FIXME: Unicode */
+ const char *desc;
+
+ desc = tty_find_named_key(&data_pos, data_end - data_pos);
+ if (desc != NULL) {
+ if (in_printable != 0) {
+ append_char(&buf, '"');
+ in_printable = 0;
+ }
+ if (buf.pos != 0)
+ append_char(&buf, ',');
+ while (*desc != '\0') {
+ append_char(&buf, *desc);
+ desc++;
+ }
+ } else {
+ if (in_printable == 0) {
+ if (buf.pos != 0)
+ append_char(&buf, ',');
+ append_char(&buf, '"');
+ in_printable = 1;
+ }
+ tty_append_printable_char(&buf, *data_pos);
+ data_pos++;
+ }
+ }
+ if (in_printable != 0)
+ append_char(&buf, '"');
+ append_char(&buf, '\0');
+ free(data);
+ return buf.buf;
+}
+
int lookup_type(const char *name)
{
int i;
@@ -861,16 +999,6 @@
return AUPARSE_TYPE_UNCLASSIFIED;
}
-static int is_hex_string(const char *str)
-{
- while (*str) {
- if (!isxdigit(*str))
- return 0;
- str++;
- }
- return 1;
-}
-
const char *interpret(const rnode *r)
{
const nvlist *nv = &r->nv;
@@ -885,6 +1013,8 @@
type = AUPARSE_TYPE_ESCAPED;
else if (r->type == AUDIT_AVC && strcmp(name, "saddr") == 0)
type = -1;
+ else if (r->type == AUDIT_USER_TTY && strcmp(name, "msg") == 0)
+ type = AUPARSE_TYPE_ESCAPED;
else if (strcmp(name, "acct") == 0) {
if (val[0] == '"')
type = AUPARSE_TYPE_ESCAPED;
@@ -949,7 +1079,10 @@
break;
case AUPARSE_TYPE_LIST:
out = print_list(val);
- break;
+ break;
+ case AUPARSE_TYPE_TTY_DATA:
+ out = print_tty_data(val);
+ break;
case AUPARSE_TYPE_UNCLASSIFIED:
default: {
char *out2;
Index: auparse/typetab.h
===================================================================
--- auparse/typetab.h (revision 108)
+++ auparse/typetab.h (working copy)
@@ -69,3 +69,4 @@
_S(AUPARSE_TYPE_A1, "a1" )
_S(AUPARSE_TYPE_A2, "a2" )
_S(AUPARSE_TYPE_SIGNAL, "sig" )
+_S(AUPARSE_TYPE_TTY_DATA, "data" )
Index: auparse/interpret.h
===================================================================
--- auparse/interpret.h (revision 108)
+++ auparse/interpret.h (working copy)
@@ -37,7 +37,7 @@
const char *interpret(const rnode *r);
void aulookup_destroy_uid_list(void);
void aulookup_destroy_gid_list(void);
-const char *au_unescape(char *buf);
+char *au_unescape(char *buf);
/* Make these hidden to prevent conflicts */
hidden_proto(lookup_type);
Index: auparse/tty_named_keys.h
===================================================================
--- auparse/tty_named_keys.h (revision 0)
+++ auparse/tty_named_keys.h (revision 0)
@@ -0,0 +1,71 @@
+/* tty_named_keys.h --
+ * Copyright 2008 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Miloslav Trmač <[EMAIL PROTECTED]>
+ */
+
+E("\x01", "^A")
+E("\x02", "^B")
+E("\x03", "^C")
+E("\x04", "^D")
+E("\x05", "^E")
+E("\x06", "^F")
+E("\x07", "^G")
+E("\x08", "^H")
+E("\t", "tab")
+E("\n", "nl")
+E("\x0B", "^K")
+E("\x0C", "^L")
+E("\r", "ret")
+E("\x0E", "^N")
+E("\x0F", "^O")
+E("\x10", "^P")
+E("\x11", "^Q")
+E("\x12", "^R")
+E("\x13", "^S")
+E("\x14", "^T")
+E("\x15", "^U")
+E("\x16", "^V")
+E("\x17", "^W")
+E("\x18", "^X")
+E("\x19", "^Y")
+E("\x1A", "^Z")
+/* \x1B handled only after all other escape sequences */
+E("\x7F", "backspace")
+
+E("\x1B[A", "up")
+E("\x1B[B", "down")
+E("\x1B[C", "right")
+E("\x1B[D", "left")
+
+E("\x1B""OP", "F1")
+E("\x1B""OQ", "F2")
+E("\x1B""OR", "F3")
+E("\x1B""OS", "F4")
+E("\x1B[15~", "F5")
+E("\x1B[17~", "F6")
+E("\x1B[18~", "F7")
+E("\x1B[19~", "F8")
+E("\x1B[20~", "F9")
+E("\x1B[21~", "F10")
+E("\x1B[23~", "F11")
+E("\x1B[24~", "F12")
+
+E("\x1B", "esc")
+E("\x7F", "backspace")
Index: auparse/Makefile.am
===================================================================
--- auparse/Makefile.am (revision 108)
+++ auparse/Makefile.am (working copy)
@@ -32,7 +32,7 @@
auparse.c auditd-config.c message.c data_buf.c auparse-defs.h \
data_buf.h nvlist.h auparse.h ellist.h \
internal.h nvpair.h rnode.h interpret.h \
- private.h expression.c expression.h
+ private.h expression.c expression.h tty_named_keys.h
nodist_libauparse_la_SOURCES = $(BUILT_SOURCES)
libauparse_la_LIBADD = ${top_builddir}/lib/libaudit.la
--
Linux-audit mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/linux-audit