mirror of
https://github.com/processone/ejabberd.git
synced 2024-10-05 14:51:05 +02:00
* src/cyrsasl*.erl: SASL support (currently support only PLAIN
mechanism) * src/ejabberd_c2s.erl: Likewise (all): Support for new-style error elements (except old errors "Not Acceptable", "Not Found", "Invalid Namespace" and "Server Connect Failed", so ejabberd may work unstable) SVN Revision: 86
This commit is contained in:
parent
658552d605
commit
f3916bddd2
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
2003-03-09 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/cyrsasl*.erl: SASL support (currently support only PLAIN
|
||||
mechanism)
|
||||
* src/ejabberd_c2s.erl: Likewise
|
||||
|
||||
(all): Support for new-style error elements (except old errors
|
||||
"Not Acceptable", "Not Found", "Invalid Namespace" and "Server
|
||||
Connect Failed", so ejabberd may work unstable)
|
||||
|
||||
2003-03-02 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/ejabberd_c2s.erl: More correct stream closing
|
||||
|
77
src/cyrsasl.erl
Normal file
77
src/cyrsasl.erl
Normal file
@ -0,0 +1,77 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : cyrsasl.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : Cyrus SASL-like library
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0,
|
||||
register_mechanism/2,
|
||||
listmech/0,
|
||||
server_new/4,
|
||||
server_start/3,
|
||||
server_step/2]).
|
||||
|
||||
-record(sasl_mechanism, {mechanism, module}).
|
||||
-record(sasl_state, {service, myname, realm, mech_mod, mech_state}).
|
||||
|
||||
-export([behaviour_info/1]).
|
||||
|
||||
behaviour_info(callbacks) ->
|
||||
[{mech_new, 0},
|
||||
{mech_step, 2}];
|
||||
behaviour_info(Other) ->
|
||||
undefined.
|
||||
|
||||
start() ->
|
||||
ets:new(sasl_mechanism, [named_table,
|
||||
public,
|
||||
{keypos, #sasl_mechanism.mechanism}]),
|
||||
cyrsasl_plain:start([]),
|
||||
ok.
|
||||
|
||||
register_mechanism(Mechanism, Module) ->
|
||||
ets:insert(sasl_mechanism, #sasl_mechanism{mechanism = Mechanism,
|
||||
module = Module}).
|
||||
|
||||
listmech() ->
|
||||
ets:select(sasl_mechanism,
|
||||
[{#sasl_mechanism{mechanism = '$1', _ = '_'}, [], ['$1']}]).
|
||||
|
||||
|
||||
server_new(Service, ServerFQDN, UserRealm, SecFlags) ->
|
||||
#sasl_state{service = Service,
|
||||
myname = ServerFQDN,
|
||||
realm = UserRealm}.
|
||||
|
||||
server_start(State, Mech, ClientIn) ->
|
||||
case ets:lookup(sasl_mechanism, Mech) of
|
||||
[#sasl_mechanism{module = Module}] ->
|
||||
MechState = Module:mech_new(),
|
||||
server_step(State#sasl_state{mech_mod = Module,
|
||||
mech_state = MechState},
|
||||
ClientIn);
|
||||
_ ->
|
||||
{error, "454"}
|
||||
end.
|
||||
|
||||
server_step(State, ClientIn) ->
|
||||
Module = State#sasl_state.mech_mod,
|
||||
MechState = State#sasl_state.mech_state,
|
||||
case Module:mech_step(MechState, ClientIn) of
|
||||
{ok, Props} ->
|
||||
{ok, Props};
|
||||
{continue, ServerOut, NewMechState} ->
|
||||
{continue, ServerOut,
|
||||
State#sasl_state{mech_state = NewMechState}};
|
||||
{error, Code} ->
|
||||
{error, Code}
|
||||
end.
|
||||
|
||||
|
||||
|
56
src/cyrsasl_plain.erl
Normal file
56
src/cyrsasl_plain.erl
Normal file
@ -0,0 +1,56 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : cyrsasl_plain.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : PLAIN SASL mechanism
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl_plain).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/1, stop/0, mech_new/0, mech_step/2, parse/1]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
%-behaviour(gen_mod).
|
||||
|
||||
start(Opts) ->
|
||||
cyrsasl:register_mechanism("PLAIN", ?MODULE),
|
||||
ok.
|
||||
|
||||
stop() ->
|
||||
ok.
|
||||
|
||||
mech_new() ->
|
||||
{ok, []}.
|
||||
|
||||
mech_step(State, ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
[_, User, Password] ->
|
||||
case ejabberd_auth:check_password(User, Password) of
|
||||
true ->
|
||||
{ok, [{username, User}]};
|
||||
_ ->
|
||||
{error, "454"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "454"}
|
||||
end.
|
||||
|
||||
|
||||
parse(S) ->
|
||||
parse1(S, "", []).
|
||||
|
||||
parse1([0 | Cs], S, T) ->
|
||||
parse1(Cs, "", [lists:reverse(S) | T]);
|
||||
parse1([C | Cs], S, T) ->
|
||||
parse1(Cs, [C | S], T);
|
||||
%parse1([], [], T) ->
|
||||
% lists:reverse(T);
|
||||
parse1([], S, T) ->
|
||||
lists:reverse([lists:reverse(S) | T]).
|
||||
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@ start(normal, Args) ->
|
||||
gen_mod:start(),
|
||||
ejabberd_config:start(),
|
||||
ejabberd_auth:start(),
|
||||
cyrsasl:start(),
|
||||
Sup = ejabberd_sup:start_link(),
|
||||
start(),
|
||||
load_modules(),
|
||||
|
@ -109,14 +109,8 @@ terminate(Reason, State) ->
|
||||
|
||||
check_password(User, Password) ->
|
||||
LUser = jlib:tolower(User),
|
||||
F = fun() ->
|
||||
case mnesia:read({passwd, LUser}) of
|
||||
[E] ->
|
||||
E#passwd.password
|
||||
end
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, Password} ->
|
||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||
[#passwd{password = Password}] ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
|
@ -16,7 +16,12 @@
|
||||
-export([start/2, receiver/4, send_text/2, send_element/2]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1, wait_for_stream/2, wait_for_auth/2, session_established/2,
|
||||
-export([init/1,
|
||||
wait_for_stream/2,
|
||||
wait_for_auth/2,
|
||||
wait_for_sasl_auth/2,
|
||||
wait_for_resource_auth/2,
|
||||
session_established/2,
|
||||
handle_event/3,
|
||||
handle_sync_event/4,
|
||||
code_change/4,
|
||||
@ -24,11 +29,12 @@
|
||||
terminate/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
-record(state, {socket, receiver, streamid,
|
||||
sasl_state,
|
||||
access,
|
||||
shaper,
|
||||
user = "", server = ?MYNAME, resource = "",
|
||||
@ -52,14 +58,16 @@
|
||||
"<?xml version='1.0'?>"
|
||||
"<stream:stream xmlns='jabber:client' "
|
||||
"xmlns:stream='http://etherx.jabber.org/streams' "
|
||||
"id='~s' from='~s'>"
|
||||
"id='~s' from='~s'~s>"
|
||||
).
|
||||
|
||||
-define(STREAM_TRAILER, "</stream:stream>").
|
||||
|
||||
-define(INVALID_NS_ERR, "<stream:error>Invalid Namespace</stream:error>").
|
||||
%-define(INVALID_XML_ERR,
|
||||
% "<stream:error code='400'>Invalid XML</stream:error>").
|
||||
-define(INVALID_XML_ERR,
|
||||
"<stream:error code='400'>Invalid XML</stream:error>").
|
||||
xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
@ -102,21 +110,48 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
%%----------------------------------------------------------------------
|
||||
|
||||
wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
||||
% TODO
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.streamid, ?MYNAME]),
|
||||
send_text(StateData#state.socket, Header),
|
||||
case lists:keysearch("xmlns:stream", 1, Attrs) of
|
||||
{value, {"xmlns:stream", "http://etherx.jabber.org/streams"}} ->
|
||||
% TODO
|
||||
{next_state, wait_for_auth, StateData};
|
||||
case xml:get_attr_s("xmlns:stream", Attrs) of
|
||||
?NS_STREAM ->
|
||||
case xml:get_attr_s("version", Attrs) of
|
||||
"1.0" ->
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.streamid,
|
||||
?MYNAME,
|
||||
" version='1.0'"]),
|
||||
send_text(StateData#state.socket, Header),
|
||||
SASLState = cyrsasl:server_new("jabber", ?MYNAME, "", []),
|
||||
Mechs = lists:map(fun(S) ->
|
||||
{xmlelement, "mechanism", [],
|
||||
[{xmlcdata, S}]}
|
||||
end, cyrsasl:listmech()),
|
||||
send_element(StateData#state.socket,
|
||||
{xmlelement, "stream:features", [],
|
||||
[{xmlelement, "mechanisms",
|
||||
[{"xmlns", ?NS_SASL_MECHANISMS}],
|
||||
Mechs}]}),
|
||||
{next_state, wait_for_sasl_auth,
|
||||
StateData#state{sasl_state = SASLState}};
|
||||
_ ->
|
||||
Header = io_lib:format(
|
||||
?STREAM_HEADER,
|
||||
[StateData#state.streamid, ?MYNAME, ""]),
|
||||
send_text(StateData#state.socket, Header),
|
||||
{next_state, wait_for_auth, StateData}
|
||||
end;
|
||||
_ ->
|
||||
send_text(StateData#state.socket, ?INVALID_NS_ERR ?STREAM_TRAILER),
|
||||
Header = io_lib:format(
|
||||
?STREAM_HEADER,
|
||||
[StateData#state.streamid, ?MYNAME, ""]),
|
||||
send_text(StateData#state.socket,
|
||||
Header ++ ?INVALID_NS_ERR ?STREAM_TRAILER),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
|
||||
wait_for_stream({xmlstreamerror, _}, StateData) ->
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR),
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
["none", ?MYNAME, " version='1.0'"]),
|
||||
send_text(StateData#state.socket,
|
||||
Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_stream(closed, StateData) ->
|
||||
@ -125,11 +160,26 @@ wait_for_stream(closed, StateData) ->
|
||||
|
||||
wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
case is_auth_packet(El) of
|
||||
{auth, ID, {U, P, D, ""}} ->
|
||||
{auth, ID, get, {"", _, _, _}} ->
|
||||
Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_auth, StateData};
|
||||
{auth, ID, {U, P, D, R}} ->
|
||||
{auth, ID, get, {U, _, _, _}} ->
|
||||
{xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El),
|
||||
Res = {xmlelement, Name, Attrs,
|
||||
[{xmlelement, "query", [{"xmlns", ?NS_AUTH}],
|
||||
[{xmlelement, "username", [], [{xmlcdata, U}]},
|
||||
{xmlelement, "password", [], []},
|
||||
{xmlelement, "digest", [], []},
|
||||
{xmlelement, "resource", [], []}
|
||||
]}]},
|
||||
send_element(StateData#state.socket, Res),
|
||||
{next_state, wait_for_auth, StateData};
|
||||
{auth, ID, set, {U, P, D, ""}} ->
|
||||
Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{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},
|
||||
case acl:match_rule(StateData#state.access, JID) of
|
||||
@ -149,12 +199,12 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
pres_t = ?SETS:from_list(Ts)}};
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
El, "401", "Unauthorized"),
|
||||
El, ?ERR_FORBIDDEN),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_auth, StateData}
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(El, "405", "Not Allowed"),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_auth, StateData}
|
||||
end;
|
||||
@ -180,12 +230,152 @@ wait_for_auth({xmlstreamend, Name}, StateData) ->
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_auth({xmlstreamerror, _}, StateData) ->
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR ?STREAM_TRAILER),
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_auth(closed, StateData) ->
|
||||
{stop, normal, StateData}.
|
||||
|
||||
|
||||
wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
|
||||
{xmlelement, Name, Attrs, Els} = El,
|
||||
case {xml:get_attr_s("xmlns", Attrs), Name} of
|
||||
{?NS_SASL_MECHANISMS, "auth"} ->
|
||||
Mech = xml:get_attr_s("mechanism", Attrs),
|
||||
ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
|
||||
case cyrsasl:server_start(StateData#state.sasl_state,
|
||||
Mech,
|
||||
ClientIn) of
|
||||
{ok, Props} ->
|
||||
send_element(StateData#state.socket,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL_MECHANISMS}], []}),
|
||||
{next_state, wait_for_resource_auth,
|
||||
StateData#state{user = xml:get_attr_s(username, Props)}};
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
send_element(StateData#state.socket,
|
||||
{xmlelement, "challenge",
|
||||
[{"xmlns", ?NS_SASL_MECHANISMS}],
|
||||
[{xmlcdata,
|
||||
jlib:encode_base64(ServerOut)}]}),
|
||||
{next_state, wait_for_sasl_response, StateData};
|
||||
{error, Code} ->
|
||||
send_element(StateData#state.socket,
|
||||
{xmlelement, "failure",
|
||||
[{"xmlns", ?NS_SASL_MECHANISMS},
|
||||
{"code", Code}],
|
||||
[]}),
|
||||
{next_state, wait_for_sasl_auth, StateData}
|
||||
end;
|
||||
_ ->
|
||||
case jlib:iq_query_info(El) of
|
||||
{iq, ID, Type, ?NS_REGISTER, SubEl} ->
|
||||
ResIQ = mod_register:process_iq(
|
||||
{"", "", ""}, {"", ?MYNAME, ""},
|
||||
{iq, ID, Type, ?NS_REGISTER, SubEl}),
|
||||
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
|
||||
{"", "", ""},
|
||||
jlib:iq_to_xml(ResIQ)),
|
||||
Res = jlib:remove_attr("to", Res1),
|
||||
send_element(StateData#state.socket, Res),
|
||||
{next_state, wait_for_sasl_auth, StateData};
|
||||
_ ->
|
||||
{next_state, wait_for_sasl_auth, StateData}
|
||||
end
|
||||
end;
|
||||
|
||||
wait_for_sasl_auth({xmlstreamend, Name}, StateData) ->
|
||||
send_text(StateData#state.socket, ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_sasl_auth({xmlstreamerror, _}, StateData) ->
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_sasl_auth(closed, StateData) ->
|
||||
{stop, normal, StateData}.
|
||||
|
||||
|
||||
wait_for_resource_auth({xmlstreamelement, El}, StateData) ->
|
||||
case is_auth_packet(El) of
|
||||
{auth, ID, get, {"", _, _, _}} ->
|
||||
Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_resource_auth, StateData};
|
||||
{auth, ID, get, {U, _, _, _}} ->
|
||||
{xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El),
|
||||
Res = {xmlelement, Name, Attrs,
|
||||
[{xmlelement, "query", [{"xmlns", ?NS_AUTH}],
|
||||
[{xmlelement, "username", [],
|
||||
[{xmlcdata, StateData#state.user}]},
|
||||
{xmlelement, "resource", [], []}
|
||||
]}]},
|
||||
send_element(StateData#state.socket, Res),
|
||||
{next_state, wait_for_resource_auth, StateData};
|
||||
{auth, ID, set, {U, _, _, ""}} ->
|
||||
Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_resource_auth, StateData};
|
||||
{auth, ID, set, {U, _, _, R}} ->
|
||||
case StateData#state.user of
|
||||
U ->
|
||||
io:format("SASLAUTH: ~p~n", [{U, R}]),
|
||||
JID = {U, ?MYNAME, R},
|
||||
case acl:match_rule(StateData#state.access, JID) of
|
||||
allow ->
|
||||
ejabberd_sm:open_session(U, R),
|
||||
Res = jlib:make_result_iq_reply(El),
|
||||
send_element(StateData#state.socket, Res),
|
||||
change_shaper(StateData, JID),
|
||||
{Fs, Ts} = mod_roster:get_subscription_lists(U),
|
||||
{next_state, session_established,
|
||||
StateData#state{user = U,
|
||||
resource = R,
|
||||
pres_f = ?SETS:from_list(Fs),
|
||||
pres_t = ?SETS:from_list(Ts)}};
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_resource_auth, StateData}
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(El, "406", "Not Acceptable"),
|
||||
send_element(StateData#state.socket, Err),
|
||||
{next_state, wait_for_resource_auth, StateData}
|
||||
end;
|
||||
_ ->
|
||||
case jlib:iq_query_info(El) of
|
||||
{iq, ID, Type, ?NS_REGISTER, SubEl} ->
|
||||
ResIQ = mod_register:process_iq(
|
||||
{"", "", ""}, {"", ?MYNAME, ""},
|
||||
{iq, ID, Type, ?NS_REGISTER, SubEl}),
|
||||
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
|
||||
{"", "", ""},
|
||||
jlib:iq_to_xml(ResIQ)),
|
||||
Res = jlib:remove_attr("to", Res1),
|
||||
send_element(StateData#state.socket, Res),
|
||||
{next_state, wait_for_resource_auth, StateData};
|
||||
_ ->
|
||||
{next_state, wait_for_resource_auth, StateData}
|
||||
end
|
||||
end;
|
||||
|
||||
wait_for_resource_auth({xmlstreamend, Name}, StateData) ->
|
||||
send_text(StateData#state.socket, ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_resource_auth({xmlstreamerror, _}, StateData) ->
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_resource_auth(closed, StateData) ->
|
||||
{stop, normal, StateData}.
|
||||
|
||||
|
||||
% TODO: wait_for_sasl_response
|
||||
|
||||
|
||||
|
||||
session_established({xmlstreamelement, El}, StateData) ->
|
||||
{xmlelement, Name, Attrs, Els} = El,
|
||||
Server = StateData#state.server,
|
||||
@ -227,7 +417,7 @@ session_established({xmlstreamend, Name}, StateData) ->
|
||||
{stop, normal, StateData};
|
||||
|
||||
session_established({xmlstreamerror, _}, StateData) ->
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR ?STREAM_TRAILER),
|
||||
send_text(StateData#state.socket, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
session_established(closed, StateData) ->
|
||||
@ -427,7 +617,7 @@ is_auth_packet(El) ->
|
||||
case jlib:iq_query_info(El) of
|
||||
{iq, ID, Type, ?NS_AUTH, SubEl} ->
|
||||
{xmlelement, _, _, Els} = SubEl,
|
||||
{auth, ID,
|
||||
{auth, ID, Type,
|
||||
get_auth_tags(Els, "", "", "", "")};
|
||||
_ ->
|
||||
false
|
||||
|
@ -18,6 +18,7 @@
|
||||
]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {mydomain, iqtable}).
|
||||
|
||||
@ -78,7 +79,7 @@ do_route(State, From, To, Packet) ->
|
||||
ok
|
||||
end;
|
||||
{"", _, _} ->
|
||||
Err = jlib:make_error_reply(Packet, "404", "Not Found"),
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_JID_NOT_FOUND),
|
||||
ejabberd_router ! {route,
|
||||
{"", State#state.mydomain, ""}, From, Err},
|
||||
ok;
|
||||
@ -116,13 +117,12 @@ process_iq(State, From, To, Packet) ->
|
||||
Err}
|
||||
end;
|
||||
_ ->
|
||||
% TODO
|
||||
ok
|
||||
end;
|
||||
reply ->
|
||||
ok;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet, "400", "Bad Request"),
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
|
||||
ejabberd_router ! {route,
|
||||
{"", State#state.mydomain, ""}, From, Err},
|
||||
ok
|
||||
|
@ -29,7 +29,7 @@
|
||||
terminate/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state, {socket, pid,
|
||||
user = "", server = ?MYNAME, resource = ""
|
||||
|
82
src/jlib.erl
82
src/jlib.erl
@ -12,6 +12,7 @@
|
||||
|
||||
-export([make_result_iq_reply/1,
|
||||
make_error_reply/3,
|
||||
make_error_reply/2,
|
||||
make_error_element/2,
|
||||
make_correct_from_to_attrs/3,
|
||||
replace_from_to_attrs/3,
|
||||
@ -29,9 +30,11 @@
|
||||
iq_to_xml/1,
|
||||
parse_xdata_submit/1,
|
||||
timestamp_to_iso/1,
|
||||
timestamp_to_xml/1]).
|
||||
timestamp_to_xml/1,
|
||||
decode_base64/1,
|
||||
encode_base64/1]).
|
||||
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
%send_iq(From, To, ID, SubTags) ->
|
||||
% ok.
|
||||
@ -67,6 +70,10 @@ make_error_reply({xmlelement, Name, Attrs, SubTags}, Code, Desc) ->
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}.
|
||||
|
||||
make_error_reply({xmlelement, Name, Attrs, SubTags}, Error) ->
|
||||
NewAttrs = make_error_reply_attrs(Attrs),
|
||||
{xmlelement, Name, NewAttrs, SubTags ++ [Error]}.
|
||||
|
||||
make_error_reply_attrs(Attrs) ->
|
||||
To = xml:get_attr("to", Attrs),
|
||||
From = xml:get_attr("from", Attrs),
|
||||
@ -362,3 +369,74 @@ timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
||||
[Year, Month, Day, Hour, Minute, Second]))}],
|
||||
[]}.
|
||||
|
||||
|
||||
%
|
||||
% Base64 stuff (based on httpd_util.erl)
|
||||
%
|
||||
|
||||
decode_base64(S) ->
|
||||
decode1_base64([C || C <- S,
|
||||
C /= $ ,
|
||||
C /= $\t,
|
||||
C /= $\n,
|
||||
C /= $\r]).
|
||||
|
||||
decode1_base64([]) ->
|
||||
[];
|
||||
decode1_base64([Sextet1,Sextet2,$=,$=|Rest]) ->
|
||||
Bits2x6=
|
||||
(d(Sextet1) bsl 18) bor
|
||||
(d(Sextet2) bsl 12),
|
||||
Octet1=Bits2x6 bsr 16,
|
||||
[Octet1|decode_base64(Rest)];
|
||||
decode1_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->
|
||||
Bits3x6=
|
||||
(d(Sextet1) bsl 18) bor
|
||||
(d(Sextet2) bsl 12) bor
|
||||
(d(Sextet3) bsl 6),
|
||||
Octet1=Bits3x6 bsr 16,
|
||||
Octet2=(Bits3x6 bsr 8) band 16#ff,
|
||||
[Octet1,Octet2|decode_base64(Rest)];
|
||||
decode1_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->
|
||||
Bits4x6=
|
||||
(d(Sextet1) bsl 18) bor
|
||||
(d(Sextet2) bsl 12) bor
|
||||
(d(Sextet3) bsl 6) bor
|
||||
d(Sextet4),
|
||||
Octet1=Bits4x6 bsr 16,
|
||||
Octet2=(Bits4x6 bsr 8) band 16#ff,
|
||||
Octet3=Bits4x6 band 16#ff,
|
||||
[Octet1,Octet2,Octet3|decode_base64(Rest)];
|
||||
decode1_base64(CatchAll) ->
|
||||
"".
|
||||
|
||||
d(X) when X >= $A, X =<$Z ->
|
||||
X-65;
|
||||
d(X) when X >= $a, X =<$z ->
|
||||
X-71;
|
||||
d(X) when X >= $0, X =<$9 ->
|
||||
X+4;
|
||||
d($+) -> 62;
|
||||
d($/) -> 63;
|
||||
d(_) -> 63.
|
||||
|
||||
|
||||
encode_base64([]) ->
|
||||
[];
|
||||
encode_base64([A]) ->
|
||||
[e(A bsr 2), e((A band 3) bsl 4), $=, $=];
|
||||
encode_base64([A,B]) ->
|
||||
[e(A bsr 2), e(((A band 3) bsl 4) bor (B bsr 4)), e((B band 15) bsl 2), $=];
|
||||
encode_base64([A,B,C|Ls]) ->
|
||||
encode_base64_do(A,B,C, Ls).
|
||||
encode_base64_do(A,B,C, Rest) ->
|
||||
BB = (A bsl 16) bor (B bsl 8) bor C,
|
||||
[e(BB bsr 18), e((BB bsr 12) band 63),
|
||||
e((BB bsr 6) band 63), e(BB band 63)|encode_base64(Rest)].
|
||||
|
||||
e(X) when X >= 0, X < 26 -> X+65;
|
||||
e(X) when X>25, X<52 -> X+71;
|
||||
e(X) when X>51, X<62 -> X-4;
|
||||
e(62) -> $+;
|
||||
e(63) -> $/;
|
||||
e(X) -> exit({bad_encode_base64_token, X}).
|
||||
|
@ -18,7 +18,7 @@
|
||||
process_sm_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
|
||||
start(Opts) ->
|
||||
@ -37,9 +37,7 @@ stop() ->
|
||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case acl:match_rule(configure, From) of
|
||||
deny ->
|
||||
{iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]};
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
allow ->
|
||||
Lang = xml:get_tag_attr_s("xml:lang", SubEl),
|
||||
case Type of
|
||||
@ -68,11 +66,9 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{"xmlns", XMLNS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
@ -90,11 +86,9 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end
|
||||
end.
|
||||
@ -140,7 +134,7 @@ get_form(["running nodes", ENode, "DB"], Lang) ->
|
||||
Node ->
|
||||
case rpc:call(Node, mnesia, system_info, [tables]) of
|
||||
{badrpc, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
Tables ->
|
||||
STables = lists:sort(Tables),
|
||||
{result, [{xmlelement, "title", [],
|
||||
@ -174,7 +168,7 @@ get_form(["running nodes", ENode, "modules", "stop"], Lang) ->
|
||||
Node ->
|
||||
case rpc:call(Node, gen_mod, loaded_modules, []) of
|
||||
{badrpc, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
Modules ->
|
||||
SModules = lists:sort(Modules),
|
||||
{result, [{xmlelement, "title", [],
|
||||
@ -390,7 +384,7 @@ get_form(["config", "remusers"], Lang) ->
|
||||
};
|
||||
|
||||
get_form(_, Lang) ->
|
||||
{error, "503", "Service Unavailable"}.
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
||||
|
||||
|
||||
@ -493,9 +487,9 @@ set_form(["running nodes", ENode, "backup", "backup"], Lang, XData) ->
|
||||
{value, {_, [String]}} ->
|
||||
case rpc:call(Node, mnesia, backup, [String]) of
|
||||
{badrpc, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
_ ->
|
||||
{result, []}
|
||||
end;
|
||||
@ -517,9 +511,9 @@ set_form(["running nodes", ENode, "backup", "restore"], Lang, XData) ->
|
||||
case rpc:call(Node, mnesia, restore,
|
||||
[String, [{default_op, keep_tables}]]) of
|
||||
{badrpc, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
_ ->
|
||||
{result, []}
|
||||
end;
|
||||
@ -540,9 +534,9 @@ set_form(["running nodes", ENode, "backup", "textfile"], Lang, XData) ->
|
||||
{value, {_, [String]}} ->
|
||||
case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
|
||||
{badrpc, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
_ ->
|
||||
{result, []}
|
||||
end;
|
||||
@ -689,7 +683,7 @@ set_form(["config", "remusers"], Lang, XData) ->
|
||||
{result, []};
|
||||
|
||||
set_form(_, Lang, XData) ->
|
||||
{error, "503", "Service Unavailable"}.
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
||||
|
||||
|
||||
@ -744,11 +738,9 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{"xmlns", XMLNS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
@ -766,11 +758,9 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end
|
||||
end.
|
||||
@ -807,8 +797,8 @@ get_sm_form(User, [], Lang) ->
|
||||
]};
|
||||
|
||||
get_sm_form(_, _, Lang) ->
|
||||
{error, "503", "Service Unavailable"}.
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
||||
|
||||
set_sm_form(_, _, Lang, XData) ->
|
||||
{error, "503", "Service Unavailable"}.
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
@ -22,7 +22,7 @@
|
||||
unregister_feature/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-define(EMPTY_INFO_RESULT,
|
||||
{iq, ID, result, XMLNS, [{xmlelement, "query",
|
||||
@ -62,9 +62,7 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
Lang = xml:get_tag_attr_s("xml:lang", SubEl),
|
||||
case Type of
|
||||
set ->
|
||||
{iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]};
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
get ->
|
||||
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
|
||||
|
||||
@ -74,11 +72,9 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -86,9 +82,7 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
set ->
|
||||
{iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]};
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
get ->
|
||||
case string:tokens(xml:get_tag_attr_s("node", SubEl), "/") of
|
||||
[] ->
|
||||
@ -149,9 +143,7 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[feature_to_xml({?NS_IQDATA})]}]};
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", "501"}],
|
||||
[{xmlcdata, "Not Implemented"}]}]}
|
||||
[SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -204,7 +196,7 @@ get_local_items(["all users"], Server, Lang) ->
|
||||
get_local_items(["all users", [$@ | Diap]], Server, Lang) ->
|
||||
case catch ejabberd_auth:dirty_get_registered_users() of
|
||||
{'EXIT', Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
?ERR_INTERNAL_SERVER_ERROR;
|
||||
Users ->
|
||||
SUsers = lists:sort(Users),
|
||||
case catch begin
|
||||
@ -219,7 +211,8 @@ get_local_items(["all users", [$@ | Diap]], Server, Lang) ->
|
||||
end, Sub)
|
||||
end of
|
||||
{'EXIT', Reason} ->
|
||||
{error, "406", "Not Acceptable"};
|
||||
% TODO: must be "not acceptable"
|
||||
?ERR_BAD_REQUEST;
|
||||
Res ->
|
||||
{result, Res}
|
||||
end
|
||||
@ -279,7 +272,7 @@ get_local_items(["running nodes", ENode, "import", _], Server, Lang) ->
|
||||
{result, []};
|
||||
|
||||
get_local_items(_, _, _) ->
|
||||
{error, "501", "Not Implemented"}.
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
|
||||
|
||||
|
||||
|
||||
@ -413,9 +406,7 @@ process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{User, _, _} = To,
|
||||
case Type of
|
||||
set ->
|
||||
{iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]};
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
get ->
|
||||
case xml:get_tag_attr_s("node", SubEl) of
|
||||
"" ->
|
||||
@ -425,9 +416,7 @@ process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
}]};
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", "501"}],
|
||||
[{xmlcdata, "Not Implemented"}]}]}
|
||||
[SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -435,9 +424,7 @@ process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
process_sm_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
set ->
|
||||
{iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]};
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
get ->
|
||||
case xml:get_tag_attr_s("node", SubEl) of
|
||||
"" ->
|
||||
@ -446,9 +433,7 @@ process_sm_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[feature_to_xml({?NS_IQDATA})]}]};
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", "501"}],
|
||||
[{xmlcdata, "Not Implemented"}]}]}
|
||||
[SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}
|
||||
end
|
||||
end.
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
-export([start/1, init/1, stop/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
get_user_and_encoding/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-define(DEFAULT_IRC_ENCODING, "koi8-r").
|
||||
|
||||
@ -200,18 +200,14 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
|
||||
[{"xmlns", XMLNS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]}
|
||||
[SubEl, ?ERR_NOT_ALLOWED]}
|
||||
end;
|
||||
get ->
|
||||
Node =
|
||||
@ -222,11 +218,9 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
|
||||
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
||||
Res
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -238,7 +232,7 @@ get_form(From, [], Lang) ->
|
||||
Customs =
|
||||
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
||||
{'EXIT', Reason} ->
|
||||
{error, "500", "Internal Server Error"};
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
[] ->
|
||||
{User, []};
|
||||
[#irc_custom{data = Data}] ->
|
||||
@ -302,7 +296,7 @@ get_form(From, [], Lang) ->
|
||||
|
||||
|
||||
get_form(_, _, Lang) ->
|
||||
{error, "503", "Service Unavailable"}.
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
||||
|
||||
|
||||
@ -347,7 +341,7 @@ set_form(From, [], Lang, XData) ->
|
||||
|
||||
|
||||
set_form(_, _, Lang, XData) ->
|
||||
{error, "503", "Service Unavailable"}.
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
||||
|
||||
get_user_and_encoding(From, IRCServer) ->
|
||||
|
@ -27,7 +27,7 @@
|
||||
code_change/4]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
@ -285,7 +285,7 @@ handle_info({route_chan, Channel, Resource,
|
||||
ID, XMLNS, Type, SubEl);
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
El, "503", "Service Unavailable"),
|
||||
El, ?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end,
|
||||
{next_state, StateName, StateData};
|
||||
@ -835,11 +835,9 @@ iq_admin(StateData, Channel, From, To, ID, XMLNS, Type, SubEl) ->
|
||||
[{"xmlns", XMLNS}],
|
||||
ResEls
|
||||
}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end,
|
||||
ejabberd_router:route(To, From,
|
||||
jlib:iq_to_xml(ResIQ));
|
||||
@ -852,7 +850,7 @@ iq_admin(StateData, Channel, From, To, ID, XMLNS, Type, SubEl) ->
|
||||
process_iq_admin(StateData, Channel, set, SubEl) ->
|
||||
case xml:get_subtag(SubEl, "item") of
|
||||
false ->
|
||||
{error, "400", "Bad Request"};
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
ItemEl ->
|
||||
Nick = xml:get_tag_attr_s("nick", ItemEl),
|
||||
Affiliation = xml:get_tag_attr_s("affiliation", ItemEl),
|
||||
@ -861,12 +859,12 @@ process_iq_admin(StateData, Channel, set, SubEl) ->
|
||||
process_admin(StateData, Channel, Nick, Affiliation, Role, Reason)
|
||||
end;
|
||||
process_iq_admin(StateData, Channel, get, SubEl) ->
|
||||
{error, "501", "Not Implemented"}.
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
|
||||
|
||||
|
||||
|
||||
process_admin(StateData, Channel, "", Affiliation, Role, Reason) ->
|
||||
{error, "501", "Not Implemented"};
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED};
|
||||
|
||||
process_admin(StateData, Channel, Nick, Affiliation, "none", Reason) ->
|
||||
case Reason of
|
||||
@ -884,7 +882,7 @@ process_admin(StateData, Channel, Nick, Affiliation, "none", Reason) ->
|
||||
|
||||
|
||||
process_admin(StateData, Channel, Nick, Affiliation, Role, Reason) ->
|
||||
{error, "501", "Not Implemented"}.
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
|
||||
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
resend_offline_messages/1,
|
||||
remove_user/1]).
|
||||
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(offline_msg, {user, timestamp, from, to, packet}).
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
process_local_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(private_storage, {userns, xml}).
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
-export([start/1, init/0, process_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
start(Opts) ->
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
@ -97,12 +97,9 @@ process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case try_register(User, Password) of
|
||||
ok ->
|
||||
{iq, ID, result, XMLNS, [SubEl]};
|
||||
{error, Code, Reason} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement,
|
||||
"error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Reason}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end
|
||||
end;
|
||||
@ -128,9 +125,9 @@ try_register(User, Password) ->
|
||||
{atomic, ok} ->
|
||||
ok;
|
||||
{atomic, exists} ->
|
||||
{error, "400", "Bad Request"};
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
{error, Reason} ->
|
||||
{error, "500", "Internal Server Error"}
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end
|
||||
end.
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
-include_lib("mnemosyne/include/mnemosyne.hrl").
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(roster, {uj,
|
||||
user,
|
||||
|
@ -16,7 +16,7 @@
|
||||
stop/0,
|
||||
process_local_iq/3]).
|
||||
|
||||
-include("namespaces.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
start(Opts) ->
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
@ -43,11 +43,9 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{result, Res} ->
|
||||
{iq, ID, result, XMLNS,
|
||||
[{xmlelement, "query", [{"xmlns", XMLNS}], Res}]};
|
||||
{error, Code, Desc} ->
|
||||
{error, Error} ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", Code}],
|
||||
[{xmlcdata, Desc}]}]}
|
||||
[SubEl, Error]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -98,7 +96,7 @@ get_local_stats(["running nodes", ENode], Names) ->
|
||||
end;
|
||||
|
||||
get_local_stats(_, _) ->
|
||||
{error, "501", "Not Implemented"}.
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
|
||||
|
||||
|
||||
|
||||