From 0935f493eefe1871f2380384b239b1907274f046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Thu, 7 Apr 2016 16:47:01 +0200 Subject: [PATCH] Add tests for anonymous and digest-md5 auth --- test/ejabberd_cyrsasl_test.exs | 68 ++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/test/ejabberd_cyrsasl_test.exs b/test/ejabberd_cyrsasl_test.exs index b86884cc3..0dc64ee44 100644 --- a/test/ejabberd_cyrsasl_test.exs +++ b/test/ejabberd_cyrsasl_test.exs @@ -24,12 +24,13 @@ defmodule EjabberdCyrsaslTest do 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", "domain2"], []) + :ok = :ejabberd_config.start(["domain1"], []) :ok = :cyrsasl.start - cyrstate = :cyrsasl.server_new("test", "test", "test", :ok, &get_password/1, + cyrstate = :cyrsasl.server_new("domain1", "domain1", "domain1", :ok, &get_password/1, &check_password/3, &check_password_digest/5) {:ok, cyrstate: cyrstate} end @@ -51,6 +52,57 @@ defmodule EjabberdCyrsaslTest do 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 @@ -79,7 +131,8 @@ defmodule EjabberdCyrsaslTest do defp check_password_digest(user, authzid, pass, digest, digest_gen) do case get_password(authzid) do {spass, mod} -> - if digest_gen.(spass) == pass do + v = digest_gen.(spass) + if v == digest do {true, mod} else false @@ -88,4 +141,13 @@ defmodule EjabberdCyrsaslTest do 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