Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2003-03-09 23:46:47 +0300
committerAlexey Shchepin <alexey@process-one.net>2003-03-09 23:46:47 +0300
commitf3916bddd2ee79f82c138f2fce09b878ab721cf6 (patch)
treefa3e18694ddc1a8b8c41690061906110bfa370b4 /src
parent658552d605ef440a9b7ebdbbf898983a21567c65 (diff)
* 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
Diffstat (limited to 'src')
-rw-r--r--src/cyrsasl.erl77
-rw-r--r--src/cyrsasl_plain.erl56
-rw-r--r--src/ejabberd_app.erl1
-rw-r--r--src/ejabberd_auth.erl10
-rw-r--r--src/ejabberd_c2s.erl232
-rw-r--r--src/ejabberd_local.erl6
-rw-r--r--src/jd2ejd.erl2
-rw-r--r--src/jlib.erl82
-rw-r--r--src/mod_configure.erl54
-rw-r--r--src/mod_disco.erl43
-rw-r--r--src/mod_echo.erl2
-rw-r--r--src/mod_irc/mod_irc.erl24
-rw-r--r--src/mod_irc/mod_irc_connection.erl18
-rw-r--r--src/mod_offline.erl2
-rw-r--r--src/mod_private.erl2
-rw-r--r--src/mod_register.erl13
-rw-r--r--src/mod_roster.erl2
-rw-r--r--src/mod_stats.erl10
-rw-r--r--src/mod_time.erl2
-rw-r--r--src/mod_vcard.erl2
-rw-r--r--src/mod_version.erl2
21 files changed, 500 insertions, 142 deletions
diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl
new file mode 100644
index 000000000..537ad4f1b
--- /dev/null
+++ b/src/cyrsasl.erl
@@ -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.
+
+
+
diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl
new file mode 100644
index 000000000..46461e1c0
--- /dev/null
+++ b/src/cyrsasl_plain.erl
@@ -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]).
+
+
+
+
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index 7fa071675..80f8e42fb 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -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(),
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index 49d293def..efe9e407b 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -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
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index aa8e241a5..e4150ffda 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -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, 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, {U, P, D, R}} ->
+ {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
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index f2b4de026..0a1b6f63a 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -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
diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl
index ac9f81be2..456fc0a65 100644
--- a/src/jd2ejd.erl
+++ b/src/jd2ejd.erl
@@ -29,7 +29,7 @@
terminate/3]).
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").
-record(state, {socket, pid,
user = "", server = ?MYNAME, resource = ""
diff --git a/src/jlib.erl b/src/jlib.erl
index b9fb8b990..91fd5f076 100644
--- a/src/jlib.erl
+++ b/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}).
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index 248c9e3b6..71ee8f523 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -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}.
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index ec8887276..153ca8ab3 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -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.
diff --git a/src/mod_echo.erl b/src/mod_echo.erl
index 5f02c4002..1b6143a53 100644
--- a/src/mod_echo.erl
+++ b/src/mod_echo.erl
@@ -15,7 +15,7 @@
-export([start/1, init/1, stop/0]).
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").
diff --git a/src/mod_irc/mod_irc.erl b/src/mod_irc/mod_irc.erl
index bd3e69854..f2181ca3e 100644
--- a/src/mod_irc/mod_irc.erl
+++ b/src/mod_irc/mod_irc.erl
@@ -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) ->
diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl
index 172c823a3..b261ae33c 100644
--- a/src/mod_irc/mod_irc_connection.erl
+++ b/src/mod_irc/mod_irc_connection.erl
@@ -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}.
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index e85c9488e..bdddf8e69 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -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}).
diff --git a/src/mod_private.erl b/src/mod_private.erl
index d265088d0..54eb8c05b 100644
--- a/src/mod_private.erl
+++ b/src/mod_private.erl
@@ -17,7 +17,7 @@
process_local_iq/3]).
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").
-record(private_storage, {userns, xml}).
diff --git a/src/mod_register.erl b/src/mod_register.erl
index c585cb715..febc58dd6 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -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.
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index dda0e988a..38b6e36aa 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -23,7 +23,7 @@
-include_lib("mnemosyne/include/mnemosyne.hrl").
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").
-record(roster, {uj,
user,
diff --git a/src/mod_stats.erl b/src/mod_stats.erl
index ff5b65369..c2f432c1c 100644
--- a/src/mod_stats.erl
+++ b/src/mod_stats.erl
@@ -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}.
diff --git a/src/mod_time.erl b/src/mod_time.erl
index a9959398f..36c190774 100644
--- a/src/mod_time.erl
+++ b/src/mod_time.erl
@@ -17,7 +17,7 @@
process_local_iq/3]).
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").
start(Opts) ->
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index b41b21011..409c77b93 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -19,7 +19,7 @@
remove_user/1]).
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").
-record(vcard_search, {user, luser,
diff --git a/src/mod_version.erl b/src/mod_version.erl
index a00d4a08a..53c3a7535 100644
--- a/src/mod_version.erl
+++ b/src/mod_version.erl
@@ -17,7 +17,7 @@
process_local_iq/3]).
-include("ejabberd.hrl").
--include("namespaces.hrl").
+-include("jlib.hrl").