mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* (all): Changed JID storage format, added support for stringprep
* src/stringprep/: Added support for Unicode normalization form KC * src/stringprep/: Added support for case convertion to multiple characters * src/cyrsasl_digest.erl: Temporary removed "auth-int" QOP SVN Revision: 144
This commit is contained in:
parent
e1de741cfc
commit
61875f80b3
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
2003-10-07 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* (all): Changed JID storage format, added support for stringprep
|
||||||
|
|
||||||
|
* src/stringprep/: Added support for Unicode normalization form KC
|
||||||
|
|
||||||
|
2003-10-05 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/stringprep/: Added support for case convertion to multiple
|
||||||
|
characters
|
||||||
|
|
||||||
|
* src/cyrsasl_digest.erl: Temporary removed "auth-int" QOP
|
||||||
|
|
||||||
2003-09-28 Alexey Shchepin <alexey@sevcom.net>
|
2003-09-28 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/stringprep/stringprep_drv.c: Added support for nameprep,
|
* src/stringprep/stringprep_drv.c: Added support for nameprep,
|
||||||
|
@ -49,7 +49,7 @@ check_authzid(State, Props) ->
|
|||||||
error ->
|
error ->
|
||||||
{error, "invalid-authzid"};
|
{error, "invalid-authzid"};
|
||||||
JID ->
|
JID ->
|
||||||
LUser = xml:get_attr_s(username, Props),
|
LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
||||||
{U, S, R} = jlib:jid_tolower(JID),
|
{U, S, R} = jlib:jid_tolower(JID),
|
||||||
case R of
|
case R of
|
||||||
"" ->
|
"" ->
|
||||||
|
@ -34,7 +34,8 @@ mech_new() ->
|
|||||||
mech_step(#state{step = 1, nonce = Nonce} = State, "") ->
|
mech_step(#state{step = 1, nonce = Nonce} = State, "") ->
|
||||||
{continue,
|
{continue,
|
||||||
"nonce=\"" ++ jlib:encode_base64(Nonce) ++
|
"nonce=\"" ++ jlib:encode_base64(Nonce) ++
|
||||||
"\",qop=\"auth,auth-int\",charset=utf-8,algorithm=md5-sess",
|
"\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
|
||||||
|
%"\",qop=\"auth,auth-int\",charset=utf-8,algorithm=md5-sess",
|
||||||
State#state{step = 3}};
|
State#state{step = 3}};
|
||||||
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||||
case parse(ClientIn) of
|
case parse(ClientIn) of
|
||||||
|
@ -109,7 +109,7 @@ terminate(Reason, State) ->
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
check_password(User, Password) ->
|
check_password(User, Password) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||||
[#passwd{password = Password}] ->
|
[#passwd{password = Password}] ->
|
||||||
true;
|
true;
|
||||||
@ -118,7 +118,7 @@ check_password(User, Password) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
check_password(User, Password, StreamID, Digest) ->
|
check_password(User, Password, StreamID, Digest) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
case mnesia:read({passwd, LUser}) of
|
case mnesia:read({passwd, LUser}) of
|
||||||
[E] ->
|
[E] ->
|
||||||
@ -144,14 +144,14 @@ check_password(User, Password, StreamID, Digest) ->
|
|||||||
|
|
||||||
|
|
||||||
set_password(User, Password) ->
|
set_password(User, Password) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:write(#passwd{user = LUser, password = Password})
|
mnesia:write(#passwd{user = LUser, password = Password})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
try_register(User, Password) ->
|
try_register(User, Password) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
case mnesia:read({passwd, LUser}) of
|
case mnesia:read({passwd, LUser}) of
|
||||||
[] ->
|
[] ->
|
||||||
@ -168,7 +168,7 @@ dirty_get_registered_users() ->
|
|||||||
mnesia:dirty_all_keys(passwd).
|
mnesia:dirty_all_keys(passwd).
|
||||||
|
|
||||||
get_password(User) ->
|
get_password(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case catch mnesia:dirty_read(passwd, LUser) of
|
case catch mnesia:dirty_read(passwd, LUser) of
|
||||||
[#passwd{password = Password}] ->
|
[#passwd{password = Password}] ->
|
||||||
Password;
|
Password;
|
||||||
@ -177,7 +177,7 @@ get_password(User) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_password_s(User) ->
|
get_password_s(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case catch mnesia:dirty_read(passwd, LUser) of
|
case catch mnesia:dirty_read(passwd, LUser) of
|
||||||
[#passwd{password = Password}] ->
|
[#passwd{password = Password}] ->
|
||||||
Password;
|
Password;
|
||||||
@ -186,7 +186,7 @@ get_password_s(User) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
is_user_exists(User) ->
|
is_user_exists(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||||
[] ->
|
[] ->
|
||||||
false;
|
false;
|
||||||
@ -197,14 +197,14 @@ is_user_exists(User) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user(User) ->
|
remove_user(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:delete({passwd, LUser})
|
mnesia:delete({passwd, LUser})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
remove_user(User, Password) ->
|
remove_user(User, Password) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
case mnesia:read({passwd, LUser}) of
|
case mnesia:read({passwd, LUser}) of
|
||||||
[#passwd{password = Password}] ->
|
[#passwd{password = Password}] ->
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
access,
|
access,
|
||||||
shaper,
|
shaper,
|
||||||
authentificated = false,
|
authentificated = false,
|
||||||
|
jid,
|
||||||
user = "", server = ?MYNAME, resource = "",
|
user = "", server = ?MYNAME, resource = "",
|
||||||
pres_t = ?SETS:new(),
|
pres_t = ?SETS:new(),
|
||||||
pres_f = ?SETS:new(),
|
pres_f = ?SETS:new(),
|
||||||
@ -205,7 +206,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
{next_state, wait_for_auth, StateData};
|
{next_state, wait_for_auth, StateData};
|
||||||
{auth, ID, set, {U, P, D, R}} ->
|
{auth, ID, set, {U, P, D, R}} ->
|
||||||
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
||||||
JID = {U, ?MYNAME, R},
|
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||||
case acl:match_rule(StateData#state.access, JID) of
|
case acl:match_rule(StateData#state.access, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
case ejabberd_auth:check_password(
|
case ejabberd_auth:check_password(
|
||||||
@ -224,6 +225,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
{next_state, session_established,
|
{next_state, session_established,
|
||||||
StateData#state{user = U,
|
StateData#state{user = U,
|
||||||
resource = R,
|
resource = R,
|
||||||
|
jid = JID,
|
||||||
pres_f = ?SETS:from_list(Fs),
|
pres_f = ?SETS:from_list(Fs),
|
||||||
pres_t = ?SETS:from_list(Ts),
|
pres_t = ?SETS:from_list(Ts),
|
||||||
privacy_list = PrivList}};
|
privacy_list = PrivList}};
|
||||||
@ -281,12 +283,14 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "success",
|
{xmlelement, "success",
|
||||||
[{"xmlns", ?NS_SASL}], []}),
|
[{"xmlns", ?NS_SASL}], []}),
|
||||||
{U, _, R} = jlib:string_to_jid(
|
JID = #jid{user = U, resource = R} =
|
||||||
|
jlib:string_to_jid(
|
||||||
xml:get_attr_s(authzid, Props)),
|
xml:get_attr_s(authzid, Props)),
|
||||||
{next_state, wait_for_stream,
|
{next_state, wait_for_stream,
|
||||||
StateData#state{authentificated = true,
|
StateData#state{authentificated = true,
|
||||||
user = U,
|
user = U,
|
||||||
resource = R
|
resource = R,
|
||||||
|
jid = JID
|
||||||
}};
|
}};
|
||||||
{continue, ServerOut, NewSASLState} ->
|
{continue, ServerOut, NewSASLState} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
@ -344,12 +348,13 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
|||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
{xmlelement, "success",
|
{xmlelement, "success",
|
||||||
[{"xmlns", ?NS_SASL}], []}),
|
[{"xmlns", ?NS_SASL}], []}),
|
||||||
{U, _, R} = jlib:string_to_jid(
|
JID = #jid{user = U, resource = R} =
|
||||||
xml:get_attr_s(authzid, Props)),
|
jlib:string_to_jid(xml:get_attr_s(authzid, Props)),
|
||||||
{next_state, wait_for_stream,
|
{next_state, wait_for_stream,
|
||||||
StateData#state{authentificated = true,
|
StateData#state{authentificated = true,
|
||||||
user = U,
|
user = U,
|
||||||
resource = R
|
resource = R,
|
||||||
|
jid = JID
|
||||||
}};
|
}};
|
||||||
{continue, ServerOut, NewSASLState} ->
|
{continue, ServerOut, NewSASLState} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
@ -402,7 +407,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
|||||||
U = StateData#state.user,
|
U = StateData#state.user,
|
||||||
R = StateData#state.resource,
|
R = StateData#state.resource,
|
||||||
io:format("SASLAUTH: ~p~n", [{U, R}]),
|
io:format("SASLAUTH: ~p~n", [{U, R}]),
|
||||||
JID = {U, ?MYNAME, R},
|
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||||
case acl:match_rule(StateData#state.access, JID) of
|
case acl:match_rule(StateData#state.access, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
ejabberd_sm:open_session(U, R),
|
ejabberd_sm:open_session(U, R),
|
||||||
@ -457,13 +462,14 @@ session_established({xmlstreamelement, El}, StateData) ->
|
|||||||
{xmlelement, Name, Attrs, Els} = El,
|
{xmlelement, Name, Attrs, Els} = El,
|
||||||
User = StateData#state.user,
|
User = StateData#state.user,
|
||||||
Server = StateData#state.server,
|
Server = StateData#state.server,
|
||||||
FromJID = {User,
|
%FromJID = {User,
|
||||||
Server,
|
% Server,
|
||||||
StateData#state.resource},
|
% StateData#state.resource},
|
||||||
|
FromJID = StateData#state.jid,
|
||||||
To = xml:get_attr_s("to", Attrs),
|
To = xml:get_attr_s("to", Attrs),
|
||||||
ToJID = case To of
|
ToJID = case To of
|
||||||
"" ->
|
"" ->
|
||||||
{User, Server, ""};
|
jlib:make_jid(User, Server, "");
|
||||||
_ ->
|
_ ->
|
||||||
jlib:string_to_jid(To)
|
jlib:string_to_jid(To)
|
||||||
end,
|
end,
|
||||||
@ -476,7 +482,9 @@ session_established({xmlstreamelement, El}, StateData) ->
|
|||||||
case Name of
|
case Name of
|
||||||
"presence" ->
|
"presence" ->
|
||||||
case ToJID of
|
case ToJID of
|
||||||
{User, Server, ""} ->
|
#jid{user = User,
|
||||||
|
server = Server,
|
||||||
|
resource = ""} ->
|
||||||
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
|
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
|
||||||
[FromJID, El, StateData]),
|
[FromJID, El, StateData]),
|
||||||
presence_update(FromJID, El, StateData);
|
presence_update(FromJID, El, StateData);
|
||||||
@ -573,7 +581,6 @@ handle_info(replaced, StateName, StateData) ->
|
|||||||
{stop, normal, StateData#state{user = ""}};
|
{stop, normal, StateData#state{user = ""}};
|
||||||
handle_info({route, From, To, Packet}, StateName, StateData) ->
|
handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||||
{xmlelement, Name, Attrs, Els} = Packet,
|
{xmlelement, Name, Attrs, Els} = Packet,
|
||||||
{FU, FS, FR} = From,
|
|
||||||
{Pass, NewAttrs, NewState} =
|
{Pass, NewAttrs, NewState} =
|
||||||
case Name of
|
case Name of
|
||||||
"presence" ->
|
"presence" ->
|
||||||
@ -694,9 +701,7 @@ terminate(Reason, StateName, StateData) ->
|
|||||||
_ ->
|
_ ->
|
||||||
ejabberd_sm:close_session(StateData#state.user,
|
ejabberd_sm:close_session(StateData#state.user,
|
||||||
StateData#state.resource),
|
StateData#state.resource),
|
||||||
From = {StateData#state.user,
|
From = StateData#state.jid,
|
||||||
StateData#state.server,
|
|
||||||
StateData#state.resource},
|
|
||||||
Packet = {xmlelement, "presence", [{"type", "unavailable"}], []},
|
Packet = {xmlelement, "presence", [{"type", "unavailable"}], []},
|
||||||
ejabberd_sm:unset_presence(StateData#state.user,
|
ejabberd_sm:unset_presence(StateData#state.user,
|
||||||
StateData#state.resource),
|
StateData#state.resource),
|
||||||
@ -797,16 +802,17 @@ get_auth_tags([], U, P, D, R) ->
|
|||||||
|
|
||||||
|
|
||||||
process_presence_probe(From, To, StateData) ->
|
process_presence_probe(From, To, StateData) ->
|
||||||
|
LFrom = jlib:jid_tolower(From),
|
||||||
case StateData#state.pres_last of
|
case StateData#state.pres_last of
|
||||||
undefined ->
|
undefined ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
Cond1 = (not StateData#state.pres_invis)
|
Cond1 = (not StateData#state.pres_invis)
|
||||||
and ?SETS:is_element(From, StateData#state.pres_f)
|
and ?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||||
and (not ?SETS:is_element(From, StateData#state.pres_i)),
|
and (not ?SETS:is_element(LFrom, StateData#state.pres_i)),
|
||||||
Cond2 = StateData#state.pres_invis
|
Cond2 = StateData#state.pres_invis
|
||||||
and ?SETS:is_element(From, StateData#state.pres_f)
|
and ?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||||
and ?SETS:is_element(From, StateData#state.pres_a),
|
and ?SETS:is_element(LFrom, StateData#state.pres_a),
|
||||||
if
|
if
|
||||||
Cond1 ->
|
Cond1 ->
|
||||||
ejabberd_router:route(To, From,
|
ejabberd_router:route(To, From,
|
||||||
@ -934,14 +940,16 @@ presence_track(From, To, Packet, StateData) ->
|
|||||||
|
|
||||||
presence_broadcast(From, JIDSet, Packet) ->
|
presence_broadcast(From, JIDSet, Packet) ->
|
||||||
lists:foreach(fun(JID) ->
|
lists:foreach(fun(JID) ->
|
||||||
ejabberd_router:route(From, JID, Packet)
|
ejabberd_router:route(
|
||||||
|
From, jlib:make_jid(JID), Packet)
|
||||||
end, ?SETS:to_list(JIDSet)).
|
end, ?SETS:to_list(JIDSet)).
|
||||||
|
|
||||||
presence_broadcast_to_trusted(From, T, A, Packet) ->
|
presence_broadcast_to_trusted(From, T, A, Packet) ->
|
||||||
lists:foreach(fun(JID) ->
|
lists:foreach(fun(JID) ->
|
||||||
case ?SETS:is_element(JID, T) of
|
case ?SETS:is_element(JID, T) of
|
||||||
true ->
|
true ->
|
||||||
ejabberd_router:route(From, JID, Packet);
|
ejabberd_router:route(
|
||||||
|
From, jlib:make_jid(JID), Packet);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
@ -949,9 +957,10 @@ presence_broadcast_to_trusted(From, T, A, Packet) ->
|
|||||||
|
|
||||||
|
|
||||||
presence_broadcast_first(From, StateData, Packet) ->
|
presence_broadcast_first(From, StateData, Packet) ->
|
||||||
{U, S, _} = From,
|
|
||||||
?SETS:fold(fun(JID, X) ->
|
?SETS:fold(fun(JID, X) ->
|
||||||
ejabberd_router:route({U, S, ""}, JID,
|
ejabberd_router:route(
|
||||||
|
jlib:jid_replace_resource(From, ""),
|
||||||
|
jlib:make_jid(JID),
|
||||||
{xmlelement, "presence",
|
{xmlelement, "presence",
|
||||||
[{"type", "probe"}],
|
[{"type", "probe"}],
|
||||||
[]}),
|
[]}),
|
||||||
@ -964,7 +973,9 @@ presence_broadcast_first(From, StateData, Packet) ->
|
|||||||
StateData;
|
StateData;
|
||||||
true ->
|
true ->
|
||||||
As = ?SETS:fold(fun(JID, A) ->
|
As = ?SETS:fold(fun(JID, A) ->
|
||||||
ejabberd_router:route(From, JID, Packet),
|
ejabberd_router:route(From,
|
||||||
|
jlib:make_jid(JID),
|
||||||
|
Packet),
|
||||||
?SETS:add_element(JID, A)
|
?SETS:add_element(JID, A)
|
||||||
end,
|
end,
|
||||||
StateData#state.pres_a,
|
StateData#state.pres_a,
|
||||||
@ -1003,9 +1014,7 @@ roster_change(IJID, ISubscription, StateData) ->
|
|||||||
StateData#state{pres_f = FSet, pres_t = TSet};
|
StateData#state{pres_f = FSet, pres_t = TSet};
|
||||||
P ->
|
P ->
|
||||||
?DEBUG("roster changed for ~p~n", [StateData#state.user]),
|
?DEBUG("roster changed for ~p~n", [StateData#state.user]),
|
||||||
From = {StateData#state.user,
|
From = StateData#state.jid,
|
||||||
StateData#state.server,
|
|
||||||
StateData#state.resource},
|
|
||||||
Cond1 = (not StateData#state.pres_invis) and IsFrom,
|
Cond1 = (not StateData#state.pres_invis) and IsFrom,
|
||||||
Cond2 = (not IsFrom)
|
Cond2 = (not IsFrom)
|
||||||
and (?SETS:is_element(LIJID, StateData#state.pres_a) or
|
and (?SETS:is_element(LIJID, StateData#state.pres_a) or
|
||||||
@ -1013,7 +1022,7 @@ roster_change(IJID, ISubscription, StateData) ->
|
|||||||
if
|
if
|
||||||
Cond1 ->
|
Cond1 ->
|
||||||
?DEBUG("C1: ~p~n", [LIJID]),
|
?DEBUG("C1: ~p~n", [LIJID]),
|
||||||
ejabberd_router:route(From, IJID, P),
|
ejabberd_router:route(From, jlib:make_jid(IJID), P),
|
||||||
A = ?SETS:add_element(LIJID,
|
A = ?SETS:add_element(LIJID,
|
||||||
StateData#state.pres_a),
|
StateData#state.pres_a),
|
||||||
StateData#state{pres_a = A,
|
StateData#state{pres_a = A,
|
||||||
@ -1021,7 +1030,7 @@ roster_change(IJID, ISubscription, StateData) ->
|
|||||||
pres_t = TSet};
|
pres_t = TSet};
|
||||||
Cond2 ->
|
Cond2 ->
|
||||||
?DEBUG("C2: ~p~n", [LIJID]),
|
?DEBUG("C2: ~p~n", [LIJID]),
|
||||||
ejabberd_router:route(From, IJID,
|
ejabberd_router:route(From, jlib:make_jid(IJID),
|
||||||
{xmlelement, "presence",
|
{xmlelement, "presence",
|
||||||
[{"type", "unavailable"}], []}),
|
[{"type", "unavailable"}], []}),
|
||||||
I = remove_element(LIJID,
|
I = remove_element(LIJID,
|
||||||
|
@ -71,7 +71,7 @@ do_route(State, From, To, Packet) ->
|
|||||||
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||||
[From, To, Packet, 8]),
|
[From, To, Packet, 8]),
|
||||||
case To of
|
case To of
|
||||||
{"", _, ""} ->
|
#jid{luser = "", lresource = ""} ->
|
||||||
{xmlelement, Name, Attrs, Els} = Packet,
|
{xmlelement, Name, Attrs, Els} = Packet,
|
||||||
case Name of
|
case Name of
|
||||||
"iq" ->
|
"iq" ->
|
||||||
@ -83,11 +83,12 @@ do_route(State, From, To, Packet) ->
|
|||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
{"", _, _} ->
|
#jid{luser = ""} ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
|
Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
|
||||||
ejabberd_router ! {route,
|
ejabberd_router ! {route,
|
||||||
{"", State#state.mydomain, ""}, From, Err},
|
jlib:make_jid("", State#state.mydomain, ""),
|
||||||
ok;
|
From,
|
||||||
|
Err};
|
||||||
_ ->
|
_ ->
|
||||||
ejabberd_sm ! {route, From, To, Packet}
|
ejabberd_sm ! {route, From, To, Packet}
|
||||||
end.
|
end.
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
-export([start_link/0, init/0]).
|
-export([start_link/0, init/0]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
-include("jlib.hrl").
|
||||||
|
|
||||||
-record(route, {domain, node, pid}).
|
-record(route, {domain, node, pid}).
|
||||||
-record(local_route, {domain, pid}).
|
-record(local_route, {domain, pid}).
|
||||||
@ -101,8 +102,7 @@ loop() ->
|
|||||||
|
|
||||||
do_route(From, To, Packet) ->
|
do_route(From, To, Packet) ->
|
||||||
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
|
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
|
||||||
{DstNode, DstDomain, DstResourse} = To,
|
#jid{lserver = LDstDomain} = To,
|
||||||
LDstDomain = jlib:tolower(DstDomain),
|
|
||||||
case mnesia:dirty_read({local_route, LDstDomain}) of
|
case mnesia:dirty_read({local_route, LDstDomain}) of
|
||||||
[] ->
|
[] ->
|
||||||
case mnesia:dirty_read({route, LDstDomain}) of
|
case mnesia:dirty_read({route, LDstDomain}) of
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
-include_lib("mnemosyne/include/mnemosyne.hrl").
|
-include_lib("mnemosyne/include/mnemosyne.hrl").
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
-include("jlib.hrl").
|
||||||
|
|
||||||
-record(s2s, {fromto, node, key}).
|
-record(s2s, {fromto, node, key}).
|
||||||
-record(local_s2s, {fromto, pid}).
|
-record(local_s2s, {fromto, pid}).
|
||||||
@ -148,8 +149,8 @@ try_register(FromTo) ->
|
|||||||
do_route(From, To, Packet) ->
|
do_route(From, To, Packet) ->
|
||||||
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||||
[From, To, Packet, 8]),
|
[From, To, Packet, 8]),
|
||||||
{_, MyServer, _} = From,
|
#jid{lserver = MyServer} = From,
|
||||||
{User, Server, Resource} = To,
|
#jid{lserver = Server} = To,
|
||||||
FromTo = {MyServer, Server},
|
FromTo = {MyServer, Server},
|
||||||
Key = randoms:get_string(),
|
Key = randoms:get_string(),
|
||||||
case find_connection(FromTo, Key) of
|
case find_connection(FromTo, Key) of
|
||||||
|
@ -266,7 +266,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
|||||||
From = xml:get_attr_s("from", Attrs),
|
From = xml:get_attr_s("from", Attrs),
|
||||||
FromJID1 = jlib:string_to_jid(From),
|
FromJID1 = jlib:string_to_jid(From),
|
||||||
FromJID = case FromJID1 of
|
FromJID = case FromJID1 of
|
||||||
{Node, Server, Resource} ->
|
#jid{lserver = Server} ->
|
||||||
if Server == StateData#state.server -> FromJID1;
|
if Server == StateData#state.server -> FromJID1;
|
||||||
true -> error
|
true -> error
|
||||||
end;
|
end;
|
||||||
|
@ -102,7 +102,7 @@ close_session(User, Resource) ->
|
|||||||
|
|
||||||
|
|
||||||
register_connection(User, Resource, Pid) ->
|
register_connection(User, Resource, Pid) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
UR = {LUser, Resource},
|
UR = {LUser, Resource},
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
Ss = mnesia:wread({session, UR}),
|
Ss = mnesia:wread({session, UR}),
|
||||||
@ -132,7 +132,7 @@ register_connection(User, Resource, Pid) ->
|
|||||||
|
|
||||||
|
|
||||||
replace_my_connection(User, Resource) ->
|
replace_my_connection(User, Resource) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
UR = {LUser, Resource},
|
UR = {LUser, Resource},
|
||||||
Es = mnesia:read({local_session, UR}),
|
Es = mnesia:read({local_session, UR}),
|
||||||
@ -151,7 +151,7 @@ replace_my_connection(User, Resource) ->
|
|||||||
|
|
||||||
|
|
||||||
remove_connection(User, Resource) ->
|
remove_connection(User, Resource) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
UR = {LUser, Resource},
|
UR = {LUser, Resource},
|
||||||
mnesia:delete({local_session, UR}),
|
mnesia:delete({local_session, UR}),
|
||||||
@ -177,33 +177,34 @@ clean_table_from_bad_node(Node) ->
|
|||||||
do_route(From, To, Packet) ->
|
do_route(From, To, Packet) ->
|
||||||
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||||
[From, To, Packet, 8]),
|
[From, To, Packet, 8]),
|
||||||
{User, Server, Resource} = To,
|
#jid{user = User, server = Server, resource = Resource,
|
||||||
|
luser = LUser, lserver = LServer, lresource = LResource} = To,
|
||||||
{xmlelement, Name, Attrs, Els} = Packet,
|
{xmlelement, Name, Attrs, Els} = Packet,
|
||||||
case Resource of
|
case Resource of
|
||||||
"" ->
|
"" ->
|
||||||
case Name of
|
case Name of
|
||||||
"presence" ->
|
"presence" ->
|
||||||
{FU, FS, FR} = From,
|
FromU = jlib:jid_replace_resource(From, ""),
|
||||||
{Pass, Subsc} =
|
{Pass, Subsc} =
|
||||||
case xml:get_attr_s("type", Attrs) of
|
case xml:get_attr_s("type", Attrs) of
|
||||||
"subscribe" ->
|
"subscribe" ->
|
||||||
{mod_roster:in_subscription(User,
|
{mod_roster:in_subscription(User,
|
||||||
{FU, FS, ""},
|
FromU,
|
||||||
subscribe),
|
subscribe),
|
||||||
true};
|
true};
|
||||||
"subscribed" ->
|
"subscribed" ->
|
||||||
{mod_roster:in_subscription(User,
|
{mod_roster:in_subscription(User,
|
||||||
{FU, FS, ""},
|
FromU,
|
||||||
subscribed),
|
subscribed),
|
||||||
true};
|
true};
|
||||||
"unsubscribe" ->
|
"unsubscribe" ->
|
||||||
{mod_roster:in_subscription(User,
|
{mod_roster:in_subscription(User,
|
||||||
{FU, FS, ""},
|
FromU,
|
||||||
unsubscribe),
|
unsubscribe),
|
||||||
true};
|
true};
|
||||||
"unsubscribed" ->
|
"unsubscribed" ->
|
||||||
{mod_roster:in_subscription(User,
|
{mod_roster:in_subscription(User,
|
||||||
{FU, FS, ""},
|
FromU,
|
||||||
unsubscribed),
|
unsubscribed),
|
||||||
true};
|
true};
|
||||||
_ ->
|
_ ->
|
||||||
@ -211,8 +212,6 @@ do_route(From, To, Packet) ->
|
|||||||
end,
|
end,
|
||||||
if Pass ->
|
if Pass ->
|
||||||
LFrom = jlib:jid_tolower(From),
|
LFrom = jlib:jid_tolower(From),
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
LServer = jlib:tolower(Server),
|
|
||||||
Resources = get_user_resources(User),
|
Resources = get_user_resources(User),
|
||||||
if
|
if
|
||||||
Resources /= [] ->
|
Resources /= [] ->
|
||||||
@ -223,7 +222,7 @@ do_route(From, To, Packet) ->
|
|||||||
ejabberd_sm !
|
ejabberd_sm !
|
||||||
{route,
|
{route,
|
||||||
From,
|
From,
|
||||||
{User, Server, R},
|
jlib:jid_replace_resource(To, R),
|
||||||
Packet};
|
Packet};
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
@ -250,21 +249,25 @@ do_route(From, To, Packet) ->
|
|||||||
fun(R) ->
|
fun(R) ->
|
||||||
ejabberd_sm ! {route,
|
ejabberd_sm ! {route,
|
||||||
From,
|
From,
|
||||||
{User, Server, R},
|
jlib:jid_replace_resource(To, R),
|
||||||
Packet}
|
Packet}
|
||||||
end, get_user_resources(User));
|
end, get_user_resources(User));
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
LUR = {jlib:tolower(User), Resource},
|
LUR = {LUser, LResource},
|
||||||
Sess = mnesia:dirty_read({session, LUR}),
|
Sess = mnesia:dirty_read({session, LUR}),
|
||||||
case Sess of
|
case Sess of
|
||||||
[] ->
|
[] ->
|
||||||
if
|
case Name of
|
||||||
Name == "message" ->
|
"message" ->
|
||||||
route_message(From, To, Packet);
|
route_message(From, To, Packet);
|
||||||
true ->
|
"iq" ->
|
||||||
|
Err = jlib:make_error_reply(
|
||||||
|
Packet, ?ERR_RECIPIENT_UNAVAILABLE),
|
||||||
|
ejabberd_router:route(To, From, Err);
|
||||||
|
_ ->
|
||||||
?DEBUG("packet droped~n", [])
|
?DEBUG("packet droped~n", [])
|
||||||
end;
|
end;
|
||||||
[Ses] ->
|
[Ses] ->
|
||||||
@ -282,10 +285,10 @@ do_route(From, To, Packet) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
route_message(From, To, Packet) ->
|
route_message(From, To, Packet) ->
|
||||||
{User, Server, Resource} = To,
|
#jid{luser = LUser} = To,
|
||||||
case catch lists:max(get_user_present_resources(User)) of
|
case catch lists:max(get_user_present_resources(LUser)) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
case ejabberd_auth:is_user_exists(User) of
|
case ejabberd_auth:is_user_exists(LUser) of
|
||||||
true ->
|
true ->
|
||||||
case catch mod_offline:store_packet(From, To, Packet) of
|
case catch mod_offline:store_packet(From, To, Packet) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
@ -303,7 +306,7 @@ route_message(From, To, Packet) ->
|
|||||||
{_, R} ->
|
{_, R} ->
|
||||||
ejabberd_sm ! {route,
|
ejabberd_sm ! {route,
|
||||||
From,
|
From,
|
||||||
{User, Server, R},
|
jlib:jid_replace_resource(To, R),
|
||||||
Packet}
|
Packet}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -311,7 +314,7 @@ route_message(From, To, Packet) ->
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
get_user_resources(User) ->
|
get_user_resources(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case catch mnesia:dirty_index_read(session, LUser, #session.user) of
|
case catch mnesia:dirty_index_read(session, LUser, #session.user) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
[];
|
[];
|
||||||
@ -325,7 +328,7 @@ get_user_resources(User) ->
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
set_presence(User, Resource, Priority) ->
|
set_presence(User, Resource, Priority) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
UR = {User, Resource},
|
UR = {User, Resource},
|
||||||
mnesia:write(#presence{ur = UR, user = LUser,
|
mnesia:write(#presence{ur = UR, user = LUser,
|
||||||
@ -334,15 +337,14 @@ set_presence(User, Resource, Priority) ->
|
|||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
unset_presence(User, Resource) ->
|
unset_presence(User, Resource) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
UR = {User, Resource},
|
UR = {User, Resource},
|
||||||
mnesia:delete({presence, UR})
|
mnesia:delete({presence, UR})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
get_user_present_resources(User) ->
|
get_user_present_resources(LUser) ->
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
|
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
[];
|
[];
|
||||||
@ -367,7 +369,7 @@ process_iq(From, To, Packet) ->
|
|||||||
{iq, ID, Type, XMLNS, SubEl} ->
|
{iq, ID, Type, XMLNS, SubEl} ->
|
||||||
case ets:lookup(sm_iqtable, XMLNS) of
|
case ets:lookup(sm_iqtable, XMLNS) of
|
||||||
[{_, Module, Function}] ->
|
[{_, Module, Function}] ->
|
||||||
ResIQ = apply(Module, Function, [From, To, IQ]),
|
ResIQ = Module:Function(From, To, IQ),
|
||||||
if
|
if
|
||||||
ResIQ /= ignore ->
|
ResIQ /= ignore ->
|
||||||
ejabberd_router ! {route,
|
ejabberd_router ! {route,
|
||||||
|
77
src/jlib.erl
77
src/jlib.erl
@ -18,12 +18,18 @@
|
|||||||
replace_from_to_attrs/3,
|
replace_from_to_attrs/3,
|
||||||
replace_from_to/3,
|
replace_from_to/3,
|
||||||
remove_attr/2,
|
remove_attr/2,
|
||||||
|
make_jid/3,
|
||||||
|
make_jid/1,
|
||||||
string_to_jid/1,
|
string_to_jid/1,
|
||||||
jid_to_string/1,
|
jid_to_string/1,
|
||||||
is_nodename/1,
|
is_nodename/1,
|
||||||
tolower/1,
|
tolower/1,
|
||||||
|
nodeprep/1,
|
||||||
|
nameprep/1,
|
||||||
|
resourceprep/1,
|
||||||
jid_tolower/1,
|
jid_tolower/1,
|
||||||
jid_remove_resource/1,
|
jid_remove_resource/1,
|
||||||
|
jid_replace_resource/2,
|
||||||
get_iq_namespace/1,
|
get_iq_namespace/1,
|
||||||
iq_query_info/1,
|
iq_query_info/1,
|
||||||
is_iq_request_type/1,
|
is_iq_request_type/1,
|
||||||
@ -130,6 +136,30 @@ remove_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
|
|||||||
NewAttrs = lists:keydelete(Attr, 1, Attrs),
|
NewAttrs = lists:keydelete(Attr, 1, Attrs),
|
||||||
{xmlelement, Name, NewAttrs, Els}.
|
{xmlelement, Name, NewAttrs, Els}.
|
||||||
|
|
||||||
|
|
||||||
|
make_jid(User, Server, Resource) ->
|
||||||
|
case stringprep:nodeprep(User) of
|
||||||
|
error -> error;
|
||||||
|
LUser ->
|
||||||
|
case stringprep:nameprep(Server) of
|
||||||
|
error -> error;
|
||||||
|
LServer ->
|
||||||
|
case stringprep:resourceprep(Resource) of
|
||||||
|
error -> error;
|
||||||
|
LResource ->
|
||||||
|
#jid{user = User,
|
||||||
|
server = Server,
|
||||||
|
resource = Resource,
|
||||||
|
luser = LUser,
|
||||||
|
lserver = LServer,
|
||||||
|
lresource = LResource}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
make_jid({User, Server, Resource}) ->
|
||||||
|
make_jid(User, Server, Resource).
|
||||||
|
|
||||||
string_to_jid(J) ->
|
string_to_jid(J) ->
|
||||||
string_to_jid1(J, "").
|
string_to_jid1(J, "").
|
||||||
|
|
||||||
@ -157,7 +187,7 @@ string_to_jid1([C | J], N) ->
|
|||||||
string_to_jid1([], "") ->
|
string_to_jid1([], "") ->
|
||||||
error;
|
error;
|
||||||
string_to_jid1([], N) ->
|
string_to_jid1([], N) ->
|
||||||
{"", lists:reverse(N), ""}.
|
make_jid("", lists:reverse(N), "").
|
||||||
|
|
||||||
string_to_jid2([$/ | J], N, "") ->
|
string_to_jid2([$/ | J], N, "") ->
|
||||||
error;
|
error;
|
||||||
@ -168,13 +198,15 @@ string_to_jid2([C | J], N, S) ->
|
|||||||
string_to_jid2([], N, "") ->
|
string_to_jid2([], N, "") ->
|
||||||
error;
|
error;
|
||||||
string_to_jid2([], N, S) ->
|
string_to_jid2([], N, S) ->
|
||||||
{N, lists:reverse(S), ""}.
|
make_jid(N, lists:reverse(S), "").
|
||||||
|
|
||||||
string_to_jid3([C | J], N, S, R) ->
|
string_to_jid3([C | J], N, S, R) ->
|
||||||
string_to_jid3(J, N, S, [C | R]);
|
string_to_jid3(J, N, S, [C | R]);
|
||||||
string_to_jid3([], N, S, R) ->
|
string_to_jid3([], N, S, R) ->
|
||||||
{N, S, lists:reverse(R)}.
|
make_jid(N, S, lists:reverse(R)).
|
||||||
|
|
||||||
|
jid_to_string(#jid{user = User, server = Server, resource = Resource}) ->
|
||||||
|
jid_to_string({User, Server, Resource});
|
||||||
jid_to_string({Node, Server, Resource}) ->
|
jid_to_string({Node, Server, Resource}) ->
|
||||||
S1 = case Node of
|
S1 = case Node of
|
||||||
"" ->
|
"" ->
|
||||||
@ -256,13 +288,34 @@ tolower([]) ->
|
|||||||
% [].
|
% [].
|
||||||
|
|
||||||
|
|
||||||
|
nodeprep(S) ->
|
||||||
|
stringprep:nodeprep(S).
|
||||||
|
|
||||||
|
nameprep(S) ->
|
||||||
|
stringprep:nameprep(S).
|
||||||
|
|
||||||
|
resourceprep(S) ->
|
||||||
|
stringprep:resourceprep(S).
|
||||||
|
|
||||||
|
|
||||||
|
jid_tolower(#jid{luser = U, lserver = S, lresource = R}) ->
|
||||||
|
{U, S, R};
|
||||||
jid_tolower({U, S, R}) ->
|
jid_tolower({U, S, R}) ->
|
||||||
{tolower(U), tolower(S), R}.
|
{tolower(U), tolower(S), R}.
|
||||||
|
|
||||||
|
jid_remove_resource(#jid{} = JID) ->
|
||||||
|
JID#jid{resource = "", lresource = ""};
|
||||||
jid_remove_resource({U, S, R}) ->
|
jid_remove_resource({U, S, R}) ->
|
||||||
{U, S, ""}.
|
{U, S, ""}.
|
||||||
|
|
||||||
|
jid_replace_resource(JID, Resource) ->
|
||||||
|
case stringprep:resourceprep(Resource) of
|
||||||
|
error -> error;
|
||||||
|
LResource ->
|
||||||
|
JID#jid{resource = Resource, lresource = LResource}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
get_iq_namespace({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
get_iq_namespace({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
||||||
case xml:remove_cdata(Els) of
|
case xml:remove_cdata(Els) of
|
||||||
[{xmlelement, Name2, Attrs2, Els2}] ->
|
[{xmlelement, Name2, Attrs2, Els2}] ->
|
||||||
@ -276,9 +329,6 @@ get_iq_namespace(_) ->
|
|||||||
iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
||||||
ID = xml:get_attr_s("id", Attrs),
|
ID = xml:get_attr_s("id", Attrs),
|
||||||
Type = xml:get_attr_s("type", Attrs),
|
Type = xml:get_attr_s("type", Attrs),
|
||||||
case xml:remove_cdata(Els) of
|
|
||||||
[{xmlelement, Name2, Attrs2, Els2}] ->
|
|
||||||
XMLNS = xml:get_attr_s("xmlns", Attrs2),
|
|
||||||
Type1 = case Type of
|
Type1 = case Type of
|
||||||
"set" -> set;
|
"set" -> set;
|
||||||
"get" -> get;
|
"get" -> get;
|
||||||
@ -287,19 +337,22 @@ iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
|||||||
_ -> invalid
|
_ -> invalid
|
||||||
end,
|
end,
|
||||||
if
|
if
|
||||||
(Type1 /= invalid) and (Type1 /= reply) and (XMLNS /= "") ->
|
(Type1 /= invalid) and (Type1 /= reply) ->
|
||||||
|
case xml:remove_cdata(Els) of
|
||||||
|
[{xmlelement, Name2, Attrs2, Els2}] ->
|
||||||
|
XMLNS = xml:get_attr_s("xmlns", Attrs2),
|
||||||
|
if
|
||||||
|
XMLNS /= "" ->
|
||||||
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}};
|
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}};
|
||||||
true ->
|
|
||||||
if
|
|
||||||
Type1 == reply ->
|
|
||||||
reply;
|
|
||||||
true ->
|
true ->
|
||||||
invalid
|
invalid
|
||||||
end
|
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
invalid
|
invalid
|
||||||
end;
|
end;
|
||||||
|
true ->
|
||||||
|
Type1
|
||||||
|
end;
|
||||||
iq_query_info(_) ->
|
iq_query_info(_) ->
|
||||||
not_iq.
|
not_iq.
|
||||||
|
|
||||||
|
@ -138,4 +138,6 @@
|
|||||||
% ?STREAM_ERROR("")).
|
% ?STREAM_ERROR("")).
|
||||||
|
|
||||||
|
|
||||||
|
-record(jid, {user, server, resource,
|
||||||
|
luser, lserver, lresource}).
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ get_stopped_nodes(Lang) ->
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
{User, _, _} = To,
|
#jid{user = User} = To,
|
||||||
case {acl:match_rule(configure, From), Type} of
|
case {acl:match_rule(configure, From), Type} of
|
||||||
{deny, _} ->
|
{deny, _} ->
|
||||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
|
@ -57,7 +57,7 @@ loop(Host) ->
|
|||||||
|
|
||||||
|
|
||||||
do_route(Host, From, To, Packet) ->
|
do_route(Host, From, To, Packet) ->
|
||||||
{ChanServ, _, Resource} = To,
|
#jid{user = ChanServ, resource = Resource} = To,
|
||||||
case ChanServ of
|
case ChanServ of
|
||||||
"" ->
|
"" ->
|
||||||
case Resource of
|
case Resource of
|
||||||
@ -75,12 +75,11 @@ do_route(Host, From, To, Packet) ->
|
|||||||
iq_data(From, To, ID, XMLNS, Type, SubEl);
|
iq_data(From, To, ID, XMLNS, Type, SubEl);
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, "503", "Service Unavailable"),
|
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||||
ejabberd_router:route(To, From, Err)
|
ejabberd_router:route(To, From, Err)
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(Packet,
|
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
|
||||||
"406", "Not Acceptable"),
|
|
||||||
ejabberd_router:route(To, From, Err)
|
ejabberd_router:route(To, From, Err)
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
@ -115,8 +114,7 @@ do_route(Host, From, To, Packet) ->
|
|||||||
case ets:lookup(irc_connection, {From, Server}) of
|
case ets:lookup(irc_connection, {From, Server}) of
|
||||||
[] ->
|
[] ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet,
|
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||||
"503", "Service Unavailable"),
|
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
[R] ->
|
[R] ->
|
||||||
Pid = R#irc_connection.pid,
|
Pid = R#irc_connection.pid,
|
||||||
@ -128,7 +126,7 @@ do_route(Host, From, To, Packet) ->
|
|||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, "406", "Not Acceptable"),
|
Packet, ?ERR_BAD_REQUEST),
|
||||||
ejabberd_router:route(To, From, Err)
|
ejabberd_router:route(To, From, Err)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -185,9 +183,7 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
|
|||||||
case XData of
|
case XData of
|
||||||
invalid ->
|
invalid ->
|
||||||
{iq, ID, error, XMLNS,
|
{iq, ID, error, XMLNS,
|
||||||
[SubEl, {xmlelement, "error",
|
[SubEl, ?ERR_BAD_REQUEST]};
|
||||||
[{"code", "400"}],
|
|
||||||
[{xmlcdata, "Bad Request"}]}]};
|
|
||||||
_ ->
|
_ ->
|
||||||
Node =
|
Node =
|
||||||
string:tokens(
|
string:tokens(
|
||||||
@ -227,8 +223,8 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
|
|||||||
|
|
||||||
|
|
||||||
get_form(From, [], Lang) ->
|
get_form(From, [], Lang) ->
|
||||||
{User, Server, _} = From,
|
#jid{user = User, server = Server,
|
||||||
{LUser, LServer, _} = jlib:jid_tolower(From),
|
luser = LUser, lserver = LServer} = From,
|
||||||
Customs =
|
Customs =
|
||||||
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
@ -345,8 +341,8 @@ set_form(_, _, Lang, XData) ->
|
|||||||
|
|
||||||
|
|
||||||
get_user_and_encoding(From, IRCServer) ->
|
get_user_and_encoding(From, IRCServer) ->
|
||||||
{User, Server, _} = From,
|
#jid{user = User, server = Server,
|
||||||
{LUser, LServer, _} = jlib:jid_tolower(From),
|
luser = LUser, lserver = LServer} = From,
|
||||||
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
{User, ?DEFAULT_IRC_ENCODING};
|
{User, ?DEFAULT_IRC_ENCODING};
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
channels = dict:new(),
|
channels = dict:new(),
|
||||||
inbuf = "", outbuf = ""}).
|
inbuf = "", outbuf = ""}).
|
||||||
|
|
||||||
-define(DBGFSM, true).
|
%-define(DBGFSM, true).
|
||||||
|
|
||||||
-ifdef(DBGFSM).
|
-ifdef(DBGFSM).
|
||||||
-define(FSMOPTS, [{debug, [trace]}]).
|
-define(FSMOPTS, [{debug, [trace]}]).
|
||||||
@ -411,7 +411,7 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) ->
|
|||||||
[From, "NICK", Nick | _] ->
|
[From, "NICK", Nick | _] ->
|
||||||
process_nick(StateData, From, Nick);
|
process_nick(StateData, From, Nick);
|
||||||
_ ->
|
_ ->
|
||||||
io:format("unknown irc command '~s'~n", [String]),
|
?DEBUG("unknown irc command '~s'~n", [String]),
|
||||||
StateData
|
StateData
|
||||||
end,
|
end,
|
||||||
NewStateData1 =
|
NewStateData1 =
|
||||||
@ -431,7 +431,7 @@ handle_info({ircstring, [$E, $R, $R, $O, $R | _] = String},
|
|||||||
|
|
||||||
|
|
||||||
handle_info({ircstring, String}, StateName, StateData) ->
|
handle_info({ircstring, String}, StateName, StateData) ->
|
||||||
io:format("unknown irc command '~s'~n", [String]),
|
?DEBUG("unknown irc command '~s'~n", [String]),
|
||||||
{next_state, StateName, StateData};
|
{next_state, StateName, StateData};
|
||||||
|
|
||||||
|
|
||||||
@ -441,7 +441,7 @@ handle_info({send_text, Text}, StateName, StateData) ->
|
|||||||
handle_info({tcp, Socket, Data}, StateName, StateData) ->
|
handle_info({tcp, Socket, Data}, StateName, StateData) ->
|
||||||
Buf = StateData#state.inbuf ++ binary_to_list(Data),
|
Buf = StateData#state.inbuf ++ binary_to_list(Data),
|
||||||
{ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"),
|
{ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"),
|
||||||
io:format("strings=~p~n", [Strings]),
|
?DEBUG("strings=~p~n", [Strings]),
|
||||||
NewBuf = process_lines(StateData#state.encoding, Strings),
|
NewBuf = process_lines(StateData#state.encoding, Strings),
|
||||||
{next_state, StateName, StateData#state{inbuf = NewBuf}};
|
{next_state, StateName, StateData#state{inbuf = NewBuf}};
|
||||||
handle_info({tcp_closed, Socket}, StateName, StateData) ->
|
handle_info({tcp_closed, Socket}, StateName, StateData) ->
|
||||||
@ -499,7 +499,7 @@ receiver(Socket, C2SPid, XMLStreamPid) ->
|
|||||||
|
|
||||||
send_text(#state{socket = Socket, encoding = Encoding}, Text) ->
|
send_text(#state{socket = Socket, encoding = Encoding}, Text) ->
|
||||||
CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)),
|
CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)),
|
||||||
%io:format("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),
|
%?DEBUG("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),
|
||||||
gen_tcp:send(Socket, CText).
|
gen_tcp:send(Socket, CText).
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
|
|
||||||
-record(state, {room,
|
-record(state, {room,
|
||||||
host,
|
host,
|
||||||
|
jid,
|
||||||
config = #config{},
|
config = #config{},
|
||||||
users = ?DICT:new(),
|
users = ?DICT:new(),
|
||||||
affiliations = ?DICT:new(),
|
affiliations = ?DICT:new(),
|
||||||
@ -117,11 +118,13 @@ init([Host, Room, Creator, Nick]) ->
|
|||||||
LCreator = jlib:jid_tolower(Creator),
|
LCreator = jlib:jid_tolower(Creator),
|
||||||
State = set_affiliation(Creator, owner,
|
State = set_affiliation(Creator, owner,
|
||||||
#state{host = Host,
|
#state{host = Host,
|
||||||
room = Room}),
|
room = Room,
|
||||||
|
jid = jlib:make_jid(Room, Host, "")}),
|
||||||
{ok, normal_state, State};
|
{ok, normal_state, State};
|
||||||
init([Host, Room, Opts]) ->
|
init([Host, Room, Opts]) ->
|
||||||
State = set_opts(Opts, #state{host = Host,
|
State = set_opts(Opts, #state{host = Host,
|
||||||
room = Room}),
|
room = Room,
|
||||||
|
jid = jlib:make_jid(Room, Host, "")}),
|
||||||
{ok, normal_state, State}.
|
{ok, normal_state, State}.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
@ -173,9 +176,9 @@ normal_state({route, From, "",
|
|||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({LJID, Info}) ->
|
fun({LJID, Info}) ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
jlib:jid_replace_resource(
|
||||||
StateData#state.host,
|
StateData#state.jid,
|
||||||
FromNick},
|
FromNick),
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
Packet)
|
Packet)
|
||||||
end,
|
end,
|
||||||
@ -189,8 +192,7 @@ normal_state({route, From, "",
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
StateData#state.jid,
|
||||||
StateData#state.host, ""},
|
|
||||||
From, Err),
|
From, Err),
|
||||||
{next_state, normal_state, StateData}
|
{next_state, normal_state, StateData}
|
||||||
end;
|
end;
|
||||||
@ -198,7 +200,7 @@ normal_state({route, From, "",
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ""},
|
StateData#state.jid,
|
||||||
From, Err),
|
From, Err),
|
||||||
{next_state, normal_state, StateData}
|
{next_state, normal_state, StateData}
|
||||||
end;
|
end;
|
||||||
@ -223,7 +225,7 @@ normal_state({route, From, "",
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ""},
|
StateData#state.jid,
|
||||||
From, Err),
|
From, Err),
|
||||||
{next_state, normal_state, StateData};
|
{next_state, normal_state, StateData};
|
||||||
IJID ->
|
IJID ->
|
||||||
@ -249,15 +251,14 @@ normal_state({route, From, "",
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ""},
|
StateData#state.jid,
|
||||||
From, Err),
|
From, Err),
|
||||||
{next_state, normal_state, StateData}
|
{next_state, normal_state, StateData}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(StateData#state.jid, From, Err),
|
||||||
{StateData#state.room, StateData#state.host, ""}, From, Err),
|
|
||||||
{next_state, normal_state, StateData}
|
{next_state, normal_state, StateData}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -293,9 +294,7 @@ normal_state({route, From, "",
|
|||||||
[SubEl, Error]},
|
[SubEl, Error]},
|
||||||
StateData}
|
StateData}
|
||||||
end,
|
end,
|
||||||
ejabberd_router:route({StateData#state.room,
|
ejabberd_router:route(StateData#state.jid,
|
||||||
StateData#state.host,
|
|
||||||
""},
|
|
||||||
From,
|
From,
|
||||||
jlib:iq_to_xml(IQRes)),
|
jlib:iq_to_xml(IQRes)),
|
||||||
case NewStateData of
|
case NewStateData of
|
||||||
@ -307,8 +306,7 @@ normal_state({route, From, "",
|
|||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
|
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(StateData#state.jid, From, Err),
|
||||||
{StateData#state.room, StateData#state.host, ""}, From, Err),
|
|
||||||
{next_state, normal_state, StateData}
|
{next_state, normal_state, StateData}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -353,9 +351,9 @@ normal_state({route, From, Nick,
|
|||||||
Packet,
|
Packet,
|
||||||
?ERR_MUC_NICK_CHANGE_CONFLICT),
|
?ERR_MUC_NICK_CHANGE_CONFLICT),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
jlib:jid_replace_resource(
|
||||||
StateData#state.host,
|
StateData#state.jid,
|
||||||
Nick}, % TODO: s/Nick/""/
|
Nick), % TODO: s/Nick/""/
|
||||||
From, Err),
|
From, Err),
|
||||||
StateData;
|
StateData;
|
||||||
_ ->
|
_ ->
|
||||||
@ -411,18 +409,18 @@ normal_state({route, From, ToNick,
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_ITEM_NOT_FOUND),
|
Packet, ?ERR_ITEM_NOT_FOUND),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
jlib:jid_replace_resource(
|
||||||
StateData#state.host,
|
StateData#state.jid,
|
||||||
ToNick},
|
ToNick),
|
||||||
From, Err);
|
From, Err);
|
||||||
ToJID ->
|
ToJID ->
|
||||||
{ok, #user{nick = FromNick}} =
|
{ok, #user{nick = FromNick}} =
|
||||||
?DICT:find(jlib:jid_tolower(From),
|
?DICT:find(jlib:jid_tolower(From),
|
||||||
StateData#state.users),
|
StateData#state.users),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
jlib:jid_replace_resource(
|
||||||
StateData#state.host,
|
StateData#state.jid,
|
||||||
FromNick},
|
FromNick),
|
||||||
ToJID, Packet)
|
ToJID, Packet)
|
||||||
end,
|
end,
|
||||||
{next_state, normal_state, StateData};
|
{next_state, normal_state, StateData};
|
||||||
@ -430,9 +428,9 @@ normal_state({route, From, ToNick,
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
jlib:jid_replace_resource(
|
||||||
StateData#state.host,
|
StateData#state.jid,
|
||||||
ToNick}, From, Err),
|
ToNick), From, Err),
|
||||||
{next_state, normal_state, StateData}
|
{next_state, normal_state, StateData}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@ -448,21 +446,22 @@ normal_state({route, From, ToNick,
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_ITEM_NOT_FOUND),
|
Packet, ?ERR_ITEM_NOT_FOUND),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ToNick},
|
jlib:jid_replace_resource(StateData#state.jid, ToNick),
|
||||||
From, Err);
|
From, Err);
|
||||||
ToJID ->
|
ToJID ->
|
||||||
{ok, #user{nick = FromNick}} =
|
{ok, #user{nick = FromNick}} =
|
||||||
?DICT:find(jlib:jid_tolower(From),
|
?DICT:find(jlib:jid_tolower(From),
|
||||||
StateData#state.users),
|
StateData#state.users),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, FromNick},
|
jlib:jid_replace_resource(StateData#state.jid, FromNick),
|
||||||
ToJID, Packet)
|
ToJID, Packet)
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ToNick}, From, Err)
|
jlib:jid_replace_resource(StateData#state.jid, ToNick), From,
|
||||||
|
Err)
|
||||||
end,
|
end,
|
||||||
{next_state, normal_state, StateData};
|
{next_state, normal_state, StateData};
|
||||||
|
|
||||||
@ -490,9 +489,7 @@ handle_event({service_message, Msg}, StateName, StateData) ->
|
|||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({LJID, Info}) ->
|
fun({LJID, Info}) ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
StateData#state.jid,
|
||||||
StateData#state.host,
|
|
||||||
""},
|
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
MessagePkt)
|
MessagePkt)
|
||||||
end,
|
end,
|
||||||
@ -792,9 +789,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
|||||||
true ->
|
true ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_MUC_NICK_CONFLICT),
|
Err = jlib:make_error_reply(Packet, ?ERR_MUC_NICK_CONFLICT),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
% TODO: s/Nick/""/
|
||||||
StateData#state.host,
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
Nick}, % TODO: s/Nick/""/
|
|
||||||
From, Err),
|
From, Err),
|
||||||
StateData;
|
StateData;
|
||||||
_ ->
|
_ ->
|
||||||
@ -809,7 +805,7 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
|||||||
_ -> ?ERR_MUC_NOT_MEMBER
|
_ -> ?ERR_MUC_NOT_MEMBER
|
||||||
end),
|
end),
|
||||||
ejabberd_router:route( % TODO: s/Nick/""/
|
ejabberd_router:route( % TODO: s/Nick/""/
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
From, Err),
|
From, Err),
|
||||||
StateData;
|
StateData;
|
||||||
_ ->
|
_ ->
|
||||||
@ -833,7 +829,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
|||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_MUC_BAD_PASSWORD),
|
Packet, ?ERR_MUC_BAD_PASSWORD),
|
||||||
ejabberd_router:route( % TODO: s/Nick/""/
|
ejabberd_router:route( % TODO: s/Nick/""/
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(
|
||||||
|
StateData#state.jid, Nick),
|
||||||
From, Err),
|
From, Err),
|
||||||
StateData
|
StateData
|
||||||
end
|
end
|
||||||
@ -922,7 +919,7 @@ send_new_presence(NJID, StateData) ->
|
|||||||
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
||||||
[{xmlelement, "item", ItemAttrs, []}]}]),
|
[{xmlelement, "item", ItemAttrs, []}]}]),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
Packet)
|
Packet)
|
||||||
end, ?DICT:to_list(StateData#state.users)).
|
end, ?DICT:to_list(StateData#state.users)).
|
||||||
@ -963,7 +960,8 @@ send_existing_presences(ToJID, StateData) ->
|
|||||||
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
||||||
[{xmlelement, "item", ItemAttrs, []}]}]),
|
[{xmlelement, "item", ItemAttrs, []}]}]),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, FromNick},
|
jlib:jid_replace_resource(
|
||||||
|
StateData#state.jid, FromNick),
|
||||||
RealToJID,
|
RealToJID,
|
||||||
Packet)
|
Packet)
|
||||||
end
|
end
|
||||||
@ -1033,11 +1031,11 @@ send_nick_changing(JID, OldNick, StateData) ->
|
|||||||
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
||||||
[{xmlelement, "item", ItemAttrs2, []}]}]),
|
[{xmlelement, "item", ItemAttrs2, []}]}]),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, OldNick},
|
jlib:jid_replace_resource(StateData#state.jid, OldNick),
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
Packet1),
|
Packet1),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
Packet2)
|
Packet2)
|
||||||
end, ?DICT:to_list(StateData#state.users)).
|
end, ?DICT:to_list(StateData#state.users)).
|
||||||
@ -1086,7 +1084,7 @@ send_history(JID, StateData) ->
|
|||||||
lists:foldl(
|
lists:foldl(
|
||||||
fun({Nick, Packet, HaveSubject}, B) ->
|
fun({Nick, Packet, HaveSubject}, B) ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
JID,
|
JID,
|
||||||
Packet),
|
Packet),
|
||||||
B or HaveSubject
|
B or HaveSubject
|
||||||
@ -1105,7 +1103,7 @@ send_subject(JID, StateData) ->
|
|||||||
[{xmlcdata,
|
[{xmlcdata,
|
||||||
Nick ++ " has set the topic to: " ++ Subject}]}]},
|
Nick ++ " has set the topic to: " ++ Subject}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ""},
|
StateData#state.jid,
|
||||||
JID,
|
JID,
|
||||||
Packet)
|
Packet)
|
||||||
end.
|
end.
|
||||||
@ -1123,7 +1121,7 @@ send_join_messages_end(JID, StateData) ->
|
|||||||
[{xmlelement, "body", [],
|
[{xmlelement, "body", [],
|
||||||
[{xmlcdata, "-"}]}]},
|
[{xmlcdata, "-"}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, ""},
|
StateData#state.jid,
|
||||||
JID,
|
JID,
|
||||||
Packet).
|
Packet).
|
||||||
|
|
||||||
@ -1550,7 +1548,7 @@ send_kickban_presence1(UJID, Reason, Code, StateData) ->
|
|||||||
[{xmlelement, "item", ItemAttrs, ItemEls},
|
[{xmlelement, "item", ItemAttrs, ItemEls},
|
||||||
{xmlelement, "status", [{"code", Code}], []}]}]},
|
{xmlelement, "status", [{"code", Code}], []}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
Packet)
|
Packet)
|
||||||
end, ?DICT:to_list(StateData#state.users)).
|
end, ?DICT:to_list(StateData#state.users)).
|
||||||
@ -1842,7 +1840,7 @@ destroy_room(DEls, StateData) ->
|
|||||||
{xmlelement, "destroy", [],
|
{xmlelement, "destroy", [],
|
||||||
DEls}]}]},
|
DEls}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room, StateData#state.host, Nick},
|
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||||
Info#user.jid,
|
Info#user.jid,
|
||||||
Packet)
|
Packet)
|
||||||
end, ?DICT:to_list(StateData#state.users)),
|
end, ?DICT:to_list(StateData#state.users)),
|
||||||
@ -1950,9 +1948,7 @@ check_invitation(From, Els, StateData) ->
|
|||||||
""})}],
|
""})}],
|
||||||
[{xmlcdata, Reason}]}]},
|
[{xmlcdata, Reason}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
StateData#state.jid,
|
||||||
StateData#state.host,
|
|
||||||
""},
|
|
||||||
JID,
|
JID,
|
||||||
Msg),
|
Msg),
|
||||||
JID;
|
JID;
|
||||||
|
@ -66,8 +66,7 @@ store_packet(From, To, Packet) ->
|
|||||||
true = is_process_alive(whereis(?PROCNAME)),
|
true = is_process_alive(whereis(?PROCNAME)),
|
||||||
case check_event(From, To, Packet) of
|
case check_event(From, To, Packet) of
|
||||||
true ->
|
true ->
|
||||||
{User, Server, Resource} = To,
|
#jid{luser = LUser} = To,
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
TimeStamp = now(),
|
TimeStamp = now(),
|
||||||
?PROCNAME ! #offline_msg{user = LUser,
|
?PROCNAME ! #offline_msg{user = LUser,
|
||||||
timestamp = TimeStamp,
|
timestamp = TimeStamp,
|
||||||
@ -125,7 +124,7 @@ find_x_event([El | Els]) ->
|
|||||||
|
|
||||||
|
|
||||||
resend_offline_messages(User) ->
|
resend_offline_messages(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
Rs = mnesia:read({offline_msg, LUser}),
|
Rs = mnesia:read({offline_msg, LUser}),
|
||||||
mnesia:delete({offline_msg, LUser}),
|
mnesia:delete({offline_msg, LUser}),
|
||||||
@ -152,7 +151,7 @@ resend_offline_messages(User) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user(User) ->
|
remove_user(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:delete({offline_msg, LUser})
|
mnesia:delete({offline_msg, LUser})
|
||||||
end,
|
end,
|
||||||
|
@ -61,7 +61,7 @@ start(Opts) ->
|
|||||||
%
|
%
|
||||||
process_iq(From, To, IQ) ->
|
process_iq(From, To, IQ) ->
|
||||||
{iq, ID, Type, XMLNS, SubEl} = IQ,
|
{iq, ID, Type, XMLNS, SubEl} = IQ,
|
||||||
{_, Server, _} = From,
|
#jid{lserver = Server} = From,
|
||||||
Res =
|
Res =
|
||||||
case ?MYNAME of
|
case ?MYNAME of
|
||||||
Server ->
|
Server ->
|
||||||
@ -85,16 +85,16 @@ process_iq(From, To, IQ) ->
|
|||||||
|
|
||||||
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl},
|
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl},
|
||||||
#userlist{name = Active}) ->
|
#userlist{name = Active}) ->
|
||||||
{User, _, _} = From,
|
#jid{luser = LUser} = From,
|
||||||
{xmlelement, _, _, Els} = SubEl,
|
{xmlelement, _, _, Els} = SubEl,
|
||||||
case xml:remove_cdata(Els) of
|
case xml:remove_cdata(Els) of
|
||||||
[] ->
|
[] ->
|
||||||
process_lists_get(User, Active);
|
process_lists_get(LUser, Active);
|
||||||
[{xmlelement, Name, Attrs, SubEls}] ->
|
[{xmlelement, Name, Attrs, SubEls}] ->
|
||||||
case Name of
|
case Name of
|
||||||
"list" ->
|
"list" ->
|
||||||
ListName = xml:get_attr("name", Attrs),
|
ListName = xml:get_attr("name", Attrs),
|
||||||
process_list_get(User, ListName);
|
process_list_get(LUser, ListName);
|
||||||
_ ->
|
_ ->
|
||||||
{error, ?ERR_BAD_REQUEST}
|
{error, ?ERR_BAD_REQUEST}
|
||||||
end;
|
end;
|
||||||
@ -103,8 +103,7 @@ process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl},
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
process_lists_get(User, Active) ->
|
process_lists_get(LUser, Active) ->
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
case catch mnesia:dirty_read(privacy, LUser) of
|
case catch mnesia:dirty_read(privacy, LUser) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||||
@ -143,13 +142,13 @@ process_lists_get(User, Active) ->
|
|||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
process_list_get(User, {value, Name}) ->
|
process_list_get(LUser, {value, Name}) ->
|
||||||
LUser = jlib:tolower(User),
|
case catch mnesia:dirty_read(privacy, LUser) of
|
||||||
case catch mnesia:dirty_read(privacy, User) of
|
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||||
[] ->
|
[] ->
|
||||||
{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
|
{error, ?ERR_ITEM_NOT_FOUND};
|
||||||
|
%{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
|
||||||
[#privacy{lists = Lists}] ->
|
[#privacy{lists = Lists}] ->
|
||||||
case lists:keysearch(Name, 1, Lists) of
|
case lists:keysearch(Name, 1, Lists) of
|
||||||
{value, {_, List}} ->
|
{value, {_, List}} ->
|
||||||
@ -163,7 +162,7 @@ process_list_get(User, {value, Name}) ->
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
process_list_get(_User, false) ->
|
process_list_get(_LUser, false) ->
|
||||||
{error, ?ERR_BAD_REQUEST}.
|
{error, ?ERR_BAD_REQUEST}.
|
||||||
|
|
||||||
item_to_xml(Item) ->
|
item_to_xml(Item) ->
|
||||||
@ -250,18 +249,18 @@ list_to_action(S) ->
|
|||||||
|
|
||||||
|
|
||||||
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
{User, _, _} = From,
|
#jid{luser = LUser} = From,
|
||||||
{xmlelement, _, _, Els} = SubEl,
|
{xmlelement, _, _, Els} = SubEl,
|
||||||
case xml:remove_cdata(Els) of
|
case xml:remove_cdata(Els) of
|
||||||
[{xmlelement, Name, Attrs, SubEls}] ->
|
[{xmlelement, Name, Attrs, SubEls}] ->
|
||||||
ListName = xml:get_attr("name", Attrs),
|
ListName = xml:get_attr("name", Attrs),
|
||||||
case Name of
|
case Name of
|
||||||
"list" ->
|
"list" ->
|
||||||
process_list_set(User, ListName, xml:remove_cdata(SubEls));
|
process_list_set(LUser, ListName, xml:remove_cdata(SubEls));
|
||||||
"active" ->
|
"active" ->
|
||||||
process_active_set(User, ListName);
|
process_active_set(LUser, ListName);
|
||||||
"default" ->
|
"default" ->
|
||||||
process_default_set(User, ListName);
|
process_default_set(LUser, ListName);
|
||||||
_ ->
|
_ ->
|
||||||
{error, ?ERR_BAD_REQUEST}
|
{error, ?ERR_BAD_REQUEST}
|
||||||
end;
|
end;
|
||||||
@ -270,8 +269,7 @@ process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
process_default_set(User, {value, Name}) ->
|
process_default_set(LUser, {value, Name}) ->
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
case mnesia:read({privacy, LUser}) of
|
case mnesia:read({privacy, LUser}) of
|
||||||
[] ->
|
[] ->
|
||||||
@ -296,8 +294,7 @@ process_default_set(User, {value, Name}) ->
|
|||||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
process_default_set(User, false) ->
|
process_default_set(LUser, false) ->
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
case mnesia:read({privacy, LUser}) of
|
case mnesia:read({privacy, LUser}) of
|
||||||
[] ->
|
[] ->
|
||||||
@ -317,8 +314,7 @@ process_default_set(User, false) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
process_active_set(User, {value, Name}) ->
|
process_active_set(LUser, {value, Name}) ->
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
case catch mnesia:dirty_read(privacy, LUser) of
|
case catch mnesia:dirty_read(privacy, LUser) of
|
||||||
[] ->
|
[] ->
|
||||||
{error, ?ERR_ITEM_NOT_FOUND};
|
{error, ?ERR_ITEM_NOT_FOUND};
|
||||||
@ -331,7 +327,7 @@ process_active_set(User, {value, Name}) ->
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
process_active_set(User, false) ->
|
process_active_set(LUser, false) ->
|
||||||
{result, [], #userlist{}}.
|
{result, [], #userlist{}}.
|
||||||
|
|
||||||
|
|
||||||
@ -339,8 +335,7 @@ process_active_set(User, false) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
process_list_set(User, {value, Name}, Els) ->
|
process_list_set(LUser, {value, Name}, Els) ->
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
case parse_items(Els) of
|
case parse_items(Els) of
|
||||||
false ->
|
false ->
|
||||||
{error, ?ERR_BAD_REQUEST};
|
{error, ?ERR_BAD_REQUEST};
|
||||||
@ -369,8 +364,8 @@ process_list_set(User, {value, Name}, Els) ->
|
|||||||
Error;
|
Error;
|
||||||
{atomic, {result, _} = Res} ->
|
{atomic, {result, _} = Res} ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{User, ?MYNAME, ""},
|
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||||
{User, ?MYNAME, ""},
|
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||||
{xmlelement, "broadcast", [],
|
{xmlelement, "broadcast", [],
|
||||||
[{privacy_list, #userlist{name = Name, list = []}}]}),
|
[{privacy_list, #userlist{name = Name, list = []}}]}),
|
||||||
Res;
|
Res;
|
||||||
@ -398,8 +393,8 @@ process_list_set(User, {value, Name}, Els) ->
|
|||||||
Error;
|
Error;
|
||||||
{atomic, {result, _} = Res} ->
|
{atomic, {result, _} = Res} ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{User, ?MYNAME, ""},
|
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||||
{User, ?MYNAME, ""},
|
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||||
{xmlelement, "broadcast", [],
|
{xmlelement, "broadcast", [],
|
||||||
[{privacy_list, #userlist{name = Name, list = List}}]}),
|
[{privacy_list, #userlist{name = Name, list = List}}]}),
|
||||||
Res;
|
Res;
|
||||||
@ -408,7 +403,7 @@ process_list_set(User, {value, Name}, Els) ->
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
process_list_set(_User, false, _Els) ->
|
process_list_set(_LUser, false, _Els) ->
|
||||||
{error, ?ERR_BAD_REQUEST}.
|
{error, ?ERR_BAD_REQUEST}.
|
||||||
|
|
||||||
|
|
||||||
@ -523,7 +518,7 @@ parse_matches1(Item, [{xmlelement, _, _, _} | Els]) ->
|
|||||||
|
|
||||||
|
|
||||||
get_user_list(User) ->
|
get_user_list(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case catch mnesia:dirty_read(privacy, LUser) of
|
case catch mnesia:dirty_read(privacy, LUser) of
|
||||||
[] ->
|
[] ->
|
||||||
#userlist{};
|
#userlist{};
|
||||||
|
@ -34,9 +34,7 @@ stop() ->
|
|||||||
|
|
||||||
|
|
||||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
{User, Server, _} = From,
|
#jid{luser = LUser, lserver = LServer} = From,
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
LServer = jlib:tolower(Server),
|
|
||||||
case ?MYNAME of
|
case ?MYNAME of
|
||||||
Server ->
|
Server ->
|
||||||
{xmlelement, Name, Attrs, Els} = SubEl,
|
{xmlelement, Name, Attrs, Els} = SubEl,
|
||||||
|
@ -47,14 +47,16 @@ start(Opts) ->
|
|||||||
proc_lib:spawn_link(?MODULE, init, [Host, ServedHosts, self()])).
|
proc_lib:spawn_link(?MODULE, init, [Host, ServedHosts, self()])).
|
||||||
|
|
||||||
|
|
||||||
|
-define(MYJID, #jid{user = "", server = Host, resource = "",
|
||||||
|
luser = "", lserver = Host, lresource = ""}).
|
||||||
|
|
||||||
init(Host, ServedHosts, Parent) ->
|
init(Host, ServedHosts, Parent) ->
|
||||||
ejabberd_router:register_route(Host),
|
ejabberd_router:register_route(Host),
|
||||||
create_new_node(Host, ["pubsub"], {"", Host, ""}),
|
create_new_node(Host, ["pubsub"], ?MYJID),
|
||||||
create_new_node(Host, ["pubsub", "nodes"], {"", Host, ""}),
|
create_new_node(Host, ["pubsub", "nodes"], ?MYJID),
|
||||||
create_new_node(Host, ["home"], {"", Host, ""}),
|
create_new_node(Host, ["home"], ?MYJID),
|
||||||
lists:foreach(fun(H) ->
|
lists:foreach(fun(H) ->
|
||||||
create_new_node(Host, ["home", H], {"", Host, ""})
|
create_new_node(Host, ["home", H], ?MYJID)
|
||||||
end, ServedHosts),
|
end, ServedHosts),
|
||||||
loop(Host, Parent).
|
loop(Host, Parent).
|
||||||
|
|
||||||
@ -86,7 +88,7 @@ loop(Host, Parent) ->
|
|||||||
do_route(Host, From, To, Packet) ->
|
do_route(Host, From, To, Packet) ->
|
||||||
{xmlelement, Name, Attrs, Els} = Packet,
|
{xmlelement, Name, Attrs, Els} = Packet,
|
||||||
case To of
|
case To of
|
||||||
{"", _, ""} ->
|
#jid{luser = "", lresource = ""} ->
|
||||||
case Name of
|
case Name of
|
||||||
"iq" ->
|
"iq" ->
|
||||||
case jlib:iq_query_info(Packet) of
|
case jlib:iq_query_info(Packet) of
|
||||||
@ -115,9 +117,7 @@ do_route(Host, From, To, Packet) ->
|
|||||||
jlib:make_error_reply(
|
jlib:make_error_reply(
|
||||||
Packet, Error)
|
Packet, Error)
|
||||||
end,
|
end,
|
||||||
ejabberd_router:route(To,
|
ejabberd_router:route(To, From, Res);
|
||||||
From,
|
|
||||||
Res);
|
|
||||||
%{iq, ID, get, ?NS_REGISTER = XMLNS, SubEl} ->
|
%{iq, ID, get, ?NS_REGISTER = XMLNS, SubEl} ->
|
||||||
% Lang = xml:get_tag_attr_s(
|
% Lang = xml:get_tag_attr_s(
|
||||||
% "xml:lang", SubEl),
|
% "xml:lang", SubEl),
|
||||||
@ -155,9 +155,7 @@ do_route(Host, From, To, Packet) ->
|
|||||||
jlib:make_error_reply(
|
jlib:make_error_reply(
|
||||||
Packet, Error)
|
Packet, Error)
|
||||||
end,
|
end,
|
||||||
ejabberd_router:route(To,
|
ejabberd_router:route(To, From, Res);
|
||||||
From,
|
|
||||||
Res);
|
|
||||||
{iq, ID, get, ?NS_VCARD = XMLNS, SubEl} ->
|
{iq, ID, get, ?NS_VCARD = XMLNS, SubEl} ->
|
||||||
Lang = xml:get_tag_attr_s(
|
Lang = xml:get_tag_attr_s(
|
||||||
"xml:lang", SubEl),
|
"xml:lang", SubEl),
|
||||||
@ -982,10 +980,10 @@ subscription_to_string(Subscription) ->
|
|||||||
|
|
||||||
check_create_permission(Host, Node, Owner) ->
|
check_create_permission(Host, Node, Owner) ->
|
||||||
if
|
if
|
||||||
{"", Host, ""} == Owner ->
|
#jid{lserver = Host} == Owner ->
|
||||||
true;
|
true;
|
||||||
true ->
|
true ->
|
||||||
{User, Server, _} = Owner,
|
#jid{luser = User, lserver = Server} = Owner,
|
||||||
case Node of
|
case Node of
|
||||||
["home", Server, User | _] ->
|
["home", Server, User | _] ->
|
||||||
true;
|
true;
|
||||||
@ -1087,8 +1085,8 @@ broadcast_publish_item(Host, Node, ItemID, Payload) ->
|
|||||||
[{xmlelement, "item",
|
[{xmlelement, "item",
|
||||||
ItemAttrs,
|
ItemAttrs,
|
||||||
Payload}]}]}]},
|
Payload}]}]}]},
|
||||||
ejabberd_router:route({"", Host, ""},
|
ejabberd_router:route(
|
||||||
JID, Stanza);
|
?MYJID, jlib:make_jid(JID), Stanza);
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
@ -1118,8 +1116,8 @@ broadcast_retract_item(Host, Node, ItemID) ->
|
|||||||
[{"node", node_to_string(Node)}],
|
[{"node", node_to_string(Node)}],
|
||||||
[{xmlelement, "retract",
|
[{xmlelement, "retract",
|
||||||
ItemAttrs, []}]}]}]},
|
ItemAttrs, []}]}]}]},
|
||||||
ejabberd_router:route({"", Host, ""},
|
ejabberd_router:route(
|
||||||
JID, Stanza);
|
?MYJID, jlib:make_jid(JID), Stanza);
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
@ -1144,8 +1142,8 @@ broadcast_removed_node(Host, Removed) ->
|
|||||||
[{xmlelement, "delete",
|
[{xmlelement, "delete",
|
||||||
[{"node", node_to_string(Node)}],
|
[{"node", node_to_string(Node)}],
|
||||||
[]}]}]},
|
[]}]}]},
|
||||||
ejabberd_router:route({"", Host, ""},
|
ejabberd_router:route(
|
||||||
JID, Stanza);
|
?MYJID, jlib:make_jid(JID), Stanza);
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
(UTag /= false) and (RTag /= false) ->
|
(UTag /= false) and (RTag /= false) ->
|
||||||
User = xml:get_tag_cdata(UTag),
|
User = xml:get_tag_cdata(UTag),
|
||||||
case From of
|
case From of
|
||||||
{User, Server, _} ->
|
#jid{user = User, lserver = Server} ->
|
||||||
ejabberd_auth:remove_user(User),
|
ejabberd_auth:remove_user(User),
|
||||||
{iq, ID, result, XMLNS, [SubEl]};
|
{iq, ID, result, XMLNS, [SubEl]};
|
||||||
_ ->
|
_ ->
|
||||||
@ -71,14 +71,18 @@ process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
(UTag == false) and (RTag /= false) ->
|
(UTag == false) and (RTag /= false) ->
|
||||||
{User, Server, _} = From,
|
case From of
|
||||||
|
#jid{user = User, lserver = Server} ->
|
||||||
ejabberd_auth:remove_user(User),
|
ejabberd_auth:remove_user(User),
|
||||||
{iq, ID, result, XMLNS, [SubEl]};
|
{iq, ID, result, XMLNS, [SubEl]};
|
||||||
|
_ ->
|
||||||
|
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}
|
||||||
|
end;
|
||||||
(UTag /= false) and (PTag /= false) ->
|
(UTag /= false) and (PTag /= false) ->
|
||||||
User = xml:get_tag_cdata(UTag),
|
User = xml:get_tag_cdata(UTag),
|
||||||
Password = xml:get_tag_cdata(PTag),
|
Password = xml:get_tag_cdata(PTag),
|
||||||
case From of
|
case From of
|
||||||
{User, Server, _} ->
|
#jid{user = User, lserver = Server} ->
|
||||||
ejabberd_auth:set_password(User, Password),
|
ejabberd_auth:set_password(User, Password),
|
||||||
{iq, ID, result, XMLNS, [SubEl]};
|
{iq, ID, result, XMLNS, [SubEl]};
|
||||||
_ ->
|
_ ->
|
||||||
@ -117,7 +121,7 @@ try_register(User, Password) ->
|
|||||||
ok;
|
ok;
|
||||||
{atomic, exists} ->
|
{atomic, exists} ->
|
||||||
% TODO: replace to "username unavailable"
|
% TODO: replace to "username unavailable"
|
||||||
{error, ?ERR_BAD_REQUEST};
|
{error, ?ERR_NOT_ALLOWED};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||||
end
|
end
|
||||||
|
@ -46,9 +46,9 @@ start(Opts) ->
|
|||||||
|
|
||||||
process_iq(From, To, IQ) ->
|
process_iq(From, To, IQ) ->
|
||||||
{iq, ID, Type, XMLNS, SubEl} = IQ,
|
{iq, ID, Type, XMLNS, SubEl} = IQ,
|
||||||
{_, Server, _} = From,
|
#jid{lserver = LServer} = From,
|
||||||
case ?MYNAME of
|
case ?MYNAME of
|
||||||
Server ->
|
LServer ->
|
||||||
process_local_iq(From, To, IQ);
|
process_local_iq(From, To, IQ);
|
||||||
_ ->
|
_ ->
|
||||||
{iq, ID, error, XMLNS,
|
{iq, ID, error, XMLNS,
|
||||||
@ -67,8 +67,7 @@ process_local_iq(From, To, {iq, _, Type, _, _} = IQ) ->
|
|||||||
|
|
||||||
|
|
||||||
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
{User, _, _} = From,
|
#jid{luser = LUser} = From,
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:index_read(roster, LUser, #roster.user)
|
mnesia:index_read(roster, LUser, #roster.user)
|
||||||
end,
|
end,
|
||||||
@ -120,19 +119,19 @@ item_to_xml(Item) ->
|
|||||||
|
|
||||||
|
|
||||||
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
{User, _, _} = From,
|
|
||||||
{xmlelement, Name, Attrs, Els} = SubEl,
|
{xmlelement, Name, Attrs, Els} = SubEl,
|
||||||
lists:foreach(fun(El) -> process_item_set(User, From, To, El) end, Els),
|
lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els),
|
||||||
{iq, ID, result, XMLNS, []}.
|
{iq, ID, result, XMLNS, []}.
|
||||||
|
|
||||||
process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
process_item_set(From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||||
JID = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
||||||
LUser = jlib:tolower(User),
|
#jid{user = User, luser = LUser} = From,
|
||||||
case JID of
|
case JID1 of
|
||||||
error ->
|
error ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
LJID = jlib:jid_tolower(JID),
|
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||||
|
LJID = jlib:jid_tolower(JID1),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
Res = mnesia:read({roster, {LUser, LJID}}),
|
Res = mnesia:read({roster, {LUser, LJID}}),
|
||||||
Item = case Res of
|
Item = case Res of
|
||||||
@ -175,7 +174,7 @@ process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
|||||||
end,
|
end,
|
||||||
if IsTo ->
|
if IsTo ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
From, OldItem#roster.jid,
|
From, jlib:make_jid(OldItem#roster.jid),
|
||||||
{xmlelement, "presence",
|
{xmlelement, "presence",
|
||||||
[{"type", "unsubscribe"}],
|
[{"type", "unsubscribe"}],
|
||||||
[]});
|
[]});
|
||||||
@ -183,7 +182,7 @@ process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
|||||||
end,
|
end,
|
||||||
if IsFrom ->
|
if IsFrom ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
From, OldItem#roster.jid,
|
From, jlib:make_jid(OldItem#roster.jid),
|
||||||
{xmlelement, "presence",
|
{xmlelement, "presence",
|
||||||
[{"type", "unsubscribed"}],
|
[{"type", "unsubscribed"}],
|
||||||
[]});
|
[]});
|
||||||
@ -198,7 +197,7 @@ process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
|||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
process_item_set(User, From, To, _) ->
|
process_item_set(From, To, _) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
||||||
@ -207,7 +206,8 @@ process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
|||||||
case jlib:string_to_jid(Val) of
|
case jlib:string_to_jid(Val) of
|
||||||
error ->
|
error ->
|
||||||
process_item_attrs(Item, Attrs);
|
process_item_attrs(Item, Attrs);
|
||||||
JID ->
|
JID1 ->
|
||||||
|
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||||
process_item_attrs(Item#roster{jid = JID}, Attrs)
|
process_item_attrs(Item#roster{jid = JID}, Attrs)
|
||||||
end;
|
end;
|
||||||
"name" ->
|
"name" ->
|
||||||
@ -252,7 +252,9 @@ process_item_els(Item, []) ->
|
|||||||
|
|
||||||
|
|
||||||
push_item(User, From, Item) ->
|
push_item(User, From, Item) ->
|
||||||
ejabberd_sm ! {route, {"", "", ""}, {User, "", ""},
|
ejabberd_sm ! {route,
|
||||||
|
jlib:make_jid("", "", ""),
|
||||||
|
jlib:make_jid(User, "", ""),
|
||||||
{xmlelement, "broadcast", [],
|
{xmlelement, "broadcast", [],
|
||||||
[{item,
|
[{item,
|
||||||
Item#roster.jid,
|
Item#roster.jid,
|
||||||
@ -269,12 +271,12 @@ push_item(User, Resource, From, Item) ->
|
|||||||
[item_to_xml(Item)]}]},
|
[item_to_xml(Item)]}]},
|
||||||
ejabberd_router ! {route,
|
ejabberd_router ! {route,
|
||||||
From,
|
From,
|
||||||
{User, ?MYNAME, Resource},
|
jlib:make_jid(User, ?MYNAME, Resource),
|
||||||
jlib:iq_to_xml(ResIQ)}.
|
jlib:iq_to_xml(ResIQ)}.
|
||||||
|
|
||||||
|
|
||||||
get_subscription_lists(User) ->
|
get_subscription_lists(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:index_read(roster, LUser, #roster.user)
|
mnesia:index_read(roster, LUser, #roster.user)
|
||||||
end,
|
end,
|
||||||
@ -286,7 +288,6 @@ get_subscription_lists(User) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
fill_subscription_lists([I | Is], F, T) ->
|
fill_subscription_lists([I | Is], F, T) ->
|
||||||
%J = I#roster.jid,
|
|
||||||
J = element(2, I#roster.uj),
|
J = element(2, I#roster.uj),
|
||||||
case I#roster.subscription of
|
case I#roster.subscription of
|
||||||
both ->
|
both ->
|
||||||
@ -303,9 +304,8 @@ fill_subscription_lists([], F, T) ->
|
|||||||
|
|
||||||
|
|
||||||
in_subscription(User, From, Type) ->
|
in_subscription(User, From, Type) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
LFrom = jlib:jid_tolower(From),
|
LFrom = jlib:jid_tolower(From),
|
||||||
{FU, FS, FR} = From,
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
case mnesia:read({roster, {LUser, LFrom}}) of
|
case mnesia:read({roster, {LUser, LFrom}}) of
|
||||||
[] ->
|
[] ->
|
||||||
@ -317,6 +317,9 @@ in_subscription(User, From, Type) ->
|
|||||||
unsubscribed ->
|
unsubscribed ->
|
||||||
false;
|
false;
|
||||||
subscribed ->
|
subscribed ->
|
||||||
|
JID = {From#jid.user,
|
||||||
|
From#jid.server,
|
||||||
|
From#jid.resource},
|
||||||
NewItem = #roster{uj = {LUser, LFrom},
|
NewItem = #roster{uj = {LUser, LFrom},
|
||||||
user = LUser,
|
user = LUser,
|
||||||
jid = From},
|
jid = From},
|
||||||
@ -376,8 +379,12 @@ in_subscription(User, From, Type) ->
|
|||||||
{atomic, false} ->
|
{atomic, false} ->
|
||||||
false;
|
false;
|
||||||
{atomic, {update, Presence, Item}} ->
|
{atomic, {update, Presence, Item}} ->
|
||||||
ejabberd_router:route({User, ?MYNAME, ""}, {FU, FS, ""}, Presence),
|
ejabberd_router:route({User, ?MYNAME, ""},
|
||||||
ejabberd_sm ! {route, {"", "", ""}, {User, "", ""},
|
jlib:jid_replace_resource(From, ""),
|
||||||
|
Presence),
|
||||||
|
ejabberd_sm ! {route,
|
||||||
|
jlib:make_jid("", "", ""),
|
||||||
|
jlib:make_jid(User, "", ""),
|
||||||
{xmlelement, "broadcast", [],
|
{xmlelement, "broadcast", [],
|
||||||
[{item,
|
[{item,
|
||||||
Item#roster.jid,
|
Item#roster.jid,
|
||||||
@ -390,9 +397,9 @@ in_subscription(User, From, Type) ->
|
|||||||
false
|
false
|
||||||
end.
|
end.
|
||||||
|
|
||||||
out_subscription(User, JID, Type) ->
|
out_subscription(User, JID1, Type) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
LJID = jlib:jid_tolower(JID),
|
LJID = jlib:jid_tolower(JID1),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
Item = case mnesia:read({roster, {LUser, LJID}}) of
|
Item = case mnesia:read({roster, {LUser, LJID}}) of
|
||||||
[] ->
|
[] ->
|
||||||
@ -400,6 +407,9 @@ out_subscription(User, JID, Type) ->
|
|||||||
(Type == unsubscribed) ->
|
(Type == unsubscribed) ->
|
||||||
false;
|
false;
|
||||||
true ->
|
true ->
|
||||||
|
JID = {JID1#jid.user,
|
||||||
|
JID1#jid.server,
|
||||||
|
JID1#jid.resource},
|
||||||
#roster{uj = {LUser, LJID},
|
#roster{uj = {LUser, LJID},
|
||||||
user = LUser,
|
user = LUser,
|
||||||
jid = JID}
|
jid = JID}
|
||||||
@ -448,7 +458,9 @@ out_subscription(User, JID, Type) ->
|
|||||||
push_item(User, {"", ?MYNAME, ""}, Item),
|
push_item(User, {"", ?MYNAME, ""}, Item),
|
||||||
if
|
if
|
||||||
Update ->
|
Update ->
|
||||||
ejabberd_sm ! {route, {"", "", ""}, {User, "", ""},
|
ejabberd_sm ! {route,
|
||||||
|
jlib:make_jid("", "", ""),
|
||||||
|
jlib:make_jid(User, "", ""),
|
||||||
{xmlelement, "broadcast", [],
|
{xmlelement, "broadcast", [],
|
||||||
[{item,
|
[{item,
|
||||||
Item#roster.jid,
|
Item#roster.jid,
|
||||||
@ -461,7 +473,7 @@ out_subscription(User, JID, Type) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user(User) ->
|
remove_user(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
lists:foreach(fun(R) ->
|
lists:foreach(fun(R) ->
|
||||||
mnesia:delete_object(R)
|
mnesia:delete_object(R)
|
||||||
@ -480,12 +492,13 @@ set_items(User, SubEl) ->
|
|||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
process_item_set_t(User, {xmlelement, Name, Attrs, Els} = XItem) ->
|
process_item_set_t(User, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||||
JID = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
case JID of
|
case JID1 of
|
||||||
error ->
|
error ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
|
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||||
LJID = jlib:jid_tolower(JID),
|
LJID = jlib:jid_tolower(JID),
|
||||||
Res = mnesia:read({roster, {LUser, LJID}}),
|
Res = mnesia:read({roster, {LUser, LJID}}),
|
||||||
Item = #roster{uj = {LUser, LJID},
|
Item = #roster{uj = {LUser, LJID},
|
||||||
@ -509,7 +522,8 @@ process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
|
|||||||
case jlib:string_to_jid(Val) of
|
case jlib:string_to_jid(Val) of
|
||||||
error ->
|
error ->
|
||||||
process_item_attrs_ws(Item, Attrs);
|
process_item_attrs_ws(Item, Attrs);
|
||||||
JID ->
|
JID1 ->
|
||||||
|
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||||
process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
|
process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
|
||||||
end;
|
end;
|
||||||
"name" ->
|
"name" ->
|
||||||
@ -548,7 +562,7 @@ process_item_attrs_ws(Item, []) ->
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
get_jid_info(User, JID) ->
|
get_jid_info(User, JID) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
LJID = jlib:jid_tolower(JID),
|
LJID = jlib:jid_tolower(JID),
|
||||||
case catch mnesia:dirty_read(roster, {LUser, LJID}) of
|
case catch mnesia:dirty_read(roster, {LUser, LJID}) of
|
||||||
[#roster{subscription = Subscription, groups = Groups}] ->
|
[#roster{subscription = Subscription, groups = Groups}] ->
|
||||||
|
@ -72,7 +72,12 @@ init(Host) ->
|
|||||||
loop() ->
|
loop() ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, Packet} ->
|
{route, From, To, Packet} ->
|
||||||
do_route(From, To, Packet),
|
case catch do_route(From, To, Packet) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
?ERROR_MSG("~p", [Reason]);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
loop();
|
loop();
|
||||||
_ ->
|
_ ->
|
||||||
loop()
|
loop()
|
||||||
@ -104,9 +109,7 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
case Type of
|
case Type of
|
||||||
set ->
|
set ->
|
||||||
{User, Server, _} = From,
|
#jid{user = User, lserver = LServer, luser = LUser} = From,
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
LServer = jlib:tolower(Server),
|
|
||||||
case ?MYNAME of
|
case ?MYNAME of
|
||||||
LServer ->
|
LServer ->
|
||||||
set_vcard(User, SubEl),
|
set_vcard(User, SubEl),
|
||||||
@ -116,8 +119,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
[SubEl, ?ERR_NOT_ALLOWED]}
|
[SubEl, ?ERR_NOT_ALLOWED]}
|
||||||
end;
|
end;
|
||||||
get ->
|
get ->
|
||||||
{User, _, _} = To,
|
#jid{luser = LUser} = To,
|
||||||
LUser = jlib:tolower(User),
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:read({vcard, LUser})
|
mnesia:read({vcard, LUser})
|
||||||
end,
|
end,
|
||||||
@ -145,18 +147,18 @@ set_vcard(User, VCARD) ->
|
|||||||
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
||||||
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
||||||
|
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
LFN = jlib:tolower(FN),
|
LFN = stringprep:tolower(FN),
|
||||||
LFamily = jlib:tolower(Family),
|
LFamily = stringprep:tolower(Family),
|
||||||
LGiven = jlib:tolower(Given),
|
LGiven = stringprep:tolower(Given),
|
||||||
LMiddle = jlib:tolower(Middle),
|
LMiddle = stringprep:tolower(Middle),
|
||||||
LNickname = jlib:tolower(Nickname),
|
LNickname = stringprep:tolower(Nickname),
|
||||||
LBDay = jlib:tolower(BDay),
|
LBDay = stringprep:tolower(BDay),
|
||||||
LCTRY = jlib:tolower(CTRY),
|
LCTRY = stringprep:tolower(CTRY),
|
||||||
LLocality = jlib:tolower(Locality),
|
LLocality = stringprep:tolower(Locality),
|
||||||
LEMail = jlib:tolower(EMail),
|
LEMail = stringprep:tolower(EMail),
|
||||||
LOrgName = jlib:tolower(OrgName),
|
LOrgName = stringprep:tolower(OrgName),
|
||||||
LOrgUnit = jlib:tolower(OrgUnit),
|
LOrgUnit = stringprep:tolower(OrgUnit),
|
||||||
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
||||||
@ -210,7 +212,7 @@ set_vcard(User, VCARD) ->
|
|||||||
|
|
||||||
|
|
||||||
do_route(From, To, Packet) ->
|
do_route(From, To, Packet) ->
|
||||||
{User, Server, Resource} = To,
|
#jid{user = User, resource = Resource} = To,
|
||||||
if
|
if
|
||||||
(User /= "") or (Resource /= "") ->
|
(User /= "") or (Resource /= "") ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
|
Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||||
@ -400,7 +402,7 @@ filter_fields([], Match) ->
|
|||||||
Match;
|
Match;
|
||||||
filter_fields([{SVar, [Val]} | Ds], Match)
|
filter_fields([{SVar, [Val]} | Ds], Match)
|
||||||
when is_list(Val) and (Val /= "") ->
|
when is_list(Val) and (Val /= "") ->
|
||||||
LVal = jlib:tolower(Val),
|
LVal = stringprep:tolower(Val),
|
||||||
NewMatch = case SVar of
|
NewMatch = case SVar of
|
||||||
"user" -> Match#vcard_search{luser = LVal};
|
"user" -> Match#vcard_search{luser = LVal};
|
||||||
"fn" -> Match#vcard_search{lfn = LVal};
|
"fn" -> Match#vcard_search{lfn = LVal};
|
||||||
@ -439,18 +441,18 @@ set_vcard_t(R, _) ->
|
|||||||
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
||||||
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
||||||
|
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
LFN = jlib:tolower(FN),
|
LFN = stringprep:tolower(FN),
|
||||||
LFamily = jlib:tolower(Family),
|
LFamily = stringprep:tolower(Family),
|
||||||
LGiven = jlib:tolower(Given),
|
LGiven = stringprep:tolower(Given),
|
||||||
LMiddle = jlib:tolower(Middle),
|
LMiddle = stringprep:tolower(Middle),
|
||||||
LNickname = jlib:tolower(Nickname),
|
LNickname = stringprep:tolower(Nickname),
|
||||||
LBDay = jlib:tolower(BDay),
|
LBDay = stringprep:tolower(BDay),
|
||||||
LCTRY = jlib:tolower(CTRY),
|
LCTRY = stringprep:tolower(CTRY),
|
||||||
LLocality = jlib:tolower(Locality),
|
LLocality = stringprep:tolower(Locality),
|
||||||
LEMail = jlib:tolower(EMail),
|
LEMail = stringprep:tolower(EMail),
|
||||||
LOrgName = jlib:tolower(OrgName),
|
LOrgName = stringprep:tolower(OrgName),
|
||||||
LOrgUnit = jlib:tolower(OrgUnit),
|
LOrgUnit = stringprep:tolower(OrgUnit),
|
||||||
|
|
||||||
mnesia:write(
|
mnesia:write(
|
||||||
#vcard_search{user = User, luser = LUser,
|
#vcard_search{user = User, luser = LUser,
|
||||||
@ -476,7 +478,7 @@ reindex_vcards() ->
|
|||||||
|
|
||||||
|
|
||||||
remove_user(User) ->
|
remove_user(User) ->
|
||||||
LUser = jlib:tolower(User),
|
LUser = jlib:nodeprep(User),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:delete({vcard, LUser}),
|
mnesia:delete({vcard, LUser}),
|
||||||
lists:foreach(fun(R) ->
|
lists:foreach(fun(R) ->
|
||||||
|
@ -32,8 +32,38 @@ static void stringprep_erl_stop(ErlDrvData handle)
|
|||||||
driver_free((char*)handle);
|
driver_free((char*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome
|
||||||
|
* library
|
||||||
|
*/
|
||||||
|
|
||||||
static int combine(int ch1, int ch2)
|
void canonical_ordering(int *str, int len)
|
||||||
|
{
|
||||||
|
int i, j, t;
|
||||||
|
int last, next;
|
||||||
|
|
||||||
|
last = GetUniCharCClass(str[0]);
|
||||||
|
for (i = 0; i < len - 1; i++)
|
||||||
|
{
|
||||||
|
next = GetUniCharCClass(str[i + 1]);
|
||||||
|
if (next != 0 && last > next)
|
||||||
|
{
|
||||||
|
for(j = i; j > 0; j--)
|
||||||
|
{
|
||||||
|
if (GetUniCharCClass(str[j]) <= next)
|
||||||
|
break;
|
||||||
|
t = str[j + 1];
|
||||||
|
str[j + 1] = str[j];
|
||||||
|
str[j] = t;
|
||||||
|
}
|
||||||
|
next = last;
|
||||||
|
}
|
||||||
|
last = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int compose(int ch1, int ch2)
|
||||||
{
|
{
|
||||||
int info1, info2;
|
int info1, info2;
|
||||||
|
|
||||||
@ -90,6 +120,29 @@ static int combine(int ch1, int ch2)
|
|||||||
pos += 3; \
|
pos += 3; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ADD_UCHAR32(str, pos, len, ch) \
|
||||||
|
if(pos >= len) { \
|
||||||
|
len = 2*len + 1; \
|
||||||
|
str = driver_realloc(str, len * sizeof(int)); \
|
||||||
|
} \
|
||||||
|
str[pos] = ch; \
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
|
||||||
|
#define ADD_DECOMP(ruc) \
|
||||||
|
info = GetUniCharDecompInfo(ruc); \
|
||||||
|
if(info >= 0) { \
|
||||||
|
decomp_len = GetDecompLen(info); \
|
||||||
|
decomp_shift = GetDecompShift(info); \
|
||||||
|
for(j = 0; j < decomp_len; j++) { \
|
||||||
|
ADD_UCHAR32(str32, str32pos, str32len, \
|
||||||
|
decompList[decomp_shift + j]); \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
ADD_UCHAR32(str32, str32pos, str32len, ruc); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int stringprep_erl_control(ErlDrvData drv_data,
|
static int stringprep_erl_control(ErlDrvData drv_data,
|
||||||
unsigned int command,
|
unsigned int command,
|
||||||
@ -105,12 +158,22 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
|||||||
int prohibit, tolower;
|
int prohibit, tolower;
|
||||||
char *rstring;
|
char *rstring;
|
||||||
int *mc;
|
int *mc;
|
||||||
|
int *str32;
|
||||||
|
int str32len, str32pos = 0;
|
||||||
|
int decomp_len, decomp_shift;
|
||||||
|
int comp_pos;
|
||||||
|
int cclass1, cclass2;
|
||||||
|
int ch1, ch2;
|
||||||
|
|
||||||
size = len + 1;
|
size = len + 1;
|
||||||
|
|
||||||
rstring = driver_alloc(size);
|
rstring = driver_alloc(size);
|
||||||
rstring[0] = 0;
|
rstring[0] = 0;
|
||||||
|
|
||||||
|
str32len = len + 1;
|
||||||
|
|
||||||
|
str32 = driver_alloc(str32len * sizeof(int));
|
||||||
|
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -164,12 +227,14 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
|||||||
|
|
||||||
if(bad) {
|
if(bad) {
|
||||||
*rbuf = rstring;
|
*rbuf = rstring;
|
||||||
|
driver_free(str32);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = GetUniCharInfo(uc);
|
info = GetUniCharInfo(uc);
|
||||||
if(info & prohibit) {
|
if(info & prohibit) {
|
||||||
*rbuf = rstring;
|
*rbuf = rstring;
|
||||||
|
driver_free(str32);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,6 +245,19 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
|||||||
if(!(info & MCMask))
|
if(!(info & MCMask))
|
||||||
{
|
{
|
||||||
ruc = uc + GetDelta(info);
|
ruc = uc + GetDelta(info);
|
||||||
|
ADD_DECOMP(ruc);
|
||||||
|
|
||||||
|
//info = GetUniCharDecompInfo(ruc);
|
||||||
|
//if(info >= 0) {
|
||||||
|
// decomp_len = GetDecompLen(info);
|
||||||
|
// decomp_shift = GetDecompShift(info);
|
||||||
|
// for(j = 0; j < decomp_len; j++) {
|
||||||
|
// ADD_UCHAR32(str32, str32pos, str32len,
|
||||||
|
// decompList[decomp_shift + j]);
|
||||||
|
// }
|
||||||
|
//} else {
|
||||||
|
// ADD_UCHAR32(str32, str32pos, str32len, ruc);
|
||||||
|
//}
|
||||||
|
|
||||||
//info = GetUniCharDecompInfo(ruc);
|
//info = GetUniCharDecompInfo(ruc);
|
||||||
//if(info >= 0) {
|
//if(info >= 0) {
|
||||||
@ -190,26 +268,63 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
|||||||
// printf("\r\n");
|
// printf("\r\n");
|
||||||
//}
|
//}
|
||||||
|
|
||||||
ADD_UCHAR(ruc);
|
//ADD_UCHAR(ruc);
|
||||||
} else {
|
} else {
|
||||||
mc = GetMC(info);
|
mc = GetMC(info);
|
||||||
for(j = 1; j <= mc[0]; j++) {
|
for(j = 1; j <= mc[0]; j++) {
|
||||||
ruc = mc[j];
|
ruc = mc[j];
|
||||||
//printf("Char %x cclass %d\r\n", ruc, GetUniCharCClass(ruc));
|
//printf("Char %x cclass %d\r\n", ruc, GetUniCharCClass(ruc));
|
||||||
ADD_UCHAR(ruc);
|
ADD_DECOMP(ruc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ruc = uc;
|
ruc = uc;
|
||||||
ADD_UCHAR(ruc);
|
ADD_DECOMP(ruc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("Combine: %x\r\n", combine(0x438, 0x301));
|
if (str32pos == 0) {
|
||||||
|
rstring[0] = 1;
|
||||||
|
*rbuf = rstring;
|
||||||
|
driver_free(str32);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
canonical_ordering(str32, str32pos);
|
||||||
|
|
||||||
|
comp_pos = 0;
|
||||||
|
ch1 = str32[0];
|
||||||
|
cclass1 = GetUniCharCClass(ch1);
|
||||||
|
for(i = 1; i < str32pos; i++)
|
||||||
|
{
|
||||||
|
ch2 = str32[i];
|
||||||
|
cclass2 = GetUniCharCClass(ch2);
|
||||||
|
//printf("Compose: %x + %x = %x\r\n", ch1, ch2, compose(ch1, ch2));
|
||||||
|
if(cclass1 == 0 && cclass1 < cclass2 && (ruc = compose(ch1, ch2))) {
|
||||||
|
ch1 = ruc;
|
||||||
|
} else {
|
||||||
|
str32[comp_pos] = ch1;
|
||||||
|
comp_pos++;
|
||||||
|
ch1 = ch2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str32[comp_pos] = ch1;
|
||||||
|
str32pos = comp_pos+1;
|
||||||
|
|
||||||
|
|
||||||
|
for(i = 0; i < str32pos; i++)
|
||||||
|
{
|
||||||
|
ruc = str32[i];
|
||||||
|
ADD_UCHAR(ruc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("Compose: %x\r\n", compose(0x438, 0x301));
|
||||||
|
//printf("Pos: %d\r\n", pos);
|
||||||
|
|
||||||
rstring[0] = 1;
|
rstring[0] = 1;
|
||||||
*rbuf = rstring;
|
*rbuf = rstring;
|
||||||
|
driver_free(str32);
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -283,6 +283,12 @@ proc uni::buildTables {} {
|
|||||||
|
|
||||||
if {[info exists decomp_map($i)]} {
|
if {[info exists decomp_map($i)]} {
|
||||||
set decomp $decomp_map($i)
|
set decomp $decomp_map($i)
|
||||||
|
#puts -$decomp
|
||||||
|
while {[info exists decomp_map([set ch1 [lindex $decomp 0]])]} {
|
||||||
|
set decomp [concat $decomp_map($ch1) [lreplace $decomp 0 0]]
|
||||||
|
#puts +$decomp
|
||||||
|
}
|
||||||
|
|
||||||
if {[info exists decomp_used($decomp)]} {
|
if {[info exists decomp_used($decomp)]} {
|
||||||
lappend decomp_info $decomp_used($decomp)
|
lappend decomp_info $decomp_used($decomp)
|
||||||
} else {
|
} else {
|
||||||
@ -442,75 +448,6 @@ static unsigned char cclassGroupMap\[\] = {"
|
|||||||
puts $f $line
|
puts $f $line
|
||||||
puts $f "};
|
puts $f "};
|
||||||
|
|
||||||
/*
|
|
||||||
* Each group represents a unique set of character attributes. The attributes
|
|
||||||
* are encoded into a 32-bit value as follows:
|
|
||||||
*
|
|
||||||
* Bits 0-4 Character category: see the constants listed below.
|
|
||||||
*
|
|
||||||
* Bits 5-7 Case delta type: 000 = identity
|
|
||||||
* 010 = add delta for lower
|
|
||||||
* 011 = add delta for lower, add 1 for title
|
|
||||||
* 100 = sutract delta for title/upper
|
|
||||||
* 101 = sub delta for upper, sub 1 for title
|
|
||||||
* 110 = sub delta for upper, add delta for lower
|
|
||||||
*
|
|
||||||
* Bits 8-21 Reserved for future use.
|
|
||||||
*
|
|
||||||
* Bits 22-31 Case delta: delta for case conversions. This should be the
|
|
||||||
* highest field so we can easily sign extend.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int cclass_groups\[\] = {"
|
|
||||||
set line " "
|
|
||||||
set last [expr {[llength $groups] - 1}]
|
|
||||||
for {set i 0} {$i <= $last} {incr i} {
|
|
||||||
foreach {type toupper tolower totitle} [split [lindex $groups $i] ,] {}
|
|
||||||
|
|
||||||
# Compute the case conversion type and delta
|
|
||||||
|
|
||||||
if {$totitle != ""} {
|
|
||||||
if {$totitle == $toupper} {
|
|
||||||
# subtract delta for title or upper
|
|
||||||
set case 4
|
|
||||||
set delta $toupper
|
|
||||||
} elseif {$toupper != ""} {
|
|
||||||
# subtract delta for upper, subtract 1 for title
|
|
||||||
set case 5
|
|
||||||
set delta $toupper
|
|
||||||
} else {
|
|
||||||
# add delta for lower, add 1 for title
|
|
||||||
set case 3
|
|
||||||
set delta $tolower
|
|
||||||
}
|
|
||||||
} elseif {$toupper != ""} {
|
|
||||||
# subtract delta for upper, add delta for lower
|
|
||||||
set case 6
|
|
||||||
set delta $toupper
|
|
||||||
} elseif {$tolower != ""} {
|
|
||||||
# add delta for lower
|
|
||||||
set case 2
|
|
||||||
set delta $tolower
|
|
||||||
} else {
|
|
||||||
# noop
|
|
||||||
set case 0
|
|
||||||
set delta 0
|
|
||||||
}
|
|
||||||
|
|
||||||
set val [expr {($delta << 22) | ($case << 5) | $type}]
|
|
||||||
|
|
||||||
append line [format "%d" $val]
|
|
||||||
if {$i != $last} {
|
|
||||||
append line ", "
|
|
||||||
}
|
|
||||||
if {[string length $line] > 65} {
|
|
||||||
puts $f $line
|
|
||||||
set line " "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
puts $f $line
|
|
||||||
puts $f "};
|
|
||||||
|
|
||||||
#define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\])
|
#define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\])
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user