]> granicus.if.org Git - ejabberd/commitdiff
Fix IDNA support in ACME requests
authorEvgeny Khramtsov <ekhramtsov@process-one.net>
Sun, 22 Sep 2019 09:44:31 +0000 (12:44 +0300)
committerEvgeny Khramtsov <ekhramtsov@process-one.net>
Sun, 22 Sep 2019 09:44:31 +0000 (12:44 +0300)
rebar.config
src/ejabberd_acme.erl

index fcf26fc3ba4f79badc965f498d57ade473806901..e9b40a27fe81de38bebaadbdb47146210f483860 100644 (file)
@@ -25,7 +25,7 @@
         {stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.17"}}},
         {fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.37"}}},
        {idna, ".*", {git, "https://github.com/benoitc/erlang-idna", {tag, "6.0.0"}}},
-        {xmpp, ".*", {git, "https://github.com/processone/xmpp", "984b3c3"}},
+        {xmpp, ".*", {git, "https://github.com/processone/xmpp", "3e892bc"}},
         {fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.20"}}},
        {yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.0"}}},
         {jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "0.14.8"}}},
@@ -34,7 +34,7 @@
         {jose, ".*", {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.8.4"}}},
         {eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.12"}}},
         {mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.4"}}},
-       {acme, ".*", {git, "https://github.com/processone/acme.git", "b312547"}},
+       {acme, ".*", {git, "https://github.com/processone/acme.git", "be6405c"}},
         {if_var_true, stun, {stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.29"}}}},
         {if_var_true, sip, {esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.30"}}}},
         {if_var_true, mysql, {p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql",
index 3e6c2d2398064eb01659a6193ab6be133572b525..14b91c1e1f61b067b832acba908223f8bcfef6e2 100644 (file)
@@ -194,14 +194,14 @@ unregister_challenge(Ref) ->
 -spec issue_request(state(), [binary(),...]) -> {issue_result(), state()}.
 issue_request(State, Domains) ->
     case check_idna(Domains) of
-       ok ->
+       {ok, AsciiDomains} ->
            case read_account_key() of
                {ok, AccKey} ->
                    Config = ejabberd_option:acme(),
                    DirURL = maps:get(ca_url, Config, default_directory_url()),
                    Contact = maps:get(contact, Config, []),
                    CertType = maps:get(cert_type, Config, rsa),
-                   issue_request(State, DirURL, Domains, AccKey, CertType, Contact);
+                   issue_request(State, DirURL, Domains, AsciiDomains, AccKey, CertType, Contact);
                {error, Reason} = Err ->
                    ?ERROR_MSG("Failed to request certificate for ~s: ~s",
                               [misc:format_hosts_list(Domains),
@@ -215,12 +215,12 @@ issue_request(State, Domains) ->
            {Err, State}
     end.
 
--spec issue_request(state(), binary(), [binary(),...], priv_key(),
+-spec issue_request(state(), binary(), [binary(),...], [string(), ...], priv_key(),
                    cert_type(), [binary()]) -> {issue_result(), state()}.
-issue_request(State, DirURL, Domains, AccKey, CertType, Contact) ->
+issue_request(State, DirURL, Domains, AsciiDomains, AccKey, CertType, Contact) ->
     Ref = make_ref(),
     ChallengeFun = fun(Auth) -> register_challenge(Auth, Ref) end,
-    Ret = case acme:issue(DirURL, Domains, AccKey,
+    Ret = case acme:issue(DirURL, AsciiDomains, AccKey,
                          [{cert_type, CertType},
                           {contact, Contact},
                           {debug_fun, debug_fun()},
@@ -630,15 +630,16 @@ have_acme_listener() ->
              false
       end, ejabberd_option:listen()).
 
--spec check_idna([binary()]) -> ok | {error, {idna_failed, binary()}}.
-check_idna([Domain|Domains]) ->
-    try idna:to_ascii(binary_to_list(Domain)) of
-       _ -> check_idna(Domains)
-    catch _:_ ->
-           {error, {idna_failed, Domain}}
-    end;
-check_idna([]) ->
-    ok.
+-spec check_idna([binary()]) -> {ok, [string()]} | {error, {idna_failed, binary()}}.
+check_idna(Domains) ->
+    lists:foldl(
+      fun(D, {ok, Ds}) ->
+             try {ok, [idna:utf8_to_ascii(D)|Ds]}
+             catch _:_ -> {error, {idna_failed, D}}
+             end;
+        (_, Err) ->
+             Err
+      end, {ok, []}, Domains).
 
 -spec format_error(term()) -> string().
 format_error({file, Reason}) ->