25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-10-05 14:51:05 +02: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:
Alexey Shchepin 2003-10-07 20:31:44 +00:00
parent e1de741cfc
commit 61875f80b3
26 changed files with 1328 additions and 1200 deletions

View File

@ -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>
* src/stringprep/stringprep_drv.c: Added support for nameprep,

View File

@ -49,7 +49,7 @@ check_authzid(State, Props) ->
error ->
{error, "invalid-authzid"};
JID ->
LUser = xml:get_attr_s(username, Props),
LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
{U, S, R} = jlib:jid_tolower(JID),
case R of
"" ->

View File

@ -34,7 +34,8 @@ mech_new() ->
mech_step(#state{step = 1, nonce = Nonce} = State, "") ->
{continue,
"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}};
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
case parse(ClientIn) of

View File

@ -109,7 +109,7 @@ terminate(Reason, State) ->
%%%----------------------------------------------------------------------
check_password(User, Password) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
case catch mnesia:dirty_read({passwd, LUser}) of
[#passwd{password = Password}] ->
true;
@ -118,7 +118,7 @@ check_password(User, Password) ->
end.
check_password(User, Password, StreamID, Digest) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
case mnesia:read({passwd, LUser}) of
[E] ->
@ -144,14 +144,14 @@ check_password(User, Password, StreamID, Digest) ->
set_password(User, Password) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
mnesia:write(#passwd{user = LUser, password = Password})
end,
mnesia:transaction(F).
try_register(User, Password) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
case mnesia:read({passwd, LUser}) of
[] ->
@ -168,7 +168,7 @@ dirty_get_registered_users() ->
mnesia:dirty_all_keys(passwd).
get_password(User) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
case catch mnesia:dirty_read(passwd, LUser) of
[#passwd{password = Password}] ->
Password;
@ -177,7 +177,7 @@ get_password(User) ->
end.
get_password_s(User) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
case catch mnesia:dirty_read(passwd, LUser) of
[#passwd{password = Password}] ->
Password;
@ -186,7 +186,7 @@ get_password_s(User) ->
end.
is_user_exists(User) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
case catch mnesia:dirty_read({passwd, LUser}) of
[] ->
false;
@ -197,14 +197,14 @@ is_user_exists(User) ->
end.
remove_user(User) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
mnesia:delete({passwd, LUser})
end,
mnesia:transaction(F).
remove_user(User, Password) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
case mnesia:read({passwd, LUser}) of
[#passwd{password = Password}] ->

View File

@ -45,6 +45,7 @@
access,
shaper,
authentificated = false,
jid,
user = "", server = ?MYNAME, resource = "",
pres_t = ?SETS:new(),
pres_f = ?SETS:new(),
@ -205,7 +206,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_auth, StateData};
{auth, ID, set, {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
allow ->
case ejabberd_auth:check_password(
@ -224,6 +225,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{next_state, session_established,
StateData#state{user = U,
resource = R,
jid = JID,
pres_f = ?SETS:from_list(Fs),
pres_t = ?SETS:from_list(Ts),
privacy_list = PrivList}};
@ -281,12 +283,14 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
send_element(StateData,
{xmlelement, "success",
[{"xmlns", ?NS_SASL}], []}),
{U, _, R} = jlib:string_to_jid(
xml:get_attr_s(authzid, Props)),
JID = #jid{user = U, resource = R} =
jlib:string_to_jid(
xml:get_attr_s(authzid, Props)),
{next_state, wait_for_stream,
StateData#state{authentificated = true,
user = U,
resource = R
resource = R,
jid = JID
}};
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
@ -344,12 +348,13 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
send_element(StateData,
{xmlelement, "success",
[{"xmlns", ?NS_SASL}], []}),
{U, _, R} = jlib:string_to_jid(
xml:get_attr_s(authzid, Props)),
JID = #jid{user = U, resource = R} =
jlib:string_to_jid(xml:get_attr_s(authzid, Props)),
{next_state, wait_for_stream,
StateData#state{authentificated = true,
user = U,
resource = R
resource = R,
jid = JID
}};
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
@ -402,7 +407,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
U = StateData#state.user,
R = StateData#state.resource,
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
allow ->
ejabberd_sm:open_session(U, R),
@ -457,13 +462,14 @@ session_established({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El,
User = StateData#state.user,
Server = StateData#state.server,
FromJID = {User,
Server,
StateData#state.resource},
%FromJID = {User,
% Server,
% StateData#state.resource},
FromJID = StateData#state.jid,
To = xml:get_attr_s("to", Attrs),
ToJID = case To of
"" ->
{User, Server, ""};
jlib:make_jid(User, Server, "");
_ ->
jlib:string_to_jid(To)
end,
@ -476,7 +482,9 @@ session_established({xmlstreamelement, El}, StateData) ->
case Name of
"presence" ->
case ToJID of
{User, Server, ""} ->
#jid{user = User,
server = Server,
resource = ""} ->
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
[FromJID, El, StateData]),
presence_update(FromJID, El, StateData);
@ -573,7 +581,6 @@ handle_info(replaced, StateName, StateData) ->
{stop, normal, StateData#state{user = ""}};
handle_info({route, From, To, Packet}, StateName, StateData) ->
{xmlelement, Name, Attrs, Els} = Packet,
{FU, FS, FR} = From,
{Pass, NewAttrs, NewState} =
case Name of
"presence" ->
@ -694,9 +701,7 @@ terminate(Reason, StateName, StateData) ->
_ ->
ejabberd_sm:close_session(StateData#state.user,
StateData#state.resource),
From = {StateData#state.user,
StateData#state.server,
StateData#state.resource},
From = StateData#state.jid,
Packet = {xmlelement, "presence", [{"type", "unavailable"}], []},
ejabberd_sm:unset_presence(StateData#state.user,
StateData#state.resource),
@ -797,16 +802,17 @@ get_auth_tags([], U, P, D, R) ->
process_presence_probe(From, To, StateData) ->
LFrom = jlib:jid_tolower(From),
case StateData#state.pres_last of
undefined ->
ok;
_ ->
Cond1 = (not StateData#state.pres_invis)
and ?SETS:is_element(From, StateData#state.pres_f)
and (not ?SETS:is_element(From, StateData#state.pres_i)),
and ?SETS:is_element(LFrom, StateData#state.pres_f)
and (not ?SETS:is_element(LFrom, StateData#state.pres_i)),
Cond2 = StateData#state.pres_invis
and ?SETS:is_element(From, StateData#state.pres_f)
and ?SETS:is_element(From, StateData#state.pres_a),
and ?SETS:is_element(LFrom, StateData#state.pres_f)
and ?SETS:is_element(LFrom, StateData#state.pres_a),
if
Cond1 ->
ejabberd_router:route(To, From,
@ -934,14 +940,16 @@ presence_track(From, To, Packet, StateData) ->
presence_broadcast(From, JIDSet, Packet) ->
lists:foreach(fun(JID) ->
ejabberd_router:route(From, JID, Packet)
ejabberd_router:route(
From, jlib:make_jid(JID), Packet)
end, ?SETS:to_list(JIDSet)).
presence_broadcast_to_trusted(From, T, A, Packet) ->
lists:foreach(fun(JID) ->
case ?SETS:is_element(JID, T) of
true ->
ejabberd_router:route(From, JID, Packet);
ejabberd_router:route(
From, jlib:make_jid(JID), Packet);
_ ->
ok
end
@ -949,12 +957,13 @@ presence_broadcast_to_trusted(From, T, A, Packet) ->
presence_broadcast_first(From, StateData, Packet) ->
{U, S, _} = From,
?SETS:fold(fun(JID, X) ->
ejabberd_router:route({U, S, ""}, JID,
{xmlelement, "presence",
[{"type", "probe"}],
[]}),
ejabberd_router:route(
jlib:jid_replace_resource(From, ""),
jlib:make_jid(JID),
{xmlelement, "presence",
[{"type", "probe"}],
[]}),
X
end,
[],
@ -964,7 +973,9 @@ presence_broadcast_first(From, StateData, Packet) ->
StateData;
true ->
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)
end,
StateData#state.pres_a,
@ -1003,9 +1014,7 @@ roster_change(IJID, ISubscription, StateData) ->
StateData#state{pres_f = FSet, pres_t = TSet};
P ->
?DEBUG("roster changed for ~p~n", [StateData#state.user]),
From = {StateData#state.user,
StateData#state.server,
StateData#state.resource},
From = StateData#state.jid,
Cond1 = (not StateData#state.pres_invis) and IsFrom,
Cond2 = (not IsFrom)
and (?SETS:is_element(LIJID, StateData#state.pres_a) or
@ -1013,7 +1022,7 @@ roster_change(IJID, ISubscription, StateData) ->
if
Cond1 ->
?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,
StateData#state.pres_a),
StateData#state{pres_a = A,
@ -1021,7 +1030,7 @@ roster_change(IJID, ISubscription, StateData) ->
pres_t = TSet};
Cond2 ->
?DEBUG("C2: ~p~n", [LIJID]),
ejabberd_router:route(From, IJID,
ejabberd_router:route(From, jlib:make_jid(IJID),
{xmlelement, "presence",
[{"type", "unavailable"}], []}),
I = remove_element(LIJID,

View File

@ -71,7 +71,7 @@ do_route(State, From, To, Packet) ->
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
case To of
{"", _, ""} ->
#jid{luser = "", lresource = ""} ->
{xmlelement, Name, Attrs, Els} = Packet,
case Name of
"iq" ->
@ -83,11 +83,12 @@ do_route(State, From, To, Packet) ->
_ ->
ok
end;
{"", _, _} ->
#jid{luser = ""} ->
Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
ejabberd_router ! {route,
{"", State#state.mydomain, ""}, From, Err},
ok;
jlib:make_jid("", State#state.mydomain, ""),
From,
Err};
_ ->
ejabberd_sm ! {route, From, To, Packet}
end.

View File

@ -22,6 +22,7 @@
-export([start_link/0, init/0]).
-include("ejabberd.hrl").
-include("jlib.hrl").
-record(route, {domain, node, pid}).
-record(local_route, {domain, pid}).
@ -101,8 +102,7 @@ loop() ->
do_route(From, To, Packet) ->
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
{DstNode, DstDomain, DstResourse} = To,
LDstDomain = jlib:tolower(DstDomain),
#jid{lserver = LDstDomain} = To,
case mnesia:dirty_read({local_route, LDstDomain}) of
[] ->
case mnesia:dirty_read({route, LDstDomain}) of

View File

@ -18,6 +18,7 @@
-include_lib("mnemosyne/include/mnemosyne.hrl").
-include("ejabberd.hrl").
-include("jlib.hrl").
-record(s2s, {fromto, node, key}).
-record(local_s2s, {fromto, pid}).
@ -148,8 +149,8 @@ try_register(FromTo) ->
do_route(From, To, Packet) ->
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
{_, MyServer, _} = From,
{User, Server, Resource} = To,
#jid{lserver = MyServer} = From,
#jid{lserver = Server} = To,
FromTo = {MyServer, Server},
Key = randoms:get_string(),
case find_connection(FromTo, Key) of

View File

@ -266,7 +266,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
From = xml:get_attr_s("from", Attrs),
FromJID1 = jlib:string_to_jid(From),
FromJID = case FromJID1 of
{Node, Server, Resource} ->
#jid{lserver = Server} ->
if Server == StateData#state.server -> FromJID1;
true -> error
end;

View File

@ -102,7 +102,7 @@ close_session(User, Resource) ->
register_connection(User, Resource, Pid) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
UR = {LUser, Resource},
F = fun() ->
Ss = mnesia:wread({session, UR}),
@ -132,7 +132,7 @@ register_connection(User, Resource, Pid) ->
replace_my_connection(User, Resource) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
UR = {LUser, Resource},
Es = mnesia:read({local_session, UR}),
@ -151,7 +151,7 @@ replace_my_connection(User, Resource) ->
remove_connection(User, Resource) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
UR = {LUser, Resource},
mnesia:delete({local_session, UR}),
@ -177,33 +177,34 @@ clean_table_from_bad_node(Node) ->
do_route(From, To, Packet) ->
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[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,
case Resource of
"" ->
case Name of
"presence" ->
{FU, FS, FR} = From,
FromU = jlib:jid_replace_resource(From, ""),
{Pass, Subsc} =
case xml:get_attr_s("type", Attrs) of
"subscribe" ->
{mod_roster:in_subscription(User,
{FU, FS, ""},
FromU,
subscribe),
true};
"subscribed" ->
{mod_roster:in_subscription(User,
{FU, FS, ""},
FromU,
subscribed),
true};
"unsubscribe" ->
{mod_roster:in_subscription(User,
{FU, FS, ""},
FromU,
unsubscribe),
true};
"unsubscribed" ->
{mod_roster:in_subscription(User,
{FU, FS, ""},
FromU,
unsubscribed),
true};
_ ->
@ -211,8 +212,6 @@ do_route(From, To, Packet) ->
end,
if Pass ->
LFrom = jlib:jid_tolower(From),
LUser = jlib:tolower(User),
LServer = jlib:tolower(Server),
Resources = get_user_resources(User),
if
Resources /= [] ->
@ -223,7 +222,7 @@ do_route(From, To, Packet) ->
ejabberd_sm !
{route,
From,
{User, Server, R},
jlib:jid_replace_resource(To, R),
Packet};
true ->
ok
@ -250,21 +249,25 @@ do_route(From, To, Packet) ->
fun(R) ->
ejabberd_sm ! {route,
From,
{User, Server, R},
jlib:jid_replace_resource(To, R),
Packet}
end, get_user_resources(User));
_ ->
ok
end;
_ ->
LUR = {jlib:tolower(User), Resource},
LUR = {LUser, LResource},
Sess = mnesia:dirty_read({session, LUR}),
case Sess of
[] ->
if
Name == "message" ->
case Name of
"message" ->
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", [])
end;
[Ses] ->
@ -282,10 +285,10 @@ do_route(From, To, Packet) ->
end.
route_message(From, To, Packet) ->
{User, Server, Resource} = To,
case catch lists:max(get_user_present_resources(User)) of
#jid{luser = LUser} = To,
case catch lists:max(get_user_present_resources(LUser)) of
{'EXIT', _} ->
case ejabberd_auth:is_user_exists(User) of
case ejabberd_auth:is_user_exists(LUser) of
true ->
case catch mod_offline:store_packet(From, To, Packet) of
{'EXIT', _} ->
@ -303,7 +306,7 @@ route_message(From, To, Packet) ->
{_, R} ->
ejabberd_sm ! {route,
From,
{User, Server, R},
jlib:jid_replace_resource(To, R),
Packet}
end.
@ -311,7 +314,7 @@ route_message(From, To, Packet) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_user_resources(User) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
case catch mnesia:dirty_index_read(session, LUser, #session.user) of
{'EXIT', Reason} ->
[];
@ -325,7 +328,7 @@ get_user_resources(User) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set_presence(User, Resource, Priority) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
UR = {User, Resource},
mnesia:write(#presence{ur = UR, user = LUser,
@ -334,15 +337,14 @@ set_presence(User, Resource, Priority) ->
mnesia:transaction(F).
unset_presence(User, Resource) ->
LUser = jlib:tolower(User),
LUser = jlib:nodeprep(User),
F = fun() ->
UR = {User, Resource},
mnesia:delete({presence, UR})
end,
mnesia:transaction(F).
get_user_present_resources(User) ->
LUser = jlib:tolower(User),
get_user_present_resources(LUser) ->
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
{'EXIT', Reason} ->
[];
@ -367,7 +369,7 @@ process_iq(From, To, Packet) ->
{iq, ID, Type, XMLNS, SubEl} ->
case ets:lookup(sm_iqtable, XMLNS) of
[{_, Module, Function}] ->
ResIQ = apply(Module, Function, [From, To, IQ]),
ResIQ = Module:Function(From, To, IQ),
if
ResIQ /= ignore ->
ejabberd_router ! {route,

View File

@ -18,12 +18,18 @@
replace_from_to_attrs/3,
replace_from_to/3,
remove_attr/2,
make_jid/3,
make_jid/1,
string_to_jid/1,
jid_to_string/1,
is_nodename/1,
tolower/1,
nodeprep/1,
nameprep/1,
resourceprep/1,
jid_tolower/1,
jid_remove_resource/1,
jid_replace_resource/2,
get_iq_namespace/1,
iq_query_info/1,
is_iq_request_type/1,
@ -130,6 +136,30 @@ remove_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
NewAttrs = lists:keydelete(Attr, 1, Attrs),
{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_jid1(J, "").
@ -157,7 +187,7 @@ string_to_jid1([C | J], N) ->
string_to_jid1([], "") ->
error;
string_to_jid1([], N) ->
{"", lists:reverse(N), ""}.
make_jid("", lists:reverse(N), "").
string_to_jid2([$/ | J], N, "") ->
error;
@ -168,13 +198,15 @@ string_to_jid2([C | J], N, S) ->
string_to_jid2([], N, "") ->
error;
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(J, N, S, [C | 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}) ->
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}) ->
{tolower(U), tolower(S), R}.
jid_remove_resource(#jid{} = JID) ->
JID#jid{resource = "", lresource = ""};
jid_remove_resource({U, S, R}) ->
{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" ->
case xml:remove_cdata(Els) of
[{xmlelement, Name2, Attrs2, Els2}] ->
@ -276,29 +329,29 @@ get_iq_namespace(_) ->
iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
ID = xml:get_attr_s("id", 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
"set" -> set;
"get" -> get;
"result" -> reply;
"error" -> reply;
_ -> invalid
end,
if
(Type1 /= invalid) and (Type1 /= reply) and (XMLNS /= "") ->
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}};
true ->
Type1 = case Type of
"set" -> set;
"get" -> get;
"result" -> reply;
"error" -> reply;
_ -> invalid
end,
if
(Type1 /= invalid) and (Type1 /= reply) ->
case xml:remove_cdata(Els) of
[{xmlelement, Name2, Attrs2, Els2}] ->
XMLNS = xml:get_attr_s("xmlns", Attrs2),
if
Type1 == reply ->
reply;
XMLNS /= "" ->
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}};
true ->
invalid
end
end;
_ ->
invalid
end;
_ ->
invalid
true ->
Type1
end;
iq_query_info(_) ->
not_iq.

View File

@ -138,4 +138,6 @@
% ?STREAM_ERROR("")).
-record(jid, {user, server, resource,
luser, lserver, lresource}).

View File

@ -436,7 +436,7 @@ get_stopped_nodes(Lang) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
{deny, _} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};

View File

@ -57,7 +57,7 @@ loop(Host) ->
do_route(Host, From, To, Packet) ->
{ChanServ, _, Resource} = To,
#jid{user = ChanServ, resource = Resource} = To,
case ChanServ of
"" ->
case Resource of
@ -75,12 +75,11 @@ do_route(Host, From, To, Packet) ->
iq_data(From, To, ID, XMLNS, Type, SubEl);
_ ->
Err = jlib:make_error_reply(
Packet, "503", "Service Unavailable"),
Packet, ?ERR_SERVICE_UNAVAILABLE),
ejabberd_router:route(To, From, Err)
end;
_ ->
Err = jlib:make_error_reply(Packet,
"406", "Not Acceptable"),
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
ejabberd_router:route(To, From, Err)
end;
_ ->
@ -115,8 +114,7 @@ do_route(Host, From, To, Packet) ->
case ets:lookup(irc_connection, {From, Server}) of
[] ->
Err = jlib:make_error_reply(
Packet,
"503", "Service Unavailable"),
Packet, ?ERR_SERVICE_UNAVAILABLE),
ejabberd_router:route(To, From, Err);
[R] ->
Pid = R#irc_connection.pid,
@ -128,7 +126,7 @@ do_route(Host, From, To, Packet) ->
end;
_ ->
Err = jlib:make_error_reply(
Packet, "406", "Not Acceptable"),
Packet, ?ERR_BAD_REQUEST),
ejabberd_router:route(To, From, Err)
end
end
@ -185,9 +183,7 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
case XData of
invalid ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", "400"}],
[{xmlcdata, "Bad Request"}]}]};
[SubEl, ?ERR_BAD_REQUEST]};
_ ->
Node =
string:tokens(
@ -227,8 +223,8 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
get_form(From, [], Lang) ->
{User, Server, _} = From,
{LUser, LServer, _} = jlib:jid_tolower(From),
#jid{user = User, server = Server,
luser = LUser, lserver = LServer} = From,
Customs =
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
{'EXIT', Reason} ->
@ -345,8 +341,8 @@ set_form(_, _, Lang, XData) ->
get_user_and_encoding(From, IRCServer) ->
{User, Server, _} = From,
{LUser, LServer, _} = jlib:jid_tolower(From),
#jid{user = User, server = Server,
luser = LUser, lserver = LServer} = From,
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
{'EXIT', Reason} ->
{User, ?DEFAULT_IRC_ENCODING};

View File

@ -36,7 +36,7 @@
channels = dict:new(),
inbuf = "", outbuf = ""}).
-define(DBGFSM, true).
%-define(DBGFSM, true).
-ifdef(DBGFSM).
-define(FSMOPTS, [{debug, [trace]}]).
@ -411,7 +411,7 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) ->
[From, "NICK", Nick | _] ->
process_nick(StateData, From, Nick);
_ ->
io:format("unknown irc command '~s'~n", [String]),
?DEBUG("unknown irc command '~s'~n", [String]),
StateData
end,
NewStateData1 =
@ -431,7 +431,7 @@ handle_info({ircstring, [$E, $R, $R, $O, $R | _] = String},
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};
@ -441,7 +441,7 @@ handle_info({send_text, Text}, StateName, StateData) ->
handle_info({tcp, Socket, Data}, StateName, StateData) ->
Buf = StateData#state.inbuf ++ binary_to_list(Data),
{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),
{next_state, StateName, StateData#state{inbuf = NewBuf}};
handle_info({tcp_closed, Socket}, StateName, StateData) ->
@ -499,7 +499,7 @@ receiver(Socket, C2SPid, XMLStreamPid) ->
send_text(#state{socket = Socket, encoding = Encoding}, 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).

View File

@ -59,6 +59,7 @@
-record(state, {room,
host,
jid,
config = #config{},
users = ?DICT:new(),
affiliations = ?DICT:new(),
@ -117,11 +118,13 @@ init([Host, Room, Creator, Nick]) ->
LCreator = jlib:jid_tolower(Creator),
State = set_affiliation(Creator, owner,
#state{host = Host,
room = Room}),
room = Room,
jid = jlib:make_jid(Room, Host, "")}),
{ok, normal_state, State};
init([Host, Room, Opts]) ->
State = set_opts(Opts, #state{host = Host,
room = Room}),
room = Room,
jid = jlib:make_jid(Room, Host, "")}),
{ok, normal_state, State}.
%%----------------------------------------------------------------------
@ -173,9 +176,9 @@ normal_state({route, From, "",
lists:foreach(
fun({LJID, Info}) ->
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
FromNick},
jlib:jid_replace_resource(
StateData#state.jid,
FromNick),
Info#user.jid,
Packet)
end,
@ -189,8 +192,7 @@ normal_state({route, From, "",
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room,
StateData#state.host, ""},
StateData#state.jid,
From, Err),
{next_state, normal_state, StateData}
end;
@ -198,7 +200,7 @@ normal_state({route, From, "",
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ""},
StateData#state.jid,
From, Err),
{next_state, normal_state, StateData}
end;
@ -223,7 +225,7 @@ normal_state({route, From, "",
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ""},
StateData#state.jid,
From, Err),
{next_state, normal_state, StateData};
IJID ->
@ -249,15 +251,14 @@ normal_state({route, From, "",
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ""},
StateData#state.jid,
From, Err),
{next_state, normal_state, StateData}
end;
_ ->
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ""}, From, Err),
ejabberd_router:route(StateData#state.jid, From, Err),
{next_state, normal_state, StateData}
end;
@ -293,9 +294,7 @@ normal_state({route, From, "",
[SubEl, Error]},
StateData}
end,
ejabberd_router:route({StateData#state.room,
StateData#state.host,
""},
ejabberd_router:route(StateData#state.jid,
From,
jlib:iq_to_xml(IQRes)),
case NewStateData of
@ -307,8 +306,7 @@ normal_state({route, From, "",
_ ->
Err = jlib:make_error_reply(
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ""}, From, Err),
ejabberd_router:route(StateData#state.jid, From, Err),
{next_state, normal_state, StateData}
end;
@ -353,9 +351,9 @@ normal_state({route, From, Nick,
Packet,
?ERR_MUC_NICK_CHANGE_CONFLICT),
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
Nick}, % TODO: s/Nick/""/
jlib:jid_replace_resource(
StateData#state.jid,
Nick), % TODO: s/Nick/""/
From, Err),
StateData;
_ ->
@ -411,18 +409,18 @@ normal_state({route, From, ToNick,
Err = jlib:make_error_reply(
Packet, ?ERR_ITEM_NOT_FOUND),
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
ToNick},
jlib:jid_replace_resource(
StateData#state.jid,
ToNick),
From, Err);
ToJID ->
{ok, #user{nick = FromNick}} =
?DICT:find(jlib:jid_tolower(From),
StateData#state.users),
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
FromNick},
jlib:jid_replace_resource(
StateData#state.jid,
FromNick),
ToJID, Packet)
end,
{next_state, normal_state, StateData};
@ -430,9 +428,9 @@ normal_state({route, From, ToNick,
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
ToNick}, From, Err),
jlib:jid_replace_resource(
StateData#state.jid,
ToNick), From, Err),
{next_state, normal_state, StateData}
end
end;
@ -448,21 +446,22 @@ normal_state({route, From, ToNick,
Err = jlib:make_error_reply(
Packet, ?ERR_ITEM_NOT_FOUND),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ToNick},
jlib:jid_replace_resource(StateData#state.jid, ToNick),
From, Err);
ToJID ->
{ok, #user{nick = FromNick}} =
?DICT:find(jlib:jid_tolower(From),
StateData#state.users),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, FromNick},
jlib:jid_replace_resource(StateData#state.jid, FromNick),
ToJID, Packet)
end;
_ ->
Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, ToNick}, From, Err)
jlib:jid_replace_resource(StateData#state.jid, ToNick), From,
Err)
end,
{next_state, normal_state, StateData};
@ -490,9 +489,7 @@ handle_event({service_message, Msg}, StateName, StateData) ->
lists:foreach(
fun({LJID, Info}) ->
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
""},
StateData#state.jid,
Info#user.jid,
MessagePkt)
end,
@ -792,9 +789,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
true ->
Err = jlib:make_error_reply(Packet, ?ERR_MUC_NICK_CONFLICT),
ejabberd_router:route(
{StateData#state.room,
StateData#state.host,
Nick}, % TODO: s/Nick/""/
% TODO: s/Nick/""/
jlib:jid_replace_resource(StateData#state.jid, Nick),
From, Err),
StateData;
_ ->
@ -809,7 +805,7 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
_ -> ?ERR_MUC_NOT_MEMBER
end),
ejabberd_router:route( % TODO: s/Nick/""/
{StateData#state.room, StateData#state.host, Nick},
jlib:jid_replace_resource(StateData#state.jid, Nick),
From, Err),
StateData;
_ ->
@ -833,7 +829,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
Err = jlib:make_error_reply(
Packet, ?ERR_MUC_BAD_PASSWORD),
ejabberd_router:route( % TODO: s/Nick/""/
{StateData#state.room, StateData#state.host, Nick},
jlib:jid_replace_resource(
StateData#state.jid, Nick),
From, Err),
StateData
end
@ -922,7 +919,7 @@ send_new_presence(NJID, StateData) ->
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
[{xmlelement, "item", ItemAttrs, []}]}]),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, Nick},
jlib:jid_replace_resource(StateData#state.jid, Nick),
Info#user.jid,
Packet)
end, ?DICT:to_list(StateData#state.users)).
@ -963,7 +960,8 @@ send_existing_presences(ToJID, StateData) ->
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
[{xmlelement, "item", ItemAttrs, []}]}]),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, FromNick},
jlib:jid_replace_resource(
StateData#state.jid, FromNick),
RealToJID,
Packet)
end
@ -1033,11 +1031,11 @@ send_nick_changing(JID, OldNick, StateData) ->
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
[{xmlelement, "item", ItemAttrs2, []}]}]),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, OldNick},
jlib:jid_replace_resource(StateData#state.jid, OldNick),
Info#user.jid,
Packet1),
ejabberd_router:route(
{StateData#state.room, StateData#state.host, Nick},
jlib:jid_replace_resource(StateData#state.jid, Nick),
Info#user.jid,
Packet2)
end, ?DICT:to_list(StateData#state.users)).