Don't call to mod_register when it's not loaded

Fixes #2828
This commit is contained in:
Evgeny Khramtsov 2019-04-23 21:05:21 +03:00
parent edba1aebb5
commit cbf3fec2c8
2 changed files with 104 additions and 69 deletions

View File

@ -478,16 +478,23 @@ update_module(ModuleNameString) ->
%%%
register(User, Host, Password) ->
{ok, IPRaw} = inet_parse:address(binary_to_list(<<"::ffff:127.0.0.1">>)),
case mod_register:try_register(User, Host, Password, IPRaw, <<"en">>) of
Ret = case gen_mod:is_loaded(Host, mod_register) of
true ->
{ok, IPRaw} = inet_parse:address("::ffff:127.0.0.1"),
mod_register:try_register(User, Host, Password, IPRaw);
false ->
ejabberd_auth:try_register(User, Host, Password)
end,
case Ret of
ok ->
{ok, io_lib:format("User ~s@~s successfully registered", [User, Host])};
{error, exists} ->
Msg = io_lib:format("User ~s@~s already registered", [User, Host]),
{error, conflict, 10090, Msg};
{error, Reason} ->
String = io_lib:format("Can't register user ~s@~s at node ~p: ~p",
[User, Host, node(), Reason]),
String = io_lib:format("Can't register user ~s@~s at node ~p: ~s",
[User, Host, node(),
mod_register:format_error(Reason)]),
{error, cannot_register, 10001, String}
end.

View File

@ -34,13 +34,15 @@
-behaviour(gen_mod).
-export([start/2, stop/1, reload/3, stream_feature_register/2,
c2s_unauthenticated_packet/2, try_register/5,
c2s_unauthenticated_packet/2, try_register/4,
process_iq/1, send_registration_notifications/3,
transform_options/1, transform_module_options/1,
mod_opt_type/1, mod_options/1, opt_type/1, depends/2]).
mod_opt_type/1, mod_options/1, opt_type/1, depends/2,
format_error/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include("translate.hrl").
start(Host, _Opts) ->
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
@ -306,75 +308,92 @@ try_set_password(User, Server, Password, #iq{lang = Lang, meta = M} = IQ) ->
xmpp:make_error(IQ, xmpp:err_not_acceptable(ErrText, Lang))
end.
try_register(User, Server, Password, SourceRaw, Lang) ->
try_register(User, Server, Password, SourceRaw) ->
case jid:is_nodename(User) of
false -> {error, xmpp:err_bad_request(<<"Malformed username">>, Lang)};
_ ->
JID = jid:make(User, Server),
Access = gen_mod:get_module_opt(Server, ?MODULE, access),
IPAccess = get_ip_access(Server),
case {acl:match_rule(Server, Access, JID),
check_ip_access(SourceRaw, IPAccess)}
of
{deny, _} -> {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
{_, deny} -> {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
{allow, allow} ->
Source = may_remove_resource(SourceRaw),
case check_timeout(Source) of
true ->
case is_strong_password(Server, Password) of
false ->
{error, invalid_jid};
true ->
case check_access(User, Server, SourceRaw) of
deny ->
{error, eaccess};
allow ->
Source = may_remove_resource(SourceRaw),
case check_timeout(Source) of
true ->
case ejabberd_auth:try_register(User, Server,
Password)
of
ok ->
?INFO_MSG("The account ~s was registered "
"from IP address ~s",
[jid:encode({User, Server, <<"">>}),
ejabberd_config:may_hide_data(
ip_to_string(Source))]),
send_welcome_message(JID),
send_registration_notifications(
?MODULE, JID, Source),
ok;
Error ->
remove_timeout(Source),
case Error of
{error, exists} ->
Txt = <<"User already exists">>,
{error, xmpp:err_conflict(Txt, Lang)};
{error, invalid_jid} ->
{error, xmpp:err_jid_malformed()};
{error, invalid_password} ->
Txt = <<"Incorrect password">>,
{error, xmpp:err_not_allowed(Txt, Lang)};
{error, not_allowed} ->
{error, xmpp:err_not_allowed()};
{error, _} ->
?ERROR_MSG("failed to register user "
"~s@~s: ~p",
[User, Server, Error]),
{error, xmpp:err_internal_server_error()}
end
case is_strong_password(Server, Password) of
true ->
case ejabberd_auth:try_register(
User, Server, Password) of
ok ->
ok;
{error, _} = Err ->
remove_timeout(Source),
Err
end;
false ->
remove_timeout(Source),
{error, weak_password};
_ ->
remove_timeout(Source),
{error, invalid_password}
end;
error_preparing_password ->
remove_timeout(Source),
ErrText = <<"The password contains unacceptable characters">>,
{error, xmpp:err_not_acceptable(ErrText, Lang)};
false ->
remove_timeout(Source),
ErrText = <<"The password is too weak">>,
{error, xmpp:err_not_acceptable(ErrText, Lang)}
end;
false ->
ErrText =
<<"Users are not allowed to register accounts "
"so quickly">>,
{error, xmpp:err_resource_constraint(ErrText, Lang)}
end
end
{error, wait}
end
end
end.
try_register(User, Server, Password, SourceRaw, Lang) ->
case try_register(User, Server, Password, SourceRaw) of
ok ->
JID = jid:make(User, Server),
Source = may_remove_resource(SourceRaw),
?INFO_MSG("The account ~s was registered from IP address ~s",
[jid:encode({User, Server, <<"">>}),
ejabberd_config:may_hide_data(ip_to_string(Source))]),
send_welcome_message(JID),
send_registration_notifications(?MODULE, JID, Source);
{error, invalid_jid = Why} ->
{error, xmpp:err_jid_malformed(format_error(Why), Lang)};
{error, eaccess = Why} ->
{error, xmpp:err_forbidden(format_error(Why), Lang)};
{error, wait = Why} ->
{error, xmpp:err_resource_constraint(format_error(Why), Lang)};
{error, weak_password = Why} ->
{error, xmpp:err_not_acceptable(format_error(Why), Lang)};
{error, invalid_password = Why} ->
{error, xmpp:err_not_acceptable(format_error(Why), Lang)};
{error, not_allowed = Why} ->
{error, xmpp:err_not_allowed(format_error(Why), Lang)};
{error, exists = Why} ->
{error, xmpp:err_conflict(format_error(Why), Lang)};
{error, db_failure = Why} ->
{error, xmpp:err_internal_server_error(format_error(Why), Lang)};
{error, Why} ->
?ERROR_MSG("Failed to register user ~s@~s: ~s",
[User, Server, format_error(Why)]),
{error, xmpp:err_internal_server_error(format_error(Why), Lang)}
end.
format_error(invalid_jid) ->
?T("Malformed username");
format_error(eaccess) ->
?T("Access denied by service policy");
format_error(wait) ->
?T("Users are not allowed to register accounts so quickly");
format_error(weak_password) ->
?T("The password is too weak");
format_error(invalid_password) ->
?T("The password contains unacceptable characters");
format_error(not_allowed) ->
?T("Not allowed");
format_error(exists) ->
?T("User already exists");
format_error(db_failure) ->
?T("Database failure");
format_error(Unexpected) ->
list_to_binary(io_lib:format(?T("Unexpected error condition: ~p"), [Unexpected])).
send_welcome_message(JID) ->
Host = JID#jid.lserver,
case gen_mod:get_module_opt(Host, ?MODULE, welcome_message) of
@ -597,6 +616,15 @@ check_ip_access(undefined, _IPAccess) ->
check_ip_access(IPAddress, IPAccess) ->
acl:match_rule(global, IPAccess, IPAddress).
check_access(User, Server, Source) ->
JID = jid:make(User, Server),
Access = gen_mod:get_module_opt(Server, ?MODULE, access),
IPAccess = get_ip_access(Server),
case acl:match_rule(Server, Access, JID) of
allow -> check_ip_access(Source, IPAccess);
deny -> deny
end.
mod_opt_type(access) -> fun acl:access_rules_validator/1;
mod_opt_type(access_from) -> fun acl:access_rules_validator/1;
mod_opt_type(access_remove) -> fun acl:access_rules_validator/1;