* 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:
Alexey Shchepin 2003-03-09 20:46:47 +00:00
parent 658552d605
commit f3916bddd2
22 changed files with 510 additions and 142 deletions

View File

@ -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
View 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
View 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]).

View File

@ -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(),

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -29,7 +29,7 @@
terminate/3]).
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").
-record(state, {socket, pid,
user = "", server = ?MYNAME, resource = ""

View File

@ -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}).

View File

@ -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}.

View File

@ -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.

View File

@ -15,7 +15,7 @@
-export([start/1, init/1, stop/0]).
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").

View File

@ -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) ->

View File

@ -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}.

View File

@ -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}).

View File

@ -17,7 +17,7 @@
process_local_iq/3]).
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").
-record(private_storage, {userns, xml}).

View File

@ -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.

View File

@ -23,7 +23,7 @@
-include_lib("mnemosyne/include/mnemosyne.hrl").
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").
-record(roster, {uj,
user,

View File

@ -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}.

View File

@ -17,7 +17,7 @@
process_local_iq/3]).
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").
start(Opts) ->

View File

@ -19,7 +19,7 @@
remove_user/1]).
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").
-record(vcard_search, {user, luser,

View File

@ -17,7 +17,7 @@
process_local_iq/3]).
-include("ejabberd.hrl").
-include("namespaces.hrl").
-include("jlib.hrl").