From cd2e2b1a880f93b7198bbc17cb1d9be2c23048e8 Mon Sep 17 00:00:00 2001 From: Mickael Remond Date: Tue, 12 Apr 2016 10:34:24 +0200 Subject: [PATCH] Synchronizing master changes --- rebar.config | 2 +- sql/mssql.sql | 4 +- sql/mysql.sql | 8 +- src/cyrsasl_anonymous.erl | 5 +- src/ejabberd_auth_anonymous.erl | 2 +- src/ejabberd_c2s.erl | 33 ++----- src/ejabberd_ctl.erl | 6 +- src/ejabberd_s2s_in.erl | 2 +- src/ejabberd_s2s_out.erl | 2 +- src/ejabberd_sm.erl | 6 +- src/mod_admin_extra.erl | 7 +- src/mod_register.erl | 2 +- test/ejabberd_cyrsasl_test.exs | 153 ++++++++++++++++++++++++++++++++ test/mod_admin_extra_test.exs | 12 +-- 14 files changed, 194 insertions(+), 50 deletions(-) create mode 100644 test/ejabberd_cyrsasl_test.exs diff --git a/rebar.config b/rebar.config index 5b6676a13..d006dc64c 100644 --- a/rebar.config +++ b/rebar.config @@ -8,7 +8,7 @@ %%%------------------------------------------------------------------- {deps, [{lager, ".*", {git, "https://github.com/basho/lager", {tag, "3.0.2"}}}, - {p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.3"}}}, + {p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.4"}}}, {cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.2"}}}, {fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.1"}}}, {stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.3"}}}, diff --git a/sql/mssql.sql b/sql/mssql.sql index 675542b68..45378d246 100644 --- a/sql/mssql.sql +++ b/sql/mssql.sql @@ -362,8 +362,8 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW CREATE TABLE [dbo].[users] ( [username] [varchar] (250) NOT NULL, [password] [text] NOT NULL, - [serverkey] [text] NOT NULL, - [salt] [text] NOT NULL, + [serverkey] [text] NOT NULL DEFAULT '', + [salt] [text] NOT NULL DEFAULT '', [iterationcount] [smallint] NOT NULL DEFAULT 0, [created_at] [datetime] NOT NULL DEFAULT GETDATE(), CONSTRAINT [users_PRIMARY] PRIMARY KEY CLUSTERED diff --git a/sql/mysql.sql b/sql/mysql.sql index f08b3a4b9..b7a86d0e6 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -19,15 +19,15 @@ CREATE TABLE users ( username varchar(191) PRIMARY KEY, password text NOT NULL, - serverkey text NOT NULL DEFAULT '', - salt text NOT NULL DEFAULT '', + serverkey varchar(64) NOT NULL DEFAULT '', + salt varchar(64) NOT NULL DEFAULT '', iterationcount integer NOT NULL DEFAULT 0, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Add support for SCRAM auth to a database created before ejabberd 16.03: --- ALTER TABLE users ADD COLUMN serverkey text NOT NULL DEFAULT ''; --- ALTER TABLE users ADD COLUMN salt text NOT NULL DEFAULT ''; +-- ALTER TABLE users ADD COLUMN serverkey varchar(64) NOT NULL DEFAULT ''; +-- ALTER TABLE users ADD COLUMN salt varchar(64) NOT NULL DEFAULT ''; -- ALTER TABLE users ADD COLUMN iterationcount integer NOT NULL DEFAULT 0; CREATE TABLE last ( diff --git a/src/cyrsasl_anonymous.erl b/src/cyrsasl_anonymous.erl index 2b2a9f63c..802e1cd7b 100644 --- a/src/cyrsasl_anonymous.erl +++ b/src/cyrsasl_anonymous.erl @@ -45,9 +45,8 @@ mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) -> mech_step(#state{server = Server} = S, ClientIn) -> User = iolist_to_binary([randoms:get_string(), - randoms:get_string(), - randoms:get_string()]), + jlib:integer_to_binary(p1_time_compat:unique_integer([positive]))]), case ejabberd_auth:is_user_exists(User, Server) of true -> mech_step(S, ClientIn); - false -> {ok, [{username, User}, {auth_module, ejabberd_auth_anonymous}]} + false -> {ok, [{username, User}, {authzid, User}, {auth_module, ejabberd_auth_anonymous}]} end. diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl index 9c4b719c3..5a5b395bf 100644 --- a/src/ejabberd_auth_anonymous.erl +++ b/src/ejabberd_auth_anonymous.erl @@ -56,7 +56,7 @@ %% Create the anonymous table if at least one virtual host has anonymous features enabled %% Register to login / logout events -record(anonymous, {us = {<<"">>, <<"">>} :: {binary(), binary()}, - sid = {p1_time_compat:timestamp(), self()} :: ejabberd_sm:sid()}). + sid = ejabberd_sm:make_sid() :: ejabberd_sm:sid()}). start(Host) -> %% TODO: Check cluster mode diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 3736f7d07..948e2027b 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -327,7 +327,7 @@ init([{SockMod, Socket}, Opts]) -> xml_socket = XMLSocket, zlib = Zlib, tls = TLS, tls_required = StartTLSRequired, tls_enabled = TLSEnabled, tls_options = TLSOpts, - sid = {p1_time_compat:timestamp(), self()}, streamid = new_id(), + sid = ejabberd_sm:make_sid(), streamid = new_id(), access = Access, shaper = Shaper, ip = IP, mgmt_state = StreamMgmtState, mgmt_max_queue = MaxAckQueue, @@ -522,7 +522,6 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, <<"Use of STARTTLS required">>)), - send_trailer(StateData), {stop, normal, StateData}; true -> fsm_next_state(wait_for_auth, @@ -537,34 +536,28 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> [jlib:ip_to_list(IP), LogReason]), send_header(StateData, Server, <<"">>, DefaultLang), send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, ReasonT)), - send_trailer(StateData), {stop, normal, StateData}; _ -> send_header(StateData, ?MYNAME, <<"">>, DefaultLang), send_element(StateData, ?HOST_UNKNOWN_ERR), - send_trailer(StateData), {stop, normal, StateData} end; _ -> send_header(StateData, ?MYNAME, <<"">>, DefaultLang), send_element(StateData, ?INVALID_NS_ERR), - send_trailer(StateData), {stop, normal, StateData} end; wait_for_stream(timeout, StateData) -> {stop, normal, StateData}; wait_for_stream({xmlstreamelement, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_stream({xmlstreamend, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_stream({xmlstreamerror, _}, StateData) -> send_header(StateData, ?MYNAME, <<"1.0">>, <<"">>), send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}; @@ -724,10 +717,9 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> wait_for_auth(timeout, StateData) -> {stop, normal, StateData}; wait_for_auth({xmlstreamend, _Name}, StateData) -> - send_trailer(StateData), {stop, normal, StateData}; + {stop, normal, StateData}; wait_for_auth({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_auth(closed, StateData) -> {stop, normal, StateData}; @@ -843,7 +835,6 @@ wait_for_feature_request({xmlstreamelement, El}, send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, <<"Use of STARTTLS required">>)), - send_trailer(StateData), {stop, normal, StateData}; true -> process_unauthenticated_stanza(StateData, El), @@ -854,11 +845,10 @@ wait_for_feature_request(timeout, StateData) -> {stop, normal, StateData}; wait_for_feature_request({xmlstreamend, _Name}, StateData) -> - send_trailer(StateData), {stop, normal, StateData}; + {stop, normal, StateData}; wait_for_feature_request({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_feature_request(closed, StateData) -> {stop, normal, StateData}; @@ -963,11 +953,10 @@ wait_for_sasl_response(timeout, StateData) -> {stop, normal, StateData}; wait_for_sasl_response({xmlstreamend, _Name}, StateData) -> - send_trailer(StateData), {stop, normal, StateData}; + {stop, normal, StateData}; wait_for_sasl_response({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_sasl_response(closed, StateData) -> {stop, normal, StateData}; @@ -1092,10 +1081,9 @@ wait_for_bind({xmlstreamelement, El}, StateData) -> wait_for_bind(timeout, StateData) -> {stop, normal, StateData}; wait_for_bind({xmlstreamend, _Name}, StateData) -> - send_trailer(StateData), {stop, normal, StateData}; + {stop, normal, StateData}; wait_for_bind({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; wait_for_bind(closed, StateData) -> {stop, normal, StateData}; @@ -1168,7 +1156,6 @@ session_established({xmlstreamelement, El}, case check_from(El, FromJID) of 'invalid-from' -> send_element(StateData, ?INVALID_FROM), - send_trailer(StateData), {stop, normal, StateData}; _NewEl -> session_established2(El, StateData) @@ -1181,17 +1168,15 @@ session_established(timeout, StateData) -> [?MODULE, Options, session_established, StateData]), fsm_next_state(session_established, StateData); session_established({xmlstreamend, _Name}, StateData) -> - send_trailer(StateData), {stop, normal, StateData}; + {stop, normal, StateData}; session_established({xmlstreamerror, <<"XML stanza is too big">> = E}, StateData) -> send_element(StateData, ?POLICY_VIOLATION_ERR((StateData#state.lang), E)), - send_trailer(StateData), {stop, normal, StateData}; session_established({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), - send_trailer(StateData), {stop, normal, StateData}; session_established(closed, #state{mgmt_state = active} = StateData) -> catch (StateData#state.sockmod):close(StateData#state.socket), @@ -1346,7 +1331,6 @@ handle_info(kick, StateName, StateData) -> handle_info({kick, kicked_by_admin, Xmlelement}, StateName, StateData); handle_info({kick, Reason, Xmlelement}, _StateName, StateData) -> send_element(StateData, Xmlelement), - send_trailer(StateData), {stop, normal, StateData#state{authenticated = Reason}}; handle_info({route, _From, _To, {broadcast, Data}}, @@ -1359,7 +1343,6 @@ handle_info({route, _From, _To, {broadcast, Data}}, {exit, Reason} -> Lang = StateData#state.lang, send_element(StateData, ?SERRT_CONFLICT(Lang, Reason)), - catch send_trailer(StateData), {stop, normal, StateData}; {privacy_list, PrivList, PrivListName} -> case ejabberd_hooks:run_fold(privacy_updated_list, @@ -1673,11 +1656,9 @@ handle_info(system_shutdown, StateName, StateData) -> wait_for_stream -> send_header(StateData, ?MYNAME, <<"1.0">>, <<"en">>), send_element(StateData, ?SERR_SYSTEM_SHUTDOWN), - send_trailer(StateData), ok; _ -> send_element(StateData, ?SERR_SYSTEM_SHUTDOWN), - send_trailer(StateData), ok end, {stop, normal, StateData}; @@ -1809,6 +1790,7 @@ terminate(_Reason, StateName, StateData) -> ok end end, + catch send_trailer(StateData), (StateData#state.sockmod):close(StateData#state.socket), ok. @@ -2431,7 +2413,6 @@ fsm_next_state(session_established, #state{mgmt_max_queue = exceeded} = Err = ?SERRT_POLICY_VIOLATION(StateData#state.lang, <<"Too many unacked stanzas">>), send_element(StateData, Err), - send_trailer(StateData), {stop, normal, StateData#state{mgmt_resend = false}}; fsm_next_state(session_established, #state{mgmt_state = pending} = StateData) -> fsm_next_state(wait_for_resume, StateData); diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index edec5a07e..7cacc3bbb 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -48,7 +48,7 @@ -behaviour(ejabberd_config). -author('alexey@process-one.net'). --export([start/0, init/0, process/1, +-export([start/0, init/0, process/1, process2/2, register_commands/3, unregister_commands/3, opt_type/1]). @@ -231,6 +231,10 @@ process(Args, Version) -> Code. %% @spec (Args::[string()], AccessCommands) -> {String::string(), Code::integer()} +process2(Args, AccessCommands) -> + process2(Args, AccessCommands, ?DEFAULT_VERSION). + +%% @spec (Args::[string()], AccessCommands, Version) -> {String::string(), Code::integer()} process2(["--auth", User, Server, Pass | Args], AccessCommands, Version) -> process2(Args, AccessCommands, {list_to_binary(User), list_to_binary(Server), list_to_binary(Pass), true}, Version); diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index c8d3cd04e..d8d0a400a 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -325,7 +325,7 @@ wait_for_feature_request({xmlstreamelement, El}, {s2s_tls_compression, StateData#state.server}, fun(true) -> true; (false) -> false - end, true) of + end, false) of true -> lists:delete(compression_none, TLSOpts1); false -> [compression_none | TLSOpts1] end, diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 594fbb2c7..a30f2f438 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -192,7 +192,7 @@ init([From, Server, Type]) -> {s2s_tls_compression, From}, fun(true) -> true; (false) -> false - end, true) of + end, false) of false -> [compression_none | TLSOpts4]; true -> TLSOpts4 end, diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 4f7cfeeaa..7ab0a5f78 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -66,7 +66,8 @@ get_max_user_sessions/2, get_all_pids/0, is_existing_resource/3, - get_commands_spec/0 + get_commands_spec/0, + make_sid/0 ]). -export([init/1, handle_call/3, handle_cast/2, @@ -806,6 +807,9 @@ kick_user(User, Server) -> end, Resources), length(Resources). +make_sid() -> + {p1_time_compat:unique_timestamp(), self()}. + opt_type(sm_db_type) -> fun (mnesia) -> mnesia; (internal) -> mnesia; diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index cb7947876..b12a80007 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -31,7 +31,7 @@ -include("logger.hrl"). -export([start/2, stop/1, compile/1, get_cookie/0, - remove_node/1, set_password/3, + remove_node/1, set_password/3, check_password/3, check_password_hash/4, delete_old_users/1, delete_old_users_vhost/2, ban_account/3, num_active_users/2, num_resources/2, resource_num/3, @@ -162,7 +162,7 @@ get_commands_spec() -> result_desc = "Status code: 0 on success, 1 otherwise"}, #ejabberd_commands{name = check_password, tags = [accounts], desc = "Check if a password is correct", - module = ejabberd_auth, function = check_password, + module = ?MODULE, function = check_password, args = [{user, binary}, {host, binary}, {password, binary}], args_example = [<<"peter">>, <<"myserver.com">>, <<"secret">>], args_desc = ["User name to check", "Server to check", "Password to check"], @@ -593,6 +593,9 @@ set_password(User, Host, Password) -> Fun = fun () -> ejabberd_auth:set_password(User, Host, Password) end, user_action(User, Host, Fun, ok). +check_password(User, Host, Password) -> + ejabberd_auth:check_password(User, <<>>, Host, Password). + %% Copied some code from ejabberd_commands.erl check_password_hash(User, Host, PasswordHash, HashMethod) -> AccountPass = ejabberd_auth:get_password_s(User, Host), diff --git a/src/mod_register.erl b/src/mod_register.erl index fee2a2284..c1a7cab81 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -375,7 +375,7 @@ try_set_password(User, Server, Password, IQ, SubEl, Txt = <<"Empty password">>, IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}; {error, not_allowed} -> - Txt = <<"Chaning password is not allowed">>, + Txt = <<"Changing password is not allowed">>, IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}; {error, invalid_jid} -> IQ#iq{type = error, diff --git a/test/ejabberd_cyrsasl_test.exs b/test/ejabberd_cyrsasl_test.exs new file mode 100644 index 000000000..0dc64ee44 --- /dev/null +++ b/test/ejabberd_cyrsasl_test.exs @@ -0,0 +1,153 @@ +# ---------------------------------------------------------------------- +# +# ejabberd, Copyright (C) 2002-2016 ProcessOne +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# ---------------------------------------------------------------------- + +defmodule EjabberdCyrsaslTest do + @author "pawel@process-one.net" + + use ExUnit.Case, async: true + + setup_all do + :p1_sha.load_nif() + :mnesia.start + :ok = start_module(:stringprep) + :ok = start_module(:jid) + :ok = :ejabberd_config.start(["domain1"], []) + :ok = :cyrsasl.start + cyrstate = :cyrsasl.server_new("domain1", "domain1", "domain1", :ok, &get_password/1, + &check_password/3, &check_password_digest/5) + {:ok, cyrstate: cyrstate} + end + + test "Plain text (correct user and pass)", context do + step1 = :cyrsasl.server_start(context[:cyrstate], "PLAIN", <<0,"user1",0,"pass">>) + assert {:ok, _} = step1 + {:ok, kv} = step1 + assert kv[:authzid] == "user1", "got correct user" + end + + test "Plain text (correct user wrong pass)", context do + step1 = :cyrsasl.server_start(context[:cyrstate], "PLAIN", <<0,"user1",0,"badpass">>) + assert step1 == {:error, "not-authorized", "user1"}, "got error response" + end + + test "Plain text (wrong user wrong pass)", context do + step1 = :cyrsasl.server_start(context[:cyrstate], "PLAIN", <<0,"nouser1",0,"badpass">>) + assert step1 == {:error, "not-authorized", "nouser1"}, "got error response" + end + + test "Anonymous", context do + setup_anonymous_mocks() + step1 = :cyrsasl.server_start(context[:cyrstate], "ANONYMOUS", "domain1") + assert {:ok, _} = step1 + end + + test "Digest-MD5 (correct user and pass)", context do + assert {:continue, init_str, state1} = :cyrsasl.server_start(context[:cyrstate], "DIGEST-MD5", "") + assert [_, nonce] = Regex.run(~r/nonce="(.*?)"/, init_str) + user = "user1" + domain = "domain1" + digest_uri = "xmpp/#{domain}" + pass = "pass" + cnonce = "abcd" + nc = "00000001" + response_hash = calc_digest_sha(user, domain, pass, nc, nonce, cnonce) + response = "username=\"#{user}\",realm=\"#{domain}\",nonce=\"#{nonce}\",cnonce=\"#{cnonce}\"," <> + "nc=\"#{nc}\",qop=auth,digest-uri=\"#{digest_uri}\",response=\"#{response_hash}\"," <> + "charset=utf-8,algorithm=md5-sess" + assert {:continue, calc_str, state3} = :cyrsasl.server_step(state1, response) + assert {:ok, list} = :cyrsasl.server_step(state3, "") + end + + defp calc_digest_sha(user, domain, pass, nc, nonce, cnonce) do + digest_uri = "xmpp/#{domain}" + a0 = "#{user}:#{domain}:#{pass}" + a1 = "#{str_md5(a0)}:#{nonce}:#{cnonce}" + a2 = "AUTHENTICATE:#{digest_uri}" + hex_md5("#{hex_md5(a1)}:#{nonce}:#{nc}:#{cnonce}:auth:#{hex_md5(a2)}") + end + + defp str_md5(str) do + :erlang.md5(str) + end + + defp hex_md5(str) do + :p1_sha.to_hexlist(:erlang.md5(str)) + end + + defp setup_anonymous_mocks() do + :meck.unload + mock(:ejabberd_auth_anonymous, :is_sasl_anonymous_enabled, + fn (host) -> + true + end) + mock(:ejabberd_auth, :is_user_exists, + fn (user, domain) -> + domain == "domain1" and get_password(user) != false + end) + end + + defp start_module(module) do + case apply(module, :start, []) do + :ok -> :ok + {:error, {:already_started, _}} -> :ok + other -> other + end + end + + defp get_password(user) do + if user == "user1" or user == "user2" do + {"pass", :internal} + else + :false + end + end + + defp check_password(user, authzid, pass) do + case get_password(authzid) do + {^pass, mod} -> + {true, mod} + _ -> + false + end + end + + defp check_password_digest(user, authzid, pass, digest, digest_gen) do + case get_password(authzid) do + {spass, mod} -> + v = digest_gen.(spass) + if v == digest do + {true, mod} + else + false + end + _ -> + false + end + end + + defp mock(module, function, fun) do + try do + :meck.new(module, [:non_strict]) + catch + :error, {:already_started, _pid} -> :ok + end + :meck.expect(module, function, fun) + end +end diff --git a/test/mod_admin_extra_test.exs b/test/mod_admin_extra_test.exs index d104ed058..2029cf686 100644 --- a/test/mod_admin_extra_test.exs +++ b/test/mod_admin_extra_test.exs @@ -73,13 +73,13 @@ defmodule EjabberdModAdminExtraTest do EjabberdAuthMock.create_user @user, @domain, @password assert :ejabberd_commands.execute_command(:check_password, - [@user, <<"">>, @domain, @password]) + [@user, @domain, @password]) refute :ejabberd_commands.execute_command(:check_password, - [@user, <<"">>, @domain, "bad_password"]) + [@user, @domain, "bad_password"]) refute :ejabberd_commands.execute_command(:check_password, - [@user, <<"">>, "bad_domain", @password]) + [@user, "bad_domain", @password]) refute :ejabberd_commands.execute_command(:check_password, - ["bad_user", <<"">>, @domain, @password]) + ["bad_user", @domain, @password]) assert :meck.validate :ejabberd_auth @@ -117,9 +117,9 @@ defmodule EjabberdModAdminExtraTest do assert :ejabberd_commands.execute_command(:change_password, [@user, @domain, "new_password"]) refute :ejabberd_commands.execute_command(:check_password, - [@user, <<"">>, @domain, @password]) + [@user, @domain, @password]) assert :ejabberd_commands.execute_command(:check_password, - [@user, <<"">>, @domain, "new_password"]) + [@user, @domain, "new_password"]) assert {:not_found, 'unknown_user'} == catch_throw :ejabberd_commands.execute_command(:change_password, ["bad_user", @domain,