summaryrefslogtreecommitdiff
path: root/src/mod_privacy.erl
diff options
context:
space:
mode:
authorNathan Bruning <nathan@iperity.com>2018-10-27 15:26:37 +0200
committerNathan Bruning <nathan@iperity.com>2019-06-10 12:49:39 +0200
commit570800a54077e2a3788768894dff909f854c435b (patch)
treead369e29cc1159929db3f9ca8d6a3b64a551d4a5 /src/mod_privacy.erl
parentFix example argument in private_set, don't include Query element (diff)
Fix mod_privacy race condition
mod_privacy updates the c2s state in user_receive_packet, which tracks the *result* of the IQ set for active privacy lists. When a second stanza is sent directly after a privacy list request, the second stanza will be processed using the old privacy list, because the IQ result has not yet been routed.
Diffstat (limited to 'src/mod_privacy.erl')
-rw-r--r--src/mod_privacy.erl21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl
index 0b534d27..0204e091 100644
--- a/src/mod_privacy.erl
+++ b/src/mod_privacy.erl
@@ -419,6 +419,27 @@ user_send_packet({#iq{type = Type,
false -> IQ
end,
{NewIQ, State};
+
+user_send_packet({#iq{type = Type,
+ from = #jid{luser = U, lserver = S},
+ to = #jid{luser = U, lserver = S},
+ sub_els = [_]} = IQ,
+ State})
+ when Type == set ->
+ case xmpp:get_subtag(IQ, #privacy_query{}) of
+ #privacy_query{active = undefined} -> {IQ, State};
+ #privacy_query{default = undefined, active = Active} ->
+ case get_user_list(U, S, Active) of
+ {ok, _} ->
+ % Adjust the client's state directly, so the next to-be-processed
+ % packet will take the active list into account.
+ {IQ, State#{privacy_active_list => Active}};
+ true ->
+ {IQ, State}
+ end;
+ _ -> {IQ, State}
+ end;
+
user_send_packet(Acc) ->
Acc.