]> granicus.if.org Git - ejabberd/commitdiff
Synchronizing master changes
authorMickael Remond <mremond@process-one.net>
Tue, 12 Apr 2016 08:34:24 +0000 (10:34 +0200)
committerMickael Remond <mremond@process-one.net>
Tue, 12 Apr 2016 08:34:24 +0000 (10:34 +0200)
14 files changed:
rebar.config
sql/mssql.sql
sql/mysql.sql
src/cyrsasl_anonymous.erl
src/ejabberd_auth_anonymous.erl
src/ejabberd_c2s.erl
src/ejabberd_ctl.erl
src/ejabberd_s2s_in.erl
src/ejabberd_s2s_out.erl
src/ejabberd_sm.erl
src/mod_admin_extra.erl
src/mod_register.erl
test/ejabberd_cyrsasl_test.exs [new file with mode: 0644]
test/mod_admin_extra_test.exs

index 5b6676a130827db6487691db11abfb15c07c998c..d006dc64c414b0f5f4ef16663fa0b2374daf013f 100644 (file)
@@ -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"}}},
index 675542b681c047739dac322cbfd5e70fc4199fdd..45378d246804bc8b87c8eec457f1b9cce0f7c327 100644 (file)
@@ -362,8 +362,8 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW
 CREATE TABLE [dbo].[users] (\r
         [username] [varchar] (250) NOT NULL,\r
         [password] [text] NOT NULL,\r
-        [serverkey] [text] NOT NULL,\r
-        [salt] [text] NOT NULL,\r
+        [serverkey] [text] NOT NULL DEFAULT '',\r
+        [salt] [text] NOT NULL DEFAULT '',\r
         [iterationcount] [smallint] NOT NULL DEFAULT 0,\r
         [created_at] [datetime] NOT NULL DEFAULT GETDATE(),\r
  CONSTRAINT [users_PRIMARY] PRIMARY KEY CLUSTERED \r
index f08b3a4b925f0acc5a22f2cda06c503b4e17c7ca..b7a86d0e643bbf4730732f5e2e7df6d05453761c 100644 (file)
 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 (
index 2b2a9f63cf7e8985fb4873b8879f9f29dcaad912..802e1cd7b81c161499dd5548afb0082bb0612286 100644 (file)
@@ -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.
index 9c4b719c31080ce13c796512f7eb775c2134895b..5a5b395bf8d3eb35683db9ff1103cda70c10b287 100644 (file)
@@ -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
index 3736f7d0735e1745c5b9edb767ed7d008e17d6fa..948e2027ba24a4c8536e71677f8cafa5ad5a04c1 100644 (file)
@@ -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);
index edec5a07e5a9a45cf312b6515e12b4ed2dc5d0a7..7cacc3bbb1c8719c35947fea897a0071a5427c63 100644 (file)
@@ -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);
index c8d3cd04e97d0fd5f1d836de1b76429d6eda28ed..d8d0a400a03508e49709469539ce33e4e9b458be 100644 (file)
@@ -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,
index 594fbb2c795a03adf0069f5e66dd84aad983cdd1..a30f2f438d0f3c7ece331cbc342a2bf888c0038c 100644 (file)
@@ -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,
index 4f7cfeeaaa18bb9fbf3852f4effacdbc522c10f8..7ab0a5f782352cb4d55487b67721887f3e2be03d 100644 (file)
@@ -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;
index cb794787658c9345d0b06e3f2a9789bf256b36ee..b12a80007a32043f9301f80e0703d0ffb70ce1fe 100644 (file)
@@ -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),
index fee2a2284b35f4a5c238bdf6f09c3b53ed2bc388..c1a7cab81f78c80077524880a64156f5f4cd61ca 100644 (file)
@@ -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 (file)
index 0000000..0dc64ee
--- /dev/null
@@ -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
index d104ed0585c183f6d6eef0db2e08d8a23ae0eb7f..2029cf686ad60c20fb3c337a069c78e3c9b99a69 100644 (file)
@@ -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,