-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.

--[[
# Mozilla Security Authentication Events, Match any

This sandbox applies selprinc normalization to events matching the message matcher
and will create an alert on any matched event.

If enable_metrics is true, the module will submit metrics events for collection by the metrics
output sandbox. Ensure process_message_inject_limit is set appropriately, as if enabled process_event
will submit up to 2 messages (the alert, and the metric event).

## Sample Configuration

```lua
filename = "moz_security_auth_any.lua"
message_matcher = "Type ~= 'bastion.file.sshd'% && Fields[sshd_authmsg] == 'Accepted'"
ticker_interval = 0
process_message_inject_limit = 1

heka_selprinc = {
    events = {
        ssh = {
            select_field     = "Fields[programname]",
            select_match     = "^sshd$",
            subject_field    = "Fields[user]",
            object_field     = "Hostname",
            sourceip_field   = "Fields[ssh_remote_ipaddr]",

            aux = {
                { "geocity", "Fields[ssh_remote_ipaddr_city]" },
                { "geocountry", "Fields[ssh_remote_ipaddr_country]" }
            }
        }
    }
}

-- module makes use of alert output and needs a valid alert configuration
alert = {
    modules = { }
}

-- enable_metrics = false -- optional, if true enable secmetrics submission
```
--]]

require "string"
require "math"
require "os"

local selprinc  = require "heka.selprinc"
local alert     = require "heka.alert"

local secm
if read_config("enable_metrics") then
    secm = require "heka.secmetrics".new()
end

local cephost = read_config("Hostname") or "unknown"

function process_message()
    local sm = selprinc.match()
    if not sm then return 0 end -- nothing in the selprinc cfg matched, ignore

    local ts            = math.floor(read_message("Timestamp") / 1e9)
    local hn            = sm.object or "unknown"
    local geocity       = sm.geocity
    local geocountry    = sm.geocountry
    local user          = sm.subject
    local sourceip      = sm.sourceip

    local subject = string.format("AUTH_ANY %s %s auth %s src %s", user, sm.category, hn, sourceip)
    local payload = "Authentication to host configured to alert on any\n"
    payload = payload .. string.format("Generated by %s, event timestamp %s\n", cephost,
        os.date("%Y-%m-%d %H:%M:%S", ts))

    -- If we also have city and country information, add that to the subject
    if geocity and geocountry then
        subject = subject .. string.format(" (%s, %s)", geocity, geocountry)
    end

    if secm then
        secm:inc_accumulator("total_count")
        secm:send()
    end

    alert.send(subject, subject, payload)
    return 0
end


function timer_event()
    -- no op
end
