From 275c68db05889976afa52e3f979e62a112b83490 Mon Sep 17 00:00:00 2001 From: Hans Svensson Date: Thu, 26 Mar 2020 13:50:16 +0100 Subject: [PATCH] roster_friend: add a case clause to avoid crashing on bad request --- apps/roster/src/protocol/roster_friend.erl | 56 ++++++++++++---------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/apps/roster/src/protocol/roster_friend.erl b/apps/roster/src/protocol/roster_friend.erl index 069de4ff1..30ae11bf6 100644 --- a/apps/roster/src/protocol/roster_friend.erl +++ b/apps/roster/src/protocol/roster_friend.erl @@ -7,27 +7,31 @@ start() -> n2o_async:start(#handler{module = ?MODULE, class = system, group = roster, name = ?MODULE, state = []}). -info(#'Friend'{phone_id = Me, friend_id = Friend, settings = FriendSettings, status = request}, {Req, handled}, - #cx{params = ClientId, client_pid = C} = State) -> +info(#'Friend'{phone_id = Me, friend_id = Friend, settings = FriendSettings, status = request}, + {Req, handled}, #cx{params = ClientId, client_pid = C} = State) -> [From, FromId] = roster:parts_phone_id(Me), [To, ToId] = roster:parts_phone_id(Friend), - [{ok, FromR}, {ok, ToR}] = [kvs:get('Roster', Id) || Id <- [FromId, ToId]], - D = case {roster:get_contact(FromR, Friend), roster:get_contact(ToR, Me)} of - {#'Contact'{status = S1}, #'Contact'{status = S2}} when S1 =/= [];S2 =/= [] -> - #io{code = invalid_data}; - _ -> - [Mc] = roster:to_contact([FromR], authorization), - [Fc] = roster:to_contact([ToR], request), - Now = roster:now_msec(), - Mec = Mc#'Contact'{update = Now, created = Now, settings = Mc#'Contact'.settings ++ FriendSettings}, - Friendc = Fc#'Contact'{update = Now, created = Now}, - _Local = roster:add_contacts(ToR, [Mec]), - _Remote = roster:add_contacts(FromR, [Friendc]), - roster:send_ses(C, To, roster:presence(#'Contact'{reader = Rs} = roster:readmsgs(Mec, Friend))), - roster:send_ses(C, From, roster:presence(Friendc#'Contact'{reader = lists:reverse(Rs)})), - n2o_async:pid(system, ?MODULE) ! {send_push, Me, Friend, <<"request">>}, - roster:info(?MODULE, "~p:~p:Friend/request:~p", [Me, ClientId, Friend]), - <<>> + {ok, FromR} = kvs:get('Roster', FromId), + D = case kvs:get('Roster', ToId) of + {error, _} -> #io{code = invalid_data}; + {ok, ToR} -> + case {roster:get_contact(FromR, Friend), roster:get_contact(ToR, Me)} of + {#'Contact'{status = S1}, #'Contact'{status = S2}} when S1 =/= [];S2 =/= [] -> + #io{code = invalid_data}; + _ -> + [Mc] = roster:to_contact([FromR], authorization), + [Fc] = roster:to_contact([ToR], request), + Now = roster:now_msec(), + Mec = Mc#'Contact'{update = Now, created = Now, settings = Mc#'Contact'.settings ++ FriendSettings}, + Friendc = Fc#'Contact'{update = Now, created = Now}, + _Local = roster:add_contacts(ToR, [Mec]), + _Remote = roster:add_contacts(FromR, [Friendc]), + roster:send_ses(C, To, roster:presence(#'Contact'{reader = Rs} = roster:readmsgs(Mec, Friend))), + roster:send_ses(C, From, roster:presence(Friendc#'Contact'{reader = lists:reverse(Rs)})), + n2o_async:pid(system, ?MODULE) ! {send_push, Me, Friend, <<"request">>}, + roster:info(?MODULE, "~p:~p:Friend/request:~p", [Me, ClientId, Friend]), + <<>> + end end, {reply, {bert, D}, Req, State}; info(#'Friend'{phone_id = Me, status = request} = F, Req, #cx{params = ClientId} = State) -> @@ -37,11 +41,15 @@ info(#'Friend'{phone_id = Me, status = request} = F, Req, #cx{params = ClientId} __________ -> roster:info(?MODULE, "invalid client id: ~p", [ClientId]), error end, case PhoneId of - ?IS_UUID -> roster:info(?MODULE, "invalid phone id: ~p", [PhoneId]), - {reply, {bert, #io{code = {error, corrupted_db}}}, Req, State}; - Me -> info(F#'Friend'{phone_id = Me}, {Req, handled}, State); - _ -> roster:info(?MODULE, "invalid phone id: ~p", [Me]), - {reply, {bert, #io{code = {error, permission_denied}}}, Req, State} end; + ?IS_UUID -> + roster:info(?MODULE, "invalid phone id: ~p", [PhoneId]), + {reply, {bert, #io{code = {error, corrupted_db}}}, Req, State}; + Me -> + info(F#'Friend'{phone_id = Me}, {Req, handled}, State); + _ -> + roster:info(?MODULE, "invalid phone id: ~p", [Me]), + {reply, {bert, #io{code = {error, permission_denied}}}, Req, State} + end; info(#'Friend'{friend_id = Friend, status = ignore}, Req, #cx{params = ClientId, client_pid = C} = State) -> Me = roster:phone_id(ClientId), -- GitLab