1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct ProcessEventColumns<'a> {
    /// "uid": "0",
    pub uid: &'a str,

    /// "time": "1527895541",
    pub time: &'a str,

    /// "pid": "30219",
    pub pid: &'a str,

    /// "path": "/usr/bin/curl",
    pub path: &'a str,

    /// "auid": "1000",
    pub auid: &'a str,

    /// "cmdline": "curl google.com",
    pub cmdline: &'a str,

    /// "ctime": "1503452096",
    pub ctime: &'a str,

    /// "cwd": "",
    pub cwd: &'a str,

    /// "egid": "0",
    pub egid: &'a str,

    /// "euid": "0",
    pub euid: &'a str,

    /// "gid": "0",
    pub gid: &'a str,

    /// "parent": ""
    pub parent: &'a str,
}

#[derive(Serialize, Deserialize)]
pub struct ProcessEvent<'a> {
    ///   "action": "added" OR "removed",
    pub action: &'a str,

    /// "unixTime": 1527895550,
    #[serde(alias = "unixTime")]
    pub unix_time: u64,

    /// "columns": {//see ProcessEventColumns},
    pub columns: ProcessEventColumns<'a>,

    /// "hostIdentifier": "vagrant",
    #[serde(alias = "hostIdentifier")]
    pub host_identifier: &'a str,

    #[serde(borrow)]
    pub decorations: Option<HashMap<&'a str, &'a str>>,
}

#[derive(Serialize, Deserialize)]
pub struct SocketEventColumns<'a> {
    pub time: &'a str,
    pub success: &'a str,
    pub remote_port: &'a str,
    pub action: &'a str,
    pub auid: &'a str,
    pub family: &'a str,
    pub local_address: &'a str,
    pub local_port: &'a str,
    pub path: &'a str,
    pub pid: &'a str,
    pub remote_address: &'a str,
    #[serde(borrow)]
    pub decorations: Option<HashMap<&'a str, &'a str>>,
}

#[derive(Serialize, Deserialize)]
pub struct SocketEvent<'a> {
    pub columns: SocketEventColumns<'a>,

    #[serde(alias = "unixTime")]
    pub unix_time: u64,
    #[serde(alias = "hostIdentifier")]
    pub host_identifier: &'a str,
}


#[derive(Serialize, Deserialize)]
#[serde(tag = "name")]
pub enum Event<'a> {
    #[serde(rename = "process_events")]
    #[serde(borrow)]
    ProcessEvent(ProcessEvent<'a>),

    #[serde(rename = "socket_events")]
    #[serde(borrow)]
    SocketEvent(SocketEvent<'a>),
}

#[cfg(test)]
mod tests {
    use super::{SocketEvent, Event};
    use serde_json::json;

    #[test]
    fn it_works() {
        let log = json!(
            {
              "action": "added",
              "columns": {
                "time": "1527895541",
                "success": "1",
                "remote_port": "80",
                "action": "connect",
                "auid": "1000",
                "family": "2",
                "local_address": "",
                "local_port": "0",
                "path": "/usr/bin/curl",
                "pid": "30220",
                "remote_address": "172.217.164.110"
              },
              "unixTime": 1527895545,
              "hostIdentifier": "vagrant",
              "name": "socket_events"
            }
        ).to_string();

        let _: Event = serde_json::from_str(&log)
            .expect("Could not deserialize SocketEvent");


    }


}