Mercurial > prosody-modules
annotate mod_audit/mod_audit.lua @ 4933:530d116b7f68
mod_audit*: modules for audit logging in prosody
These are to be seen as proof-of-concept for now.
author | Jonas Schäfer <jonas@wielicki.name> |
---|---|
date | Tue, 26 Apr 2022 22:32:44 +0200 |
parents | |
children | 08dea42a302a |
rev | line source |
---|---|
4933
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
1 module:set_global(); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
2 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
3 local time_now = os.time; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
4 local st = require "util.stanza"; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
5 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
6 local host_wide_user = "@"; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
7 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
8 local stores = {}; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
9 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
10 local function get_store(self, host) |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
11 local store = rawget(self, host); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
12 if store then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
13 return store |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
14 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
15 local store = module:context(host):open_store("audit", "archive"); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
16 rawset(self, host, store); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
17 return store; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
18 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
19 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
20 setmetatable(stores, { __index = get_store }); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
21 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
22 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
23 local function session_extra(session) |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
24 local attr = { |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
25 xmlns = "xmpp:prosody.im/audit", |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
26 }; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
27 if session.id then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
28 attr.id = session.id; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
29 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
30 if session.type then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
31 attr.type = session.type; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
32 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
33 local stanza = st.stanza("session", attr); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
34 if session.ip then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
35 stanza:text_tag("remote-ip", session.ip); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
36 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
37 return stanza |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
38 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
39 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
40 local function audit(host, user, source, event_type, extra) |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
41 if not host or host == "*" then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
42 error("cannot log audit events for global"); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
43 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
44 local user = user or host_wide_user; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
45 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
46 local attr = { |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
47 ["source"] = source, |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
48 ["type"] = event_type, |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
49 }; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
50 if user ~= host_wide_user then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
51 attr.user = user; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
52 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
53 local stanza = st.stanza("audit-event", attr); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
54 if extra ~= nil then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
55 if extra.session then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
56 local child = session_extra(extra.session); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
57 if child then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
58 stanza:add_child(child); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
59 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
60 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
61 if extra.custom then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
62 for _, child in extra.custom do |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
63 if not st.is_stanza(child) then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
64 error("all extra.custom items must be stanzas") |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
65 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
66 stanza:add_child(child); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
67 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
68 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
69 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
70 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
71 local id, err = stores[host]:append(nil, nil, stanza, time_now(), user); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
72 if err then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
73 module:log("error", "failed to persist audit event: %s", err); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
74 return |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
75 else |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
76 module:log("debug", "persisted audit event %s as %s", stanza:top_tag(), id); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
77 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
78 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
79 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
80 local module_api = getmetatable(module).__index; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
81 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
82 function module_api:audit(user, event_type, extra) |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
83 audit(self.host, user, "mod_" .. self:get_name(), event_type, extra); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
84 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
85 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
86 module:hook("audit", audit, 0); |