]> granicus.if.org Git - ejabberd/commitdiff
Add tests for anonymous and digest-md5 auth
authorPaweł Chmielowski <pchmielowski@process-one.net>
Thu, 7 Apr 2016 14:47:01 +0000 (16:47 +0200)
committerPaweł Chmielowski <pchmielowski@process-one.net>
Thu, 7 Apr 2016 14:47:01 +0000 (16:47 +0200)
test/ejabberd_cyrsasl_test.exs

index b86884cc369daaa13d5d15457565e8975adfc4b8..0dc64ee447800d53f0dab4362b08187b0c014ff5 100644 (file)
@@ -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