Mercurial > prosody-modules
annotate mod_audit/mod_audit.lua @ 5193:2bb29ece216b
mod_http_oauth2: Implement stateless dynamic client registration
Replaces previous explicit registration that required either the
additional module mod_adhoc_oauth2_client or manually editing the
database. That method was enough to have something to test with, but
would not probably not scale easily.
Dynamic client registration allows creating clients on the fly, which
may be even easier in theory.
In order to not allow basically unauthenticated writes to the database,
we implement a stateless model here.
per_host_key := HMAC(config -> oauth2_registration_key, hostname)
client_id := JWT { client metadata } signed with per_host_key
client_secret := HMAC(per_host_key, client_id)
This should ensure everything we need to know is part of the client_id,
allowing redirects etc to be validated, and the client_secret can be
validated with only the client_id and the per_host_key.
A nonce injected into the client_id JWT should ensure nobody can submit
the same client metadata and retrieve the same client_secret
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 03 Mar 2023 21:14:19 +0100 |
parents | 4a5837591380 |
children | d9577083c5f5 |
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 |
5115
4a5837591380
mod_audit: remove event hook
Jonas Schäfer <jonas@wielicki.name>
parents:
4935
diff
changeset
|
3 local audit_log_limit = module:get_option_number("audit_log_limit", 10000); |
4a5837591380
mod_audit: remove event hook
Jonas Schäfer <jonas@wielicki.name>
parents:
4935
diff
changeset
|
4 local cleanup_after = module:get_option_string("audit_log_expires_after", "2w"); |
4a5837591380
mod_audit: remove event hook
Jonas Schäfer <jonas@wielicki.name>
parents:
4935
diff
changeset
|
5 |
4933
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
6 local time_now = os.time; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
7 local st = require "util.stanza"; |
4935
ae83200fb55f
mod_audit: make the extension of the module API less of a hack
Jonas Schäfer <jonas@wielicki.name>
parents:
4934
diff
changeset
|
8 local moduleapi = require "core.moduleapi"; |
4933
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 host_wide_user = "@"; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
11 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
12 local stores = {}; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
13 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
14 local function get_store(self, host) |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
15 local store = rawget(self, host); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
16 if store then |
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 |
4934
08dea42a302a
mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents:
4933
diff
changeset
|
19 store = module:context(host):open_store("audit", "archive"); |
4933
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
20 rawset(self, host, store); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
21 return store; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
22 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
23 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
24 setmetatable(stores, { __index = get_store }); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
25 |
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 local function session_extra(session) |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
28 local attr = { |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
29 xmlns = "xmpp:prosody.im/audit", |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
30 }; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
31 if session.id then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
32 attr.id = session.id; |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
33 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
34 if session.type then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
35 attr.type = session.type; |
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 local stanza = st.stanza("session", attr); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
38 if session.ip then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
39 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
|
40 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
41 return stanza |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
42 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
43 |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
44 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
|
45 if not host or host == "*" then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
46 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
|
47 end |
4934
08dea42a302a
mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents:
4933
diff
changeset
|
48 local user_key = user or host_wide_user; |
4933
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 local attr = { |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
51 ["source"] = source, |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
52 ["type"] = event_type, |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
53 }; |
4934
08dea42a302a
mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents:
4933
diff
changeset
|
54 if user_key ~= host_wide_user then |
08dea42a302a
mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents:
4933
diff
changeset
|
55 attr.user = user_key; |
4933
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
56 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
57 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
|
58 if extra ~= nil then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
59 if extra.session then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
60 local child = session_extra(extra.session); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
61 if child then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
62 stanza:add_child(child); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
63 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
64 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
65 if extra.custom then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
66 for _, child in extra.custom do |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
67 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
|
68 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
|
69 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
70 stanza:add_child(child); |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
71 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
72 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
73 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
74 |
4934
08dea42a302a
mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents:
4933
diff
changeset
|
75 local id, err = stores[host]:append(nil, nil, stanza, time_now(), user_key); |
4933
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
76 if err then |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
77 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
|
78 return |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
79 else |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
80 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
|
81 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
82 end |
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
83 |
4935
ae83200fb55f
mod_audit: make the extension of the module API less of a hack
Jonas Schäfer <jonas@wielicki.name>
parents:
4934
diff
changeset
|
84 function moduleapi.audit(module, user, event_type, extra) |
ae83200fb55f
mod_audit: make the extension of the module API less of a hack
Jonas Schäfer <jonas@wielicki.name>
parents:
4934
diff
changeset
|
85 audit(module.host, user, "mod_" .. module:get_name(), event_type, extra); |
4933
530d116b7f68
mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
86 end |