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
use chrono::prelude::{DateTime};
use std::borrow::Cow;
use usiem::components::common::LogParsingError;
use usiem::events::field::{SiemField};
use usiem::events::{SiemLog, SiemEvent};
mod event_types;
mod awstypes;
use event_types::aws_event_type;

pub fn parse_general_log(mut log: SiemLog) -> Result<SiemLog, LogParsingError> {
    let log_value = match log.event() {
        SiemEvent::Unknown => {
            let log_message = log.message();
            if log_message.len() > 0 && &log_message[0..1] == "{" {
                let val : serde_json::Value = match serde_json::from_str(log_message) {
                    Ok(val) => val,
                    Err(_) => return Err(LogParsingError::NoValidParser(log))
                };
                val
            }else{
                return Err(LogParsingError::NoValidParser(log))
            }
        },
        // Improve this
        SiemEvent::Json(val) => val.clone(),
        _ => return Err(LogParsingError::NoValidParser(log))
    };
    let timestamp = match log_value.get("eventTime") {
        Some(val) => {
            match val.as_str() {
                Some(val) => {
                    match DateTime::parse_from_rfc3339(val) {
                        Ok(timestamp) => timestamp.timestamp_millis(),
                        Err(_err) => return Err(LogParsingError::NoValidParser(log)),
                    }
                },
                None => return Err(LogParsingError::NoValidParser(log))
            }
        },
        None => return Err(LogParsingError::NoValidParser(log))
    };    
    log.set_event_created(timestamp);
    log.set_service(Cow::Borrowed("AWS"));
    log.set_product(Cow::Borrowed("AWS"));
    log.set_category(Cow::Borrowed("Cloud"));
    log.add_field("cloud.provider", SiemField::Text(Cow::Borrowed("AWS")));
    return aws_event_type(log_value, log);
}

fn get_string_field(log_value: &serde_json::Value, name: &str) -> Option<SiemField> {
    match log_value.get(name) {
        Some(val) => match val.as_str() {
            Some(val) => Some(SiemField::from_str(val.to_string())),
            None => None,
        },
        None => None,
    }
}