Hi,

I'm using libauparse version 2.8.3. I am trying to experiment with auparse_feed() with records directly received from audit_get_reply() instead of from a log file.

My code is as follows:
(I have left out declarations and error handling for brevity)
/*******************************/
    auditfd = audit_open();
 
    rc = audit_is_enabled(auditfd);
    if (0 == rc)
    {
        rc = audit_set_enabled(auditfd, 1);
    }
   
    rc = audit_set_pid(auditfd, getpid(), WAIT_YES);
   
    rule = (struct audit_rule_data *) malloc(sizeof(struct audit_rule_data));
    memset(rule, 0, sizeof(struct audit_rule_data));

    rc = audit_add_dir(&rule, "/home");
  
    rc = audit_update_watch_perms(rule, AUDIT_PERM_WRITE | AUDIT_PERM_ATTR);
   
    rc = audit_delete_rule_data(auditfd, rule, AUDIT_FILTER_EXIT, AUDIT_ALWAYS);
    rc = audit_add_rule_data(auditfd, rule, AUDIT_FILTER_EXIT, AUDIT_ALWAYS);
  
    event_cnt = (int *) malloc(sizeof(int));
   
    au = auparse_init(AUSOURCE_FEED, NULL);
    auparse_add_callback(au, on_audit_event, event_cnt, free); // callback function added here
    auparse_set_escape_mode(au, AUPARSE_ESC_RAW);

    pfd[0].fd = auditfd;
    pfd[0].events = POLLIN;

    while (1)
    {
        do
        {
            rc = poll(pfd, 1, 1000); // 1 sec
        }
        while (rc < 0 && EINTR == errno);

        if (pfd[0].revents & POLLIN)
        {
            struct audit_reply reply;

            pfd[0].revents = 0;

            rc = audit_get_reply(auditfd, &reply, GET_REPLY_NONBLOCKING, 0);

            if (rc > 0)
            {
                int rc = 0;
                char type_name[50] = {0};

                printf("type: %d: %s\n", reply.type, audit_msg_type_to_name(reply.type));
                printf("len: %d\n", reply.len);

                if (NULL != audit_msg_type_to_name(reply.type))
                {
                    strncpy(type_name, audit_msg_type_to_name(reply.type), 49);
                }
                reply.message[reply.len] = '\0';
                printf("message: %s\n", reply.message);

                if (record_buffer_len < (reply.len + 10 + strlen(type_name)))
                {
                    record_buffer_len = (reply.len + 10 + strlen(type_name));
                    record_buffer = realloc(record_buffer, record_buffer_len * sizeof(char));
                }
                memset(record_buffer, 0, record_buffer_len);

                snprintf(record_buffer, (record_buffer_len - 1), "type=%s %.*s\n", type_name, reply.len, reply.message);

                printf("to auparse: %s\n", record_buffer); // record_buffer is then passed to auparse_feed()
                printf("=======================================\n\n");

                rc = auparse_feed(au, record_buffer, record_buffer_len);
                if (-1 == rc)
                {
                    perror("auparse_feed ");
                }
            }
        }
    }
    auparse_flush_feed(au);
    auparse_destroy(au);
/*******************************/

The callback function on_audit_event() just goes through the records one by one and prints the fields and values. I have added a rule to watch for file edits in the /home folder. I see the records for file creation in this folder being received, however it looks like the callback function is not being called when an EOE record is received. Please let me know if I'm missing something.

Creating a file "test.txt" generates the following output:

type: 1300: SYSCALL
len: 305
message: audit(1560234865.559:6870): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7fffe4c1529a a2=941 a3=1b6 items=2 ppid=6374 pid=17381 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts4 ses=4 comm="touch" exe="/bin/touch" subj==unconfined key=(null)
to auparse: type=SYSCALL audit(1560234865.559:6870): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7fffe4c1529a a2=941 a3=1b6 items=2 ppid=6374 pid=17381 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts4 ses=4 comm="touch" exe="/bin/touch" subj==unconfined key=(null)

=======================================

type: 1307: CWD
len: 45
message: audit(1560234865.559:6870): cwd="/home/tarun"
to auparse: type=CWD audit(1560234865.559:6870): cwd="/home/tarun"

=======================================

type: 1302: PATH
len: 206
message: audit(1560234865.559:6870): item=0 name="/home/tarun" inode=14286851 dev=103:02 mode=040755 ouid=1000 ogid=1000 rdev=00:00 nametype=PARENT cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
to auparse: type=PATH audit(1560234865.559:6870): item=0 name="/home/tarun" inode=14286851 dev=103:02 mode=040755 ouid=1000 ogid=1000 rdev=00:00 nametype=PARENT cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0

=======================================

type: 1302: PATH
len: 204
message: audit(1560234865.559:6870): item=1 name="test.txt" inode=14309805 dev=103:02 mode=0100664 ouid=1000 ogid=1000 rdev=00:00 nametype=CREATE cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
to auparse: type=PATH audit(1560234865.559:6870): item=1 name="test.txt" inode=14309805 dev=103:02 mode=0100664 ouid=1000 ogid=1000 rdev=00:00 nametype=CREATE cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0

=======================================

type: 1327: PROCTITLE
len: 66
message: audit(1560234865.559:6870): proctitle=746F75636800746573742E747874
to auparse: type=PROCTITLE audit(1560234865.559:6870): proctitle=746F75636800746573742E747874

=======================================

type: 1320: EOE
len: 28
message: audit(1560234865.559:6870):
to auparse: type=EOE audit(1560234865.559:6870):

=======================================

The lines marked "to auparse" is the data I'm sending to auparse_feed().

Please let me know if I need to change the format of the buffer I need to pass to auparse_feed(), or if I'm missing something else.

Thanks in advance,
Tarun