aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cyrsasl_scram.erl79
-rw-r--r--src/mod_muc/mod_muc_room.erl34
-rw-r--r--src/mod_pubsub/mod_pubsub.erl8
3 files changed, 72 insertions, 49 deletions
diff --git a/src/cyrsasl_scram.erl b/src/cyrsasl_scram.erl
index 33d18cd1a..ee68bed1e 100644
--- a/src/cyrsasl_scram.erl
+++ b/src/cyrsasl_scram.erl
@@ -32,6 +32,8 @@
-include("ejabberd.hrl").
+-include("jlib.hrl").
+
-behaviour(cyrsasl).
-record(state,
@@ -60,8 +62,11 @@ mech_new(_Host, GetPassword, _CheckPassword,
{ok, #state{step = 2, get_password = GetPassword}}.
mech_step(#state{step = 2} = State, ClientIn) ->
- case str:tokens(ClientIn, <<",">>) of
- [CBind, UserNameAttribute, ClientNonceAttribute]
+ case re:split(ClientIn, <<",">>, [{return, binary}]) of
+ [_CBind, _AuthorizationIdentity, _UserNameAttribute, _ClientNonceAttribute, ExtensionAttribute | _]
+ when ExtensionAttribute /= [] ->
+ {error, <<"protocol-error-extension-not-supported">>};
+ [CBind, _AuthorizationIdentity, UserNameAttribute, ClientNonceAttribute | _]
when (CBind == <<"y">>) or (CBind == <<"n">>) ->
case parse_attribute(UserNameAttribute) of
{error, Reason} -> {error, Reason};
@@ -123,42 +128,44 @@ mech_step(#state{step = 4} = State, ClientIn) ->
[GS2ChannelBindingAttribute, NonceAttribute,
ClientProofAttribute] ->
case parse_attribute(GS2ChannelBindingAttribute) of
- {$c, CVal} when (CVal == <<"biws">>) or (CVal == <<"eSws">>) ->
- %% biws is base64 for n,, => channelbinding not supported
- %% eSws is base64 for y,, => channelbinding supported by client only
- Nonce = <<(State#state.client_nonce)/binary,
- (State#state.server_nonce)/binary>>,
- case parse_attribute(NonceAttribute) of
- {$r, CompareNonce} when CompareNonce == Nonce ->
- case parse_attribute(ClientProofAttribute) of
- {$p, ClientProofB64} ->
- ClientProof = jlib:decode_base64(ClientProofB64),
- AuthMessage =
- iolist_to_binary(
- [State#state.auth_message,
- ",",
- str:substr(ClientIn, 1,
- str:str(ClientIn, <<",p=">>)
- - 1)]),
- ClientSignature =
- scram:client_signature(State#state.stored_key,
- AuthMessage),
- ClientKey = scram:client_key(ClientProof,
- ClientSignature),
- CompareStoredKey = scram:stored_key(ClientKey),
- if CompareStoredKey == State#state.stored_key ->
- ServerSignature =
- scram:server_signature(State#state.server_key,
- AuthMessage),
- {ok, [{username, State#state.username}],
- <<"v=",
- (jlib:encode_base64(ServerSignature))/binary>>};
- true -> {error, <<"bad-auth">>}
+ {$c, CVal} ->
+ ChannelBindingSupport = binary:at(jlib:decode_base64(CVal), 0),
+ if (ChannelBindingSupport == $n)
+ or (ChannelBindingSupport == $y) ->
+ Nonce = <<(State#state.client_nonce)/binary,
+ (State#state.server_nonce)/binary>>,
+ case parse_attribute(NonceAttribute) of
+ {$r, CompareNonce} when CompareNonce == Nonce ->
+ case parse_attribute(ClientProofAttribute) of
+ {$p, ClientProofB64} ->
+ ClientProof = jlib:decode_base64(ClientProofB64),
+ AuthMessage = iolist_to_binary(
+ [State#state.auth_message,
+ ",",
+ str:substr(ClientIn, 1,
+ str:str(ClientIn, <<",p=">>)
+ - 1)]),
+ ClientSignature =
+ scram:client_signature(State#state.stored_key,
+ AuthMessage),
+ ClientKey = scram:client_key(ClientProof,
+ ClientSignature),
+ CompareStoredKey = scram:stored_key(ClientKey),
+ if CompareStoredKey == State#state.stored_key ->
+ ServerSignature =
+ scram:server_signature(State#state.server_key,
+ AuthMessage),
+ {ok, [{username, State#state.username}],
+ <<"v=",
+ (jlib:encode_base64(ServerSignature))/binary>>};
+ true -> {error, <<"bad-auth">>}
+ end;
+ _Else -> {error, <<"bad-protocol">>}
end;
+ {$r, _} -> {error, <<"bad-nonce">>};
_Else -> {error, <<"bad-protocol">>}
- end;
- {$r, _} -> {error, <<"bad-nonce">>};
- _Else -> {error, <<"bad-protocol">>}
+ end;
+ true -> {error, <<"bad-channel-binding">>}
end;
_Else -> {error, <<"bad-protocol">>}
end;
diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl
index d54143956..61ec57766 100644
--- a/src/mod_muc/mod_muc_room.erl
+++ b/src/mod_muc/mod_muc_room.erl
@@ -2593,7 +2593,7 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
SD;
{JID, role, none, Reason} ->
catch
- send_kickban_presence(JID,
+ send_kickban_presence(UJID, JID,
Reason,
<<"307">>,
SD),
@@ -2605,7 +2605,7 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
of
true ->
catch
- send_kickban_presence(JID,
+ send_kickban_presence(UJID, JID,
Reason,
<<"321">>,
none,
@@ -2628,7 +2628,7 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
{JID, affiliation, outcast,
Reason} ->
catch
- send_kickban_presence(JID,
+ send_kickban_presence(UJID, JID,
Reason,
<<"301">>,
outcast,
@@ -2979,12 +2979,12 @@ can_change_ra(_FAffiliation, _FRole, _TAffiliation,
_TRole, role, _Value, _ServiceAf) ->
false.
-send_kickban_presence(JID, Reason, Code, StateData) ->
+send_kickban_presence(UJID, JID, Reason, Code, StateData) ->
NewAffiliation = get_affiliation(JID, StateData),
- send_kickban_presence(JID, Reason, Code, NewAffiliation,
+ send_kickban_presence(UJID, JID, Reason, Code, NewAffiliation,
StateData).
-send_kickban_presence(JID, Reason, Code, NewAffiliation,
+send_kickban_presence(UJID, JID, Reason, Code, NewAffiliation,
StateData) ->
LJID = jlib:jid_tolower(JID),
LJIDs = case LJID of
@@ -3007,18 +3007,26 @@ send_kickban_presence(JID, Reason, Code, NewAffiliation,
StateData#state.users),
add_to_log(kickban, {Nick, Reason, Code}, StateData),
tab_remove_online_user(J, StateData),
- send_kickban_presence1(J, Reason, Code,
+ send_kickban_presence1(UJID, J, Reason, Code,
NewAffiliation, StateData)
end,
LJIDs).
-send_kickban_presence1(UJID, Reason, Code, Affiliation,
+send_kickban_presence1(MJID, UJID, Reason, Code, Affiliation,
StateData) ->
{ok, #user{jid = RealJID, nick = Nick}} =
(?DICT):find(jlib:jid_tolower(UJID),
StateData#state.users),
SAffiliation = affiliation_to_list(Affiliation),
BannedJIDString = jlib:jid_to_string(RealJID),
+ case MJID /= <<"">> of
+ true ->
+ {ok, #user{nick = ActorNick}} =
+ (?DICT):find(jlib:jid_tolower(MJID),
+ StateData#state.users);
+ false ->
+ ActorNick = <<"">>
+ end,
lists:foreach(fun ({_LJID, Info}) ->
JidAttrList = case Info#user.role == moderator orelse
(StateData#state.config)#config.anonymous
@@ -3039,6 +3047,12 @@ send_kickban_presence1(UJID, Reason, Code, Affiliation,
children =
[{xmlcdata, Reason}]}]
end,
+ ItemElsActor = case MJID of
+ <<"">> -> [];
+ _ -> [#xmlel{name = <<"actor">>,
+ attrs =
+ [{<<"nick">>, ActorNick}]}]
+ end,
Packet = #xmlel{name = <<"presence">>,
attrs =
[{<<"type">>, <<"unavailable">>}],
@@ -3053,7 +3067,7 @@ send_kickban_presence1(UJID, Reason, Code, Affiliation,
attrs =
ItemAttrs,
children =
- ItemEls},
+ ItemElsActor ++ ItemEls},
#xmlel{name =
<<"status">>,
attrs =
@@ -3751,7 +3765,7 @@ remove_nonmembers(StateData) ->
Affiliation = get_affiliation(JID, SD),
case Affiliation of
none ->
- catch send_kickban_presence(JID, <<"">>,
+ catch send_kickban_presence(<<"">>, JID, <<"">>,
<<"322">>, SD),
set_role(JID, none, SD);
_ -> SD
diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index 5f1d38e7d..53b32d9de 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -1977,7 +1977,7 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) ->
[#xmlel{name = <<"item">>, attrs = ItemAttrs,
children = Payload}] ->
ItemId = xml:get_attr_s(<<"id">>, ItemAttrs),
- publish_item(Host, ServerHost, Node, From, ItemId, Payload);
+ publish_item(Host, ServerHost, Node, From, ItemId, Payload, Access);
[] ->
{error,
extended_error(?ERR_BAD_REQUEST, <<"item-required">>)};
@@ -2948,8 +2948,10 @@ unsubscribe_node(Host, Node, From, Subscriber, SubId) ->
| {error, xmlel()}
).
publish_item(Host, ServerHost, Node, Publisher, <<>>, Payload) ->
- publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload);
+ publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload, all);
publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
+ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, all).
+publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, Access) ->
Action = fun (#pubsub_node{options = Options, type = Type, id = NodeId}) ->
Features = features(Type),
PublishFeature = lists:member(<<"publish">>, Features),
@@ -3045,7 +3047,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
Type = select_type(ServerHost, Host, Node),
case lists:member("auto-create", features(Type)) of
true ->
- case create_node(Host, ServerHost, Node, Publisher, Type) of
+ case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of
{result, [#xmlel{name = <<"pubsub">>,
attrs = [{<<"xmlns">>, ?NS_PUBSUB}],
children =