mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-04 16:40:36 +01:00
Merged the Process One contributions ( Virtual Hosting )
SVN Revision: 307
This commit is contained in:
parent
13de45118d
commit
374446f847
@ -13,17 +13,19 @@
|
||||
-export([start/0,
|
||||
register_mechanism/2,
|
||||
listmech/0,
|
||||
server_new/4,
|
||||
server_new/6,
|
||||
server_start/3,
|
||||
server_step/2]).
|
||||
|
||||
-record(sasl_mechanism, {mechanism, module}).
|
||||
-record(sasl_state, {service, myname, realm, mech_mod, mech_state}).
|
||||
-record(sasl_state, {service, myname, realm,
|
||||
get_password, check_password,
|
||||
mech_mod, mech_state}).
|
||||
|
||||
-export([behaviour_info/1]).
|
||||
|
||||
behaviour_info(callbacks) ->
|
||||
[{mech_new, 0},
|
||||
[{mech_new, 2},
|
||||
{mech_step, 2}];
|
||||
behaviour_info(Other) ->
|
||||
undefined.
|
||||
@ -80,15 +82,19 @@ listmech() ->
|
||||
[{#sasl_mechanism{mechanism = '$1', _ = '_'}, [], ['$1']}]).
|
||||
|
||||
|
||||
server_new(Service, ServerFQDN, UserRealm, SecFlags) ->
|
||||
server_new(Service, ServerFQDN, UserRealm, SecFlags,
|
||||
GetPassword, CheckPassword) ->
|
||||
#sasl_state{service = Service,
|
||||
myname = ServerFQDN,
|
||||
realm = UserRealm}.
|
||||
realm = UserRealm,
|
||||
get_password = GetPassword,
|
||||
check_password = CheckPassword}.
|
||||
|
||||
server_start(State, Mech, ClientIn) ->
|
||||
case ets:lookup(sasl_mechanism, Mech) of
|
||||
[#sasl_mechanism{module = Module}] ->
|
||||
{ok, MechState} = Module:mech_new(),
|
||||
{ok, MechState} = Module:mech_new(State#sasl_state.get_password,
|
||||
State#sasl_state.check_password),
|
||||
server_step(State#sasl_state{mech_mod = Module,
|
||||
mech_state = MechState},
|
||||
ClientIn);
|
||||
|
@ -12,15 +12,14 @@
|
||||
|
||||
-export([start/1,
|
||||
stop/0,
|
||||
mech_new/0,
|
||||
mech_new/2,
|
||||
mech_step/2]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
%-behaviour(gen_mod).
|
||||
|
||||
-record(state, {step, nonce, username, authzid}).
|
||||
-record(state, {step, nonce, username, authzid, get_password}).
|
||||
|
||||
start(Opts) ->
|
||||
start(_Opts) ->
|
||||
case ejabberd_auth:plain_password_required() of
|
||||
true ->
|
||||
ok;
|
||||
@ -32,15 +31,15 @@ start(Opts) ->
|
||||
stop() ->
|
||||
ok.
|
||||
|
||||
mech_new() ->
|
||||
mech_new(GetPassword, _CheckPassword) ->
|
||||
{ok, #state{step = 1,
|
||||
nonce = randoms:get_string()}}.
|
||||
nonce = randoms:get_string(),
|
||||
get_password = GetPassword}}.
|
||||
|
||||
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
||||
{continue,
|
||||
"nonce=\"" ++ Nonce ++
|
||||
"\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
|
||||
%"\",qop=\"auth,auth-int\",charset=utf-8,algorithm=md5-sess",
|
||||
State#state{step = 3}};
|
||||
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
@ -49,7 +48,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
KeyVals ->
|
||||
UserName = xml:get_attr_s("username", KeyVals),
|
||||
AuthzId = xml:get_attr_s("authzid", KeyVals),
|
||||
case ejabberd_auth:get_password(UserName) of
|
||||
case (State#state.get_password)(UserName) of
|
||||
false ->
|
||||
{error, "not-authorized"};
|
||||
Passwd ->
|
||||
@ -72,7 +71,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
end;
|
||||
mech_step(#state{step = 5,
|
||||
username = UserName,
|
||||
authzid = AuthzId} = State, "") ->
|
||||
authzid = AuthzId}, "") ->
|
||||
{ok, [{username, UserName}, {authzid, AuthzId}]};
|
||||
mech_step(A, B) ->
|
||||
io:format("SASL DIGEST: A ~p B ~p", [A,B]),
|
||||
@ -88,7 +87,7 @@ parse1([C | Cs], S, Ts) ->
|
||||
parse1(Cs, [C | S], Ts);
|
||||
parse1([], [], T) ->
|
||||
lists:reverse(T);
|
||||
parse1([], S, T) ->
|
||||
parse1([], _S, _T) ->
|
||||
bad.
|
||||
|
||||
parse2([$" | Cs], Key, Val, Ts) ->
|
||||
@ -148,13 +147,13 @@ response(KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) ->
|
||||
crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++
|
||||
":" ++ Nonce ++ ":" ++ CNonce ++ ":" ++ AuthzId
|
||||
end,
|
||||
case QOP of
|
||||
"auth" ->
|
||||
A2 = A2Prefix ++ ":" ++ DigestURI;
|
||||
_ ->
|
||||
A2 = A2Prefix ++ ":" ++ DigestURI ++
|
||||
":00000000000000000000000000000000"
|
||||
end,
|
||||
A2 = case QOP of
|
||||
"auth" ->
|
||||
A2Prefix ++ ":" ++ DigestURI;
|
||||
_ ->
|
||||
A2Prefix ++ ":" ++ DigestURI ++
|
||||
":00000000000000000000000000000000"
|
||||
end,
|
||||
T = hex(binary_to_list(crypto:md5(A1))) ++ ":" ++ Nonce ++ ":" ++
|
||||
NC ++ ":" ++ CNonce ++ ":" ++ QOP ++ ":" ++
|
||||
hex(binary_to_list(crypto:md5(A2))),
|
||||
|
@ -10,25 +10,26 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/1, stop/0, mech_new/0, mech_step/2, parse/1]).
|
||||
-export([start/1, stop/0, mech_new/2, mech_step/2, parse/1]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
%-behaviour(gen_mod).
|
||||
|
||||
start(Opts) ->
|
||||
-record(state, {check_password}).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism("PLAIN", ?MODULE),
|
||||
ok.
|
||||
|
||||
stop() ->
|
||||
ok.
|
||||
|
||||
mech_new() ->
|
||||
{ok, []}.
|
||||
mech_new(_GetPassword, CheckPassword) ->
|
||||
{ok, #state{check_password = CheckPassword}}.
|
||||
|
||||
mech_step(State, ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
[AuthzId, User, Password] ->
|
||||
case ejabberd_auth:check_password(User, Password) of
|
||||
case (State#state.check_password)(User, Password) of
|
||||
true ->
|
||||
{ok, [{username, User}, {authzid, AuthzId}]};
|
||||
_ ->
|
||||
|
@ -27,10 +27,9 @@
|
||||
[self(),?MODULE,?LINE]++Args)).
|
||||
|
||||
|
||||
%-define(MYNAME,"e.localhost").
|
||||
-define(MYNAME, ejabberd_config:get_global_option(host)).
|
||||
-define(MYHOSTS, ejabberd_config:get_global_option(hosts)).
|
||||
-define(MYNAME, hd(ejabberd_config:get_global_option(hosts))).
|
||||
-define(S2STIMEOUT, 600000).
|
||||
%-define(S2STIMEOUT, 6000).
|
||||
-define(MYLANG, ejabberd_config:get_global_option(language)).
|
||||
|
||||
-define(MSGS_DIR, "msgs").
|
||||
|
@ -12,16 +12,17 @@
|
||||
|
||||
%% External exports
|
||||
-export([start/0,
|
||||
set_password/2,
|
||||
check_password/2,
|
||||
check_password/4,
|
||||
try_register/2,
|
||||
set_password/3,
|
||||
check_password/3,
|
||||
check_password/5,
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_password/1,
|
||||
get_password_s/1,
|
||||
is_user_exists/1,
|
||||
remove_user/1,
|
||||
get_vh_registered_users/1,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
is_user_exists/2,
|
||||
remove_user/2,
|
||||
remove_user/3,
|
||||
plain_password_required/0
|
||||
]).
|
||||
|
||||
@ -34,35 +35,38 @@ start() ->
|
||||
plain_password_required() ->
|
||||
(auth_module()):plain_password_required().
|
||||
|
||||
check_password(User, Password) ->
|
||||
(auth_module()):check_password(User, Password).
|
||||
check_password(User, Server, Password) ->
|
||||
(auth_module()):check_password(User, Server, Password).
|
||||
|
||||
check_password(User, Password, StreamID, Digest) ->
|
||||
(auth_module()):check_password(User, Password, StreamID, Digest).
|
||||
check_password(User, Server, Password, StreamID, Digest) ->
|
||||
(auth_module()):check_password(User, Server, Password, StreamID, Digest).
|
||||
|
||||
set_password(User, Password) ->
|
||||
(auth_module()):set_password(User, Password).
|
||||
set_password(User, Server, Password) ->
|
||||
(auth_module()):set_password(User, Server, Password).
|
||||
|
||||
try_register(User, Password) ->
|
||||
(auth_module()):try_register(User, Password).
|
||||
try_register(User, Server, Password) ->
|
||||
(auth_module()):try_register(User, Server, Password).
|
||||
|
||||
dirty_get_registered_users() ->
|
||||
(auth_module()):dirty_get_registered_users().
|
||||
|
||||
get_password(User) ->
|
||||
(auth_module()):get_password(User).
|
||||
get_vh_registered_users(Server) ->
|
||||
(auth_module()):get_vh_registered_users(Server).
|
||||
|
||||
get_password_s(User) ->
|
||||
(auth_module()):get_password_s(User).
|
||||
get_password(User, Server) ->
|
||||
(auth_module()):get_password(User, Server).
|
||||
|
||||
is_user_exists(User) ->
|
||||
(auth_module()):is_user_exists(User).
|
||||
get_password_s(User, Server) ->
|
||||
(auth_module()):get_password_s(User, Server).
|
||||
|
||||
remove_user(User) ->
|
||||
(auth_module()):remove_user(User).
|
||||
is_user_exists(User, Server) ->
|
||||
(auth_module()):is_user_exists(User, Server).
|
||||
|
||||
remove_user(User, Password) ->
|
||||
(auth_module()):remove_user(User, Password).
|
||||
remove_user(User, Server) ->
|
||||
(auth_module()):remove_user(User, Server).
|
||||
|
||||
remove_user(User, Server, Password) ->
|
||||
(auth_module()):remove_user(User, Server, Password).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
|
@ -12,16 +12,17 @@
|
||||
|
||||
%% External exports
|
||||
-export([start/0,
|
||||
set_password/2,
|
||||
check_password/2,
|
||||
check_password/4,
|
||||
try_register/2,
|
||||
set_password/3,
|
||||
check_password/3,
|
||||
check_password/5,
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_password/1,
|
||||
get_password_s/1,
|
||||
is_user_exists/1,
|
||||
remove_user/1,
|
||||
get_vh_registered_users/1,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
is_user_exists/2,
|
||||
remove_user/2,
|
||||
remove_user/3,
|
||||
plain_password_required/0
|
||||
]).
|
||||
|
||||
@ -35,33 +36,36 @@ start() ->
|
||||
plain_password_required() ->
|
||||
true.
|
||||
|
||||
check_password(User, Password) ->
|
||||
check_password(User, _Server, Password) ->
|
||||
extauth:check_password(User, Password).
|
||||
|
||||
check_password(User, Password, _StreamID, _Digest) ->
|
||||
check_password(User, Password).
|
||||
check_password(User, Server, Password, _StreamID, _Digest) ->
|
||||
check_password(User, Server, Password).
|
||||
|
||||
set_password(User, Password) ->
|
||||
set_password(User, _Server, Password) ->
|
||||
extauth:set_password(User, Password).
|
||||
|
||||
try_register(_User, _Password) ->
|
||||
try_register(_User, _Server, _Password) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
dirty_get_registered_users() ->
|
||||
[].
|
||||
|
||||
get_password(_User) ->
|
||||
get_vh_registered_users(_Server) ->
|
||||
[].
|
||||
|
||||
get_password(_User, _Server) ->
|
||||
false.
|
||||
|
||||
get_password_s(_User) ->
|
||||
get_password_s(_User, _Server) ->
|
||||
"".
|
||||
|
||||
is_user_exists(User) ->
|
||||
is_user_exists(User, _Server) ->
|
||||
extauth:is_user_exists(User).
|
||||
|
||||
remove_user(_User) ->
|
||||
remove_user(_User, _Server) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
remove_user(_User, _Password) ->
|
||||
remove_user(_User, _Server, _Password) ->
|
||||
not_allowed.
|
||||
|
||||
|
@ -12,44 +12,52 @@
|
||||
|
||||
%% External exports
|
||||
-export([start/0,
|
||||
set_password/2,
|
||||
check_password/2,
|
||||
check_password/4,
|
||||
try_register/2,
|
||||
set_password/3,
|
||||
check_password/3,
|
||||
check_password/5,
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_password/1,
|
||||
get_password_s/1,
|
||||
is_user_exists/1,
|
||||
remove_user/1,
|
||||
get_vh_registered_users/1,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
is_user_exists/2,
|
||||
remove_user/2,
|
||||
remove_user/3,
|
||||
plain_password_required/0
|
||||
]).
|
||||
|
||||
-record(passwd, {user, password}).
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-record(passwd, {us, password}).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
start() ->
|
||||
mnesia:create_table(passwd,[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, passwd)}]),
|
||||
mnesia:create_table(passwd, [{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, passwd)}]),
|
||||
update_table(),
|
||||
ok.
|
||||
|
||||
plain_password_required() ->
|
||||
false.
|
||||
|
||||
check_password(User, Password) ->
|
||||
check_password(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read({passwd, US}) of
|
||||
[#passwd{password = Password}] ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
check_password(User, Password, StreamID, Digest) ->
|
||||
check_password(User, Server, Password, StreamID, Digest) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read({passwd, US}) of
|
||||
[#passwd{password = Passwd}] ->
|
||||
DigRes = if
|
||||
Digest /= "" ->
|
||||
@ -66,26 +74,34 @@ check_password(User, Password, StreamID, Digest) ->
|
||||
false
|
||||
end.
|
||||
|
||||
set_password(User, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error -> {error, invalid_jid};
|
||||
LUser ->
|
||||
set_password(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
if
|
||||
(LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
true ->
|
||||
F = fun() ->
|
||||
mnesia:write(#passwd{user = LUser,
|
||||
mnesia:write(#passwd{us = US,
|
||||
password = Password})
|
||||
end,
|
||||
mnesia:transaction(F)
|
||||
end.
|
||||
|
||||
|
||||
try_register(User, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error -> {error, invalid_jid};
|
||||
LUser ->
|
||||
try_register(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
if
|
||||
(LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
true ->
|
||||
F = fun() ->
|
||||
case mnesia:read({passwd, LUser}) of
|
||||
case mnesia:read({passwd, US}) of
|
||||
[] ->
|
||||
mnesia:write(#passwd{user = LUser,
|
||||
mnesia:write(#passwd{us = US,
|
||||
password = Password}),
|
||||
ok;
|
||||
[_E] ->
|
||||
@ -98,27 +114,41 @@ try_register(User, Password) ->
|
||||
dirty_get_registered_users() ->
|
||||
mnesia:dirty_all_keys(passwd).
|
||||
|
||||
get_password(User) ->
|
||||
get_vh_registered_users(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
mnesia:dirty_select(
|
||||
passwd,
|
||||
[{#passwd{us = '$1', _ = '_'},
|
||||
[{'==', {element, 2, '$1'}, LServer}],
|
||||
['$1']}]).
|
||||
|
||||
get_password(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read(passwd, LUser) of
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read(passwd, US) of
|
||||
[#passwd{password = Password}] ->
|
||||
Password;
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
get_password_s(User) ->
|
||||
get_password_s(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read(passwd, LUser) of
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read(passwd, US) of
|
||||
[#passwd{password = Password}] ->
|
||||
Password;
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
is_user_exists(User) ->
|
||||
is_user_exists(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read({passwd, US}) of
|
||||
[] ->
|
||||
false;
|
||||
[_] ->
|
||||
@ -127,20 +157,24 @@ is_user_exists(User) ->
|
||||
false
|
||||
end.
|
||||
|
||||
remove_user(User) ->
|
||||
remove_user(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
F = fun() ->
|
||||
mnesia:delete({passwd, LUser})
|
||||
mnesia:delete({passwd, US})
|
||||
end,
|
||||
mnesia:transaction(F),
|
||||
ejabberd_hooks:run(remove_user, [User]).
|
||||
ejabberd_hooks:run(remove_user, [User, Server]).
|
||||
|
||||
remove_user(User, Password) ->
|
||||
remove_user(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
F = fun() ->
|
||||
case mnesia:read({passwd, LUser}) of
|
||||
case mnesia:read({passwd, US}) of
|
||||
[#passwd{password = Password}] ->
|
||||
mnesia:delete({passwd, LUser}),
|
||||
mnesia:delete({passwd, US}),
|
||||
ok;
|
||||
[_] ->
|
||||
not_allowed;
|
||||
@ -150,10 +184,56 @@ remove_user(User, Password) ->
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, ok} ->
|
||||
ejabberd_hooks:run(remove_user, [User]),
|
||||
ejabberd_hooks:run(remove_user, [User, Server]),
|
||||
ok;
|
||||
{atomic, Res} ->
|
||||
Res;
|
||||
_ ->
|
||||
bad_request
|
||||
end.
|
||||
|
||||
|
||||
update_table() ->
|
||||
Fields = record_info(fields, passwd),
|
||||
case mnesia:table_info(passwd, attributes) of
|
||||
Fields ->
|
||||
ok;
|
||||
[user, password] ->
|
||||
?INFO_MSG("Converting passwd table from "
|
||||
"{user, password} format", []),
|
||||
Host = ?MYNAME,
|
||||
{atomic, ok} = mnesia:create_table(
|
||||
ejabberd_auth_internal_tmp_table,
|
||||
[{disc_only_copies, [node()]},
|
||||
{type, bag},
|
||||
{local_content, true},
|
||||
{record_name, passwd},
|
||||
{attributes, record_info(fields, passwd)}]),
|
||||
mnesia:transform_table(passwd, ignore, Fields),
|
||||
F1 = fun() ->
|
||||
mnesia:write_lock_table(ejabberd_auth_internal_tmp_table),
|
||||
mnesia:foldl(
|
||||
fun(#passwd{us = U} = R, _) ->
|
||||
mnesia:dirty_write(
|
||||
ejabberd_auth_internal_tmp_table,
|
||||
R#passwd{us = {U, Host}})
|
||||
end, ok, passwd)
|
||||
end,
|
||||
mnesia:transaction(F1),
|
||||
mnesia:clear_table(passwd),
|
||||
F2 = fun() ->
|
||||
mnesia:write_lock_table(passwd),
|
||||
mnesia:foldl(
|
||||
fun(R, _) ->
|
||||
mnesia:dirty_write(R)
|
||||
end, ok, ejabberd_auth_internal_tmp_table)
|
||||
end,
|
||||
mnesia:transaction(F2),
|
||||
mnesia:delete_table(ejabberd_auth_internal_tmp_table);
|
||||
_ ->
|
||||
?INFO_MSG("Recreating passwd table", []),
|
||||
mnesia:transform_table(passwd, ignore, Fields)
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
@ -12,16 +12,17 @@
|
||||
|
||||
%% External exports
|
||||
-export([start/0,
|
||||
set_password/2,
|
||||
check_password/2,
|
||||
check_password/4,
|
||||
try_register/2,
|
||||
set_password/3,
|
||||
check_password/3,
|
||||
check_password/5,
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_password/1,
|
||||
get_password_s/1,
|
||||
is_user_exists/1,
|
||||
remove_user/1,
|
||||
get_vh_registered_users/1,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
is_user_exists/2,
|
||||
remove_user/2,
|
||||
remove_user/3,
|
||||
plain_password_required/0
|
||||
]).
|
||||
|
||||
@ -41,7 +42,7 @@ start() ->
|
||||
plain_password_required() ->
|
||||
true.
|
||||
|
||||
check_password(User, Password) ->
|
||||
check_password(User, _Server, Password) ->
|
||||
case find_user_dn(User) of
|
||||
false ->
|
||||
false;
|
||||
@ -54,25 +55,28 @@ check_password(User, Password) ->
|
||||
end
|
||||
end.
|
||||
|
||||
check_password(User, Password, _StreamID, _Digest) ->
|
||||
check_password(User, Password).
|
||||
check_password(User, Server, Password, _StreamID, _Digest) ->
|
||||
check_password(User, Server, Password).
|
||||
|
||||
set_password(_User, _Password) ->
|
||||
set_password(_User, _Server, _Password) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
try_register(_User, _Password) ->
|
||||
try_register(_User, _Server, _Password) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
dirty_get_registered_users() ->
|
||||
[].
|
||||
|
||||
get_password(_User) ->
|
||||
get_vh_registered_users(_Server) ->
|
||||
[].
|
||||
|
||||
get_password(_User, _Server) ->
|
||||
false.
|
||||
|
||||
get_password_s(_User) ->
|
||||
get_password_s(_User, _Server) ->
|
||||
"".
|
||||
|
||||
is_user_exists(User) ->
|
||||
is_user_exists(User, _Server) ->
|
||||
case find_user_dn(User) of
|
||||
false ->
|
||||
false;
|
||||
@ -80,10 +84,10 @@ is_user_exists(User) ->
|
||||
true
|
||||
end.
|
||||
|
||||
remove_user(_User) ->
|
||||
remove_user(_User, _Server) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
remove_user(_User, _Password) ->
|
||||
remove_user(_User, _Server, _Password) ->
|
||||
not_allowed.
|
||||
|
||||
|
||||
|
@ -12,16 +12,16 @@
|
||||
|
||||
%% External exports
|
||||
-export([start/0,
|
||||
set_password/2,
|
||||
check_password/2,
|
||||
check_password/4,
|
||||
try_register/2,
|
||||
set_password/3,
|
||||
check_password/3,
|
||||
check_password/5,
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_password/1,
|
||||
get_password_s/1,
|
||||
is_user_exists/1,
|
||||
remove_user/1,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
is_user_exists/2,
|
||||
remove_user/2,
|
||||
remove_user/3,
|
||||
plain_password_required/0
|
||||
]).
|
||||
|
||||
@ -36,7 +36,7 @@ start() ->
|
||||
plain_password_required() ->
|
||||
false.
|
||||
|
||||
check_password(User, Password) ->
|
||||
check_password(User, _Server, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
false;
|
||||
@ -52,7 +52,7 @@ check_password(User, Password) ->
|
||||
end
|
||||
end.
|
||||
|
||||
check_password(User, Password, StreamID, Digest) ->
|
||||
check_password(User, _Server, Password, StreamID, Digest) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
false;
|
||||
@ -78,7 +78,7 @@ check_password(User, Password, StreamID, Digest) ->
|
||||
end
|
||||
end.
|
||||
|
||||
set_password(User, Password) ->
|
||||
set_password(User, _Server, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
{error, invalid_jid};
|
||||
@ -93,7 +93,7 @@ set_password(User, Password) ->
|
||||
end.
|
||||
|
||||
|
||||
try_register(User, Password) ->
|
||||
try_register(User, _Server, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
{error, invalid_jid};
|
||||
@ -118,7 +118,10 @@ dirty_get_registered_users() ->
|
||||
[]
|
||||
end.
|
||||
|
||||
get_password(User) ->
|
||||
dirty_get_registered_users(Server) ->
|
||||
dirty_get_registered_users().
|
||||
|
||||
get_password(User, _Server) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
false;
|
||||
@ -134,7 +137,7 @@ get_password(User) ->
|
||||
end
|
||||
end.
|
||||
|
||||
get_password_s(User) ->
|
||||
get_password_s(User, _Server) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
"";
|
||||
@ -150,7 +153,7 @@ get_password_s(User) ->
|
||||
end
|
||||
end.
|
||||
|
||||
is_user_exists(User) ->
|
||||
is_user_exists(User, _Server) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
false;
|
||||
@ -166,7 +169,7 @@ is_user_exists(User) ->
|
||||
end
|
||||
end.
|
||||
|
||||
remove_user(User) ->
|
||||
remove_user(User, _Server) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
error;
|
||||
@ -177,7 +180,7 @@ remove_user(User) ->
|
||||
ejabberd_hooks:run(remove_user, [User])
|
||||
end.
|
||||
|
||||
remove_user(User, Password) ->
|
||||
remove_user(User, _Server, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
error;
|
||||
|
@ -83,6 +83,8 @@
|
||||
xml:element_to_string(?SERR_INVALID_NAMESPACE)).
|
||||
-define(INVALID_XML_ERR,
|
||||
xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
|
||||
-define(HOST_UNKNOWN_ERR,
|
||||
xml:element_to_string(?SERR_HOST_UNKNOWN)).
|
||||
-define(POLICY_VIOLATION_ERR(Lang, Text),
|
||||
xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))).
|
||||
|
||||
@ -164,89 +166,114 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
end,
|
||||
case xml:get_attr_s("xmlns:stream", Attrs) of
|
||||
?NS_STREAM ->
|
||||
Lang = xml:get_attr_s("xml:lang", Attrs),
|
||||
case xml:get_attr_s("version", Attrs) of
|
||||
"1.0" ->
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.streamid,
|
||||
?MYNAME,
|
||||
" version='1.0'",
|
||||
DefaultLang]),
|
||||
send_text(StateData, Header),
|
||||
case StateData#state.authentificated of
|
||||
false ->
|
||||
SASLState =
|
||||
cyrsasl:server_new("jabber", ?MYNAME, "", []),
|
||||
Mechs = lists:map(
|
||||
fun(S) ->
|
||||
{xmlelement, "mechanism", [],
|
||||
[{xmlcdata, S}]}
|
||||
end, cyrsasl:listmech()),
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
TLSRequired = StateData#state.tls_required,
|
||||
SockMod = StateData#state.sockmod,
|
||||
TLSFeature =
|
||||
case (TLS == true) andalso
|
||||
(TLSEnabled == false) andalso
|
||||
(SockMod == gen_tcp) of
|
||||
true ->
|
||||
case TLSRequired of
|
||||
Server = jlib:nameprep(xml:get_attr_s("to", Attrs)),
|
||||
case lists:member(Server, ?MYHOSTS) of
|
||||
true ->
|
||||
Lang = xml:get_attr_s("xml:lang", Attrs),
|
||||
case xml:get_attr_s("version", Attrs) of
|
||||
"1.0" ->
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.streamid,
|
||||
Server,
|
||||
" version='1.0'",
|
||||
DefaultLang]),
|
||||
send_text(StateData, Header),
|
||||
case StateData#state.authentificated of
|
||||
false ->
|
||||
SASLState =
|
||||
cyrsasl:server_new(
|
||||
"jabber", Server, "", [],
|
||||
fun(U) ->
|
||||
ejabberd_auth:get_password(
|
||||
U, Server)
|
||||
end,
|
||||
fun(U, P) ->
|
||||
ejabberd_auth:check_password(
|
||||
U, Server, P)
|
||||
end),
|
||||
Mechs = lists:map(
|
||||
fun(S) ->
|
||||
{xmlelement, "mechanism", [],
|
||||
[{xmlcdata, S}]}
|
||||
end, cyrsasl:listmech()),
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
TLSRequired = StateData#state.tls_required,
|
||||
SockMod = StateData#state.sockmod,
|
||||
TLSFeature =
|
||||
case (TLS == true) andalso
|
||||
(TLSEnabled == false) andalso
|
||||
(SockMod == gen_tcp) of
|
||||
true ->
|
||||
[{xmlelement, "starttls",
|
||||
[{"xmlns", ?NS_TLS}],
|
||||
[{xmlelement, "required",
|
||||
[], []}]}];
|
||||
_ ->
|
||||
[{xmlelement, "starttls",
|
||||
[{"xmlns", ?NS_TLS}], []}]
|
||||
end;
|
||||
false ->
|
||||
[]
|
||||
end,
|
||||
send_element(StateData,
|
||||
{xmlelement, "stream:features", [],
|
||||
TLSFeature ++
|
||||
[{xmlelement, "mechanisms",
|
||||
[{"xmlns", ?NS_SASL}],
|
||||
Mechs},
|
||||
{xmlelement, "register",
|
||||
[{"xmlns", ?NS_FEATURE_IQREGISTER}],
|
||||
[]}]}),
|
||||
{next_state, wait_for_feature_request,
|
||||
StateData#state{sasl_state = SASLState,
|
||||
lang = Lang}};
|
||||
_ ->
|
||||
case StateData#state.resource of
|
||||
"" ->
|
||||
send_element(
|
||||
StateData,
|
||||
{xmlelement, "stream:features", [],
|
||||
[{xmlelement, "bind",
|
||||
[{"xmlns", ?NS_BIND}], []},
|
||||
{xmlelement, "session",
|
||||
[{"xmlns", ?NS_SESSION}], []}]}),
|
||||
{next_state, wait_for_bind,
|
||||
StateData#state{lang = Lang}};
|
||||
case TLSRequired of
|
||||
true ->
|
||||
[{xmlelement, "starttls",
|
||||
[{"xmlns", ?NS_TLS}],
|
||||
[{xmlelement, "required",
|
||||
[], []}]}];
|
||||
_ ->
|
||||
[{xmlelement, "starttls",
|
||||
[{"xmlns", ?NS_TLS}], []}]
|
||||
end;
|
||||
false ->
|
||||
[]
|
||||
end,
|
||||
send_element(StateData,
|
||||
{xmlelement, "stream:features", [],
|
||||
TLSFeature ++
|
||||
[{xmlelement, "mechanisms",
|
||||
[{"xmlns", ?NS_SASL}],
|
||||
Mechs},
|
||||
{xmlelement, "register",
|
||||
[{"xmlns", ?NS_FEATURE_IQREGISTER}],
|
||||
[]}]}),
|
||||
{next_state, wait_for_feature_request,
|
||||
StateData#state{server = Server,
|
||||
sasl_state = SASLState,
|
||||
lang = Lang}};
|
||||
_ ->
|
||||
send_element(
|
||||
StateData,
|
||||
{xmlelement, "stream:features", [], []}),
|
||||
{next_state, wait_for_session,
|
||||
StateData#state{lang = Lang}}
|
||||
end
|
||||
case StateData#state.resource of
|
||||
"" ->
|
||||
send_element(
|
||||
StateData,
|
||||
{xmlelement, "stream:features", [],
|
||||
[{xmlelement, "bind",
|
||||
[{"xmlns", ?NS_BIND}], []},
|
||||
{xmlelement, "session",
|
||||
[{"xmlns", ?NS_SESSION}], []}]}),
|
||||
{next_state, wait_for_bind,
|
||||
StateData#state{server = Server,
|
||||
lang = Lang}};
|
||||
_ ->
|
||||
send_element(
|
||||
StateData,
|
||||
{xmlelement, "stream:features", [], []}),
|
||||
{next_state, wait_for_session,
|
||||
StateData#state{server = Server,
|
||||
lang = Lang}}
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
Header = io_lib:format(
|
||||
?STREAM_HEADER,
|
||||
[StateData#state.streamid, Server, "", DefaultLang]),
|
||||
send_text(StateData, Header),
|
||||
{next_state, wait_for_auth,
|
||||
StateData#state{server = Server,
|
||||
lang = Lang}}
|
||||
end;
|
||||
_ ->
|
||||
Header = io_lib:format(
|
||||
?STREAM_HEADER,
|
||||
[StateData#state.streamid, ?MYNAME, "", DefaultLang]),
|
||||
send_text(StateData, Header),
|
||||
{next_state, wait_for_auth, StateData#state{lang = Lang}}
|
||||
send_text(StateData,
|
||||
Header ++ ?HOST_UNKNOWN_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData}
|
||||
end;
|
||||
_ ->
|
||||
Header = io_lib:format(
|
||||
?STREAM_HEADER,
|
||||
[StateData#state.streamid, ?MYNAME, "", ""]),
|
||||
[StateData#state.streamid, ?MYNAME, "", DefaultLang]),
|
||||
send_text(StateData,
|
||||
Header ++ ?INVALID_NS_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData}
|
||||
@ -297,19 +324,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
send_element(StateData, Err),
|
||||
{next_state, wait_for_auth, StateData};
|
||||
{auth, _ID, set, {U, P, D, R}} ->
|
||||
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
||||
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||
case (JID /= error) andalso
|
||||
(acl:match_rule(StateData#state.access, JID) == allow) of
|
||||
true ->
|
||||
case ejabberd_auth:check_password(
|
||||
U, P, StateData#state.streamid, D) of
|
||||
U, StateData#state.server, P,
|
||||
StateData#state.streamid, D) of
|
||||
true ->
|
||||
?INFO_MSG(
|
||||
"(~w) Accepted legacy authentication for ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID)]),
|
||||
ejabberd_sm:open_session(U, R),
|
||||
ejabberd_sm:open_session(
|
||||
U, StateData#state.server, R),
|
||||
Res1 = jlib:make_result_iq_reply(El),
|
||||
Res = setelement(4, Res1, []),
|
||||
send_element(StateData, Res),
|
||||
@ -317,13 +345,14 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
{Fs, Ts} = ejabberd_hooks:run_fold(
|
||||
roster_get_subscription_lists,
|
||||
{[], []},
|
||||
[U]),
|
||||
[U, StateData#state.server]),
|
||||
LJID = jlib:jid_tolower(
|
||||
jlib:jid_remove_resource(JID)),
|
||||
Fs1 = [LJID | Fs],
|
||||
Ts1 = [LJID | Ts],
|
||||
PrivList =
|
||||
case catch mod_privacy:get_user_list(U) of
|
||||
case catch mod_privacy:get_user_list(
|
||||
U, StateData#state.server) of
|
||||
{'EXIT', _} -> none;
|
||||
PL -> PL
|
||||
end,
|
||||
@ -368,8 +397,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
case jlib:iq_query_info(El) of
|
||||
#iq{xmlns = ?NS_REGISTER} = IQ ->
|
||||
ResIQ = mod_register:process_iq(
|
||||
{"", "", ""}, {"", ?MYNAME, ""}, IQ),
|
||||
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
|
||||
{"", "", ""},
|
||||
jlib:make_jid("", StateData#state.server, ""),
|
||||
IQ),
|
||||
Res1 = jlib:replace_from_to({"", StateData#state.server, ""},
|
||||
{"", "", ""},
|
||||
jlib:iq_to_xml(ResIQ)),
|
||||
Res = jlib:remove_attr("to", Res1),
|
||||
@ -414,8 +445,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s",
|
||||
[StateData#state.socket, U]),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{streamid = new_id(),
|
||||
authentificated = true,
|
||||
StateData#state{authentificated = true,
|
||||
user = U
|
||||
}};
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
@ -445,7 +475,6 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{sockmod = tls,
|
||||
socket = TLSSocket,
|
||||
streamid = new_id(),
|
||||
tls_enabled = true
|
||||
}};
|
||||
_ ->
|
||||
@ -461,8 +490,10 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
|
||||
case jlib:iq_query_info(El) of
|
||||
#iq{xmlns = ?NS_REGISTER} = IQ ->
|
||||
ResIQ = mod_register:process_iq(
|
||||
{"", "", ""}, {"", ?MYNAME, ""}, IQ),
|
||||
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
|
||||
{"", "", ""},
|
||||
jlib:make_jid("", StateData#state.server, ""),
|
||||
IQ),
|
||||
Res1 = jlib:replace_from_to({"", StateData#state.server, ""},
|
||||
{"", "", ""},
|
||||
jlib:iq_to_xml(ResIQ)),
|
||||
Res = jlib:remove_attr("to", Res1),
|
||||
@ -502,8 +533,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s",
|
||||
[StateData#state.socket, U]),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{streamid = new_id(),
|
||||
authentificated = true,
|
||||
StateData#state{authentificated = true,
|
||||
user = U
|
||||
}};
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
@ -525,8 +555,10 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
||||
case jlib:iq_query_info(El) of
|
||||
#iq{xmlns = ?NS_REGISTER} = IQ ->
|
||||
ResIQ = mod_register:process_iq(
|
||||
{"", "", ""}, {"", ?MYNAME, ""}, IQ),
|
||||
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
|
||||
{"", "", ""},
|
||||
jlib:make_jid("", StateData#state.server, ""),
|
||||
IQ),
|
||||
Res1 = jlib:replace_from_to({"", StateData#state.server, ""},
|
||||
{"", "", ""},
|
||||
jlib:iq_to_xml(ResIQ)),
|
||||
Res = jlib:remove_attr("to", Res1),
|
||||
@ -601,26 +633,27 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
#iq{type = set, xmlns = ?NS_SESSION} ->
|
||||
U = StateData#state.user,
|
||||
R = StateData#state.resource,
|
||||
io:format("SASLAUTH: ~p~n", [{U, R}]),
|
||||
JID = StateData#state.jid,
|
||||
case acl:match_rule(StateData#state.access, JID) of
|
||||
allow ->
|
||||
?INFO_MSG("(~w) Opened session for ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID)]),
|
||||
ejabberd_sm:open_session(U, R),
|
||||
ejabberd_sm:open_session(
|
||||
U, StateData#state.server, R),
|
||||
Res = jlib:make_result_iq_reply(El),
|
||||
send_element(StateData, Res),
|
||||
change_shaper(StateData, JID),
|
||||
{Fs, Ts} = ejabberd_hooks:run_fold(
|
||||
roster_get_subscription_lists,
|
||||
{[], []},
|
||||
[U]),
|
||||
[U, StateData#state.server]),
|
||||
LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
|
||||
Fs1 = [LJID | Fs],
|
||||
Ts1 = [LJID | Ts],
|
||||
PrivList =
|
||||
case catch mod_privacy:get_user_list(U) of
|
||||
case catch mod_privacy:get_user_list(
|
||||
U, StateData#state.server) of
|
||||
{'EXIT', _} -> none;
|
||||
PL -> PL
|
||||
end,
|
||||
@ -835,6 +868,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
%-ifdef(PRIVACY_SUPPORT).
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, To, Packet},
|
||||
in) of
|
||||
@ -884,6 +918,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
#iq{} ->
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, To, Packet},
|
||||
in) of
|
||||
@ -905,6 +940,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
"message" ->
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, To, Packet},
|
||||
in) of
|
||||
@ -955,6 +991,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
[{xmlelement, "status", [],
|
||||
[{xmlcdata, "Replaced by new connection"}]}]},
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
"Replaced by new connection"),
|
||||
presence_broadcast(
|
||||
@ -966,6 +1003,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(StateData#state.jid)]),
|
||||
ejabberd_sm:close_session(StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource),
|
||||
|
||||
Tmp = ?SETS:new(),
|
||||
@ -980,6 +1018,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
Packet = {xmlelement, "presence",
|
||||
[{"type", "unavailable"}], []},
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
""),
|
||||
presence_broadcast(
|
||||
@ -1070,6 +1109,7 @@ process_presence_probe(From, To, StateData) ->
|
||||
%-ifdef(PRIVACY_SUPPORT).
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{To, From, Packet},
|
||||
out) of
|
||||
@ -1102,6 +1142,7 @@ presence_update(From, Packet, StateData) ->
|
||||
xml:get_tag_cdata(StatusTag)
|
||||
end,
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
Status),
|
||||
presence_broadcast(StateData, From, StateData#state.pres_a, Packet),
|
||||
@ -1173,6 +1214,7 @@ presence_track(From, To, Packet, StateData) ->
|
||||
{xmlelement, _Name, Attrs, _Els} = Packet,
|
||||
LTo = jlib:jid_tolower(To),
|
||||
User = StateData#state.user,
|
||||
Server = StateData#state.server,
|
||||
case xml:get_attr_s("type", Attrs) of
|
||||
"unavailable" ->
|
||||
ejabberd_router:route(From, To, Packet),
|
||||
@ -1189,22 +1231,22 @@ presence_track(From, To, Packet, StateData) ->
|
||||
"subscribe" ->
|
||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
[User, To, subscribe]),
|
||||
[User, Server, To, subscribe]),
|
||||
StateData;
|
||||
"subscribed" ->
|
||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
[User, To, subscribed]),
|
||||
[User, Server, To, subscribed]),
|
||||
StateData;
|
||||
"unsubscribe" ->
|
||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
[User, To, unsubscribe]),
|
||||
[User, Server, To, unsubscribe]),
|
||||
StateData;
|
||||
"unsubscribed" ->
|
||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
[User, To, unsubscribed]),
|
||||
[User, Server, To, unsubscribed]),
|
||||
StateData;
|
||||
"error" ->
|
||||
ejabberd_router:route(From, To, Packet),
|
||||
@ -1216,6 +1258,7 @@ presence_track(From, To, Packet, StateData) ->
|
||||
%-ifdef(PRIVACY_SUPPORT).
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, To, Packet},
|
||||
out) of
|
||||
@ -1239,6 +1282,7 @@ presence_broadcast(StateData, From, JIDSet, Packet) ->
|
||||
%-ifdef(PRIVACY_SUPPORT).
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, FJID, Packet},
|
||||
out) of
|
||||
@ -1261,6 +1305,7 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
|
||||
%-ifdef(PRIVACY_SUPPORT).
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, FJID, Packet},
|
||||
out) of
|
||||
@ -1300,6 +1345,7 @@ presence_broadcast_first(From, StateData, Packet) ->
|
||||
%-ifdef(PRIVACY_SUPPORT).
|
||||
case catch mod_privacy:check_packet(
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.privacy_list,
|
||||
{From, FJID, Packet},
|
||||
out) of
|
||||
@ -1395,6 +1441,7 @@ update_priority(El, StateData) ->
|
||||
end
|
||||
end,
|
||||
ejabberd_sm:set_presence(StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
Pri).
|
||||
|
||||
@ -1439,15 +1486,17 @@ process_privacy_iq(From, To,
|
||||
|
||||
|
||||
resend_offline_messages(#state{user = User,
|
||||
server = Server,
|
||||
privacy_list = PrivList} = StateData) ->
|
||||
case ejabberd_hooks:run_fold(resend_offline_messages_hook, [],
|
||||
[User]) of
|
||||
[User, Server]) of
|
||||
Rs when list(Rs) ->
|
||||
lists:foreach(
|
||||
fun({route,
|
||||
From, To, {xmlelement, Name, Attrs, Els} = Packet}) ->
|
||||
Pass = case catch mod_privacy:check_packet(
|
||||
< |