Packages
ejabberd
19.9.0
26.4.0
26.3.0
26.2.0
26.1.0
25.10.0
25.8.0
25.7.0
25.4.0
25.3.0
24.12.0
24.10.0
24.7.0
24.6.0
24.2.6
23.10.0
23.4.0
23.1.0
22.10.0
22.5.0
21.12.0
21.7.0
21.4.0
21.1.0
20.12.0
20.7.0
20.4.0
20.3.0
20.2.0
20.1.0
19.9.1
19.9.0
19.8.0
19.5.0
19.2.0
18.12.1
18.12.0
18.6.0
18.4.0
18.3.0
18.1.0
17.11.0
17.9.0
17.6.0
17.3.0
17.1.0
16.12.0-beta1
16.9.0
16.8.0
16.6.2
16.6.1
16.6.0
16.4.1
16.4.0
16.3.0
16.2.0
16.1.0-beta1
Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
Current section
56 Versions
Jump to
Current section
56 Versions
Compare versions
143
files changed
+2899
additions
-2938
deletions
| @@ -111,7 +111,8 @@ To compile ejabberd you need: | |
| 111 111 | - OpenSSL ≥ 1.0.0. |
| 112 112 | - Zlib ≥ 1.2.3, for Stream Compression support (XEP-0138). Optional. |
| 113 113 | - PAM library. Optional. For Pluggable Authentication Modules (PAM). |
| 114 | - - ImageMagick's Convert program. Optional. For CAPTCHA challenges. |
| 114 | + - ImageMagick's Convert program and Ghostscript fonts. Optional. For CAPTCHA |
| 115 | + challenges. |
| 115 116 | |
| 116 117 | If your system splits packages in libraries and development headers, you must |
| 117 118 | install the development packages also. |
| @@ -60,25 +60,25 @@ | |
| 60 60 | <<"src/gen_pubsub_node.erl">>,<<"src/mod_http_fileserver_opt.erl">>, |
| 61 61 | <<"src/mod_bosh_opt.erl">>,<<"src/mod_proxy65_stream.erl">>, |
| 62 62 | <<"src/mod_fail2ban.erl">>,<<"src/misc.erl">>, |
| 63 | - <<"src/mod_announce_opt.erl">>,<<"src/ejabberd_redis.erl">>, |
| 64 | - <<"src/win32_dns.erl">>,<<"src/gen_pubsub_nodetree.erl">>, |
| 65 | - <<"src/mod_pubsub_opt.erl">>,<<"src/nodetree_virtual.erl">>, |
| 63 | + <<"src/mod_announce_opt.erl">>,<<"src/mod_jidprep.erl">>, |
| 64 | + <<"src/ejabberd_redis.erl">>,<<"src/win32_dns.erl">>, |
| 65 | + <<"src/gen_pubsub_nodetree.erl">>,<<"src/mod_pubsub_opt.erl">>, |
| 66 | + <<"src/mod_jidprep_opt.erl">>,<<"src/nodetree_virtual.erl">>, |
| 66 67 | <<"src/mod_time.erl">>,<<"src/mod_vcard_mnesia.erl">>, |
| 67 68 | <<"src/ejabberd_regexp.erl">>,<<"src/mod_vcard_opt.erl">>, |
| 68 | - <<"src/mod_vcard_xupdate.erl">>,<<"src/acme_challenge.erl">>, |
| 69 | - <<"src/ejabberd_auth.erl">>,<<"src/eldap_filter_yecc.yrl">>, |
| 70 | - <<"src/mod_mix_mnesia.erl">>,<<"src/ejabberd_commands_doc.erl">>, |
| 71 | - <<"src/mod_muc_sql.erl">>,<<"src/extauth_sup.erl">>, |
| 72 | - <<"src/ejabberd_stun.erl">>,<<"src/mod_fail2ban_opt.erl">>, |
| 73 | - <<"src/mod_mix_sql.erl">>,<<"src/mod_mam_opt.erl">>, |
| 74 | - <<"src/mod_delegation.erl">>,<<"src/ejabberd_tmp_sup.erl">>, |
| 75 | - <<"src/mod_roster_mnesia.erl">>,<<"src/ejabberd_sup.erl">>, |
| 76 | - <<"src/ejabberd_auth_pam.erl">>,<<"src/ejabberd_local.erl">>, |
| 77 | - <<"src/mod_client_state.erl">>,<<"src/mod_mqtt_opt.erl">>, |
| 78 | - <<"src/mod_disco_opt.erl">>,<<"src/eldap_filter.erl">>, |
| 79 | - <<"src/ejd2sql.erl">>,<<"src/eldap_filter_yecc.erl">>, |
| 80 | - <<"src/mod_shared_roster.erl">>,<<"src/mod_block_strangers.erl">>, |
| 81 | - <<"src/ejabberd_rdbms.erl">>,<<"src/ELDAPv3.erl">>, |
| 69 | + <<"src/mod_vcard_xupdate.erl">>,<<"src/ejabberd_auth.erl">>, |
| 70 | + <<"src/eldap_filter_yecc.yrl">>,<<"src/mod_mix_mnesia.erl">>, |
| 71 | + <<"src/ejabberd_commands_doc.erl">>,<<"src/mod_muc_sql.erl">>, |
| 72 | + <<"src/extauth_sup.erl">>,<<"src/ejabberd_stun.erl">>, |
| 73 | + <<"src/mod_fail2ban_opt.erl">>,<<"src/mod_mix_sql.erl">>, |
| 74 | + <<"src/mod_mam_opt.erl">>,<<"src/mod_delegation.erl">>, |
| 75 | + <<"src/ejabberd_tmp_sup.erl">>,<<"src/mod_roster_mnesia.erl">>, |
| 76 | + <<"src/ejabberd_sup.erl">>,<<"src/ejabberd_auth_pam.erl">>, |
| 77 | + <<"src/ejabberd_local.erl">>,<<"src/mod_client_state.erl">>, |
| 78 | + <<"src/mod_mqtt_opt.erl">>,<<"src/mod_disco_opt.erl">>, |
| 79 | + <<"src/eldap_filter.erl">>,<<"src/ejd2sql.erl">>, |
| 80 | + <<"src/eldap_filter_yecc.erl">>,<<"src/mod_shared_roster.erl">>, |
| 81 | + <<"src/mod_block_strangers.erl">>,<<"src/ELDAPv3.erl">>, |
| 82 82 | <<"src/mod_carboncopy.erl">>,<<"src/ejabberd_auth_ldap.erl">>, |
| 83 83 | <<"src/xml_compress.erl">>,<<"src/mod_blocking.erl">>, |
| 84 84 | <<"src/mod_push_keepalive.erl">>,<<"src/ejabberd_app.erl">>, |
| @@ -95,11 +95,11 @@ | |
| 95 95 | <<"src/data.json">>,<<"src/mod_register.erl">>, |
| 96 96 | <<"src/ejabberd_c2s_config.erl">>,<<"src/mod_mqtt_mnesia.erl">>, |
| 97 97 | <<"src/mod_private_opt.erl">>,<<"src/mod_register_opt.erl">>, |
| 98 | - <<"src/ejabberd_acme_comm.erl">>,<<"src/mod_shared_roster_ldap_opt.erl">>, |
| 99 | - <<"src/ejabberd_backend_sup.erl">>,<<"src/mod_muc_admin.erl">>, |
| 100 | - <<"src/ejabberd_sm_mnesia.erl">>,<<"src/jd2ejd.erl">>, |
| 101 | - <<"src/mod_client_state_opt.erl">>,<<"src/mod_caps_mnesia.erl">>, |
| 102 | - <<"src/mod_bosh_mnesia.erl">>,<<"src/eldap_pool.erl">>,<<"src/str.erl">>, |
| 98 | + <<"src/mod_shared_roster_ldap_opt.erl">>,<<"src/ejabberd_backend_sup.erl">>, |
| 99 | + <<"src/mod_muc_admin.erl">>,<<"src/ejabberd_sm_mnesia.erl">>, |
| 100 | + <<"src/jd2ejd.erl">>,<<"src/mod_client_state_opt.erl">>, |
| 101 | + <<"src/mod_caps_mnesia.erl">>,<<"src/mod_bosh_mnesia.erl">>, |
| 102 | + <<"src/eldap_pool.erl">>,<<"src/str.erl">>, |
| 103 103 | <<"src/mod_admin_update_sql.erl">>,<<"src/ejabberd_http_ws.erl">>, |
| 104 104 | <<"src/ejabberd_cluster.erl">>,<<"src/ejabberd_oauth.erl">>, |
| 105 105 | <<"src/mod_roster_opt.erl">>,<<"src/ejabberd_oauth_mnesia.erl">>, |
| @@ -107,7 +107,8 @@ | |
| 107 107 | <<"src/mod_privacy_sql.erl">>,<<"src/subscribe.json">>, |
| 108 108 | <<"src/ejabberd_sm_redis.erl">>,<<"src/pubsub_migrate.erl">>, |
| 109 109 | <<"src/mod_muc_room.erl">>,<<"src/ejabberd_router_multicast.erl">>, |
| 110 | - <<"src/ext_mod.erl">>,<<"src/mod_caps_sql.erl">>,<<"src/mod_mqtt.erl">>, |
| 110 | + <<"src/ejabberd_oauth.erl~">>,<<"src/ext_mod.erl">>, |
| 111 | + <<"src/mod_caps_sql.erl">>,<<"src/mod_mqtt.erl">>, |
| 111 112 | <<"src/ejabberd_web_admin.erl">>,<<"src/mod_adhoc.erl">>, |
| 112 113 | <<"src/ejabberd_sql_sup.erl">>,<<"src/mod_shared_roster_opt.erl">>, |
| 113 114 | <<"src/ejabberd_logger.erl">>,<<"src/node_pep_sql.erl">>, |
| @@ -189,18 +190,18 @@ | |
| 189 190 | <<"include/bosh.hrl">>,<<"include/mod_proxy65.hrl">>, |
| 190 191 | <<"include/ejabberd_router.hrl">>,<<"include/ejabberd_sql.hrl">>, |
| 191 192 | <<"include/mod_offline.hrl">>,<<"include/ejabberd_commands.hrl">>, |
| 192 | - <<"include/mod_roster.hrl">>,<<"include/ejabberd_acme.hrl">>, |
| 193 | - <<"include/eldap.hrl">>,<<"include/ejabberd_http.hrl">>, |
| 194 | - <<"include/ejabberd_stacktrace.hrl">>,<<"include/mod_vcard.hrl">>, |
| 195 | - <<"include/ejabberd_ctl.hrl">>,<<"include/mod_mam.hrl">>, |
| 196 | - <<"include/mod_last.hrl">>,<<"include/mod_push.hrl">>, |
| 197 | - <<"include/ejabberd_config.hrl">>,<<"include/ejabberd_sm.hrl">>, |
| 198 | - <<"include/translate.hrl">>,<<"include/mod_private.hrl">>, |
| 199 | - <<"include/mod_announce.hrl">>,<<"include/mod_muc.hrl">>, |
| 200 | - <<"include/mod_privacy.hrl">>,<<"include/logger.hrl">>, |
| 201 | - <<"include/adhoc.hrl">>,<<"include/ejabberd_oauth.hrl">>, |
| 202 | - <<"include/mod_caps.hrl">>,<<"include/mod_muc_room.hrl">>, |
| 203 | - <<"include/ejabberd_web_admin.hrl">>,<<"README.md">>,<<"COPYING">>]}. |
| 193 | + <<"include/mod_roster.hrl">>,<<"include/eldap.hrl">>, |
| 194 | + <<"include/ejabberd_http.hrl">>,<<"include/ejabberd_stacktrace.hrl">>, |
| 195 | + <<"include/mod_vcard.hrl">>,<<"include/ejabberd_ctl.hrl">>, |
| 196 | + <<"include/mod_mam.hrl">>,<<"include/mod_last.hrl">>, |
| 197 | + <<"include/mod_push.hrl">>,<<"include/ejabberd_config.hrl">>, |
| 198 | + <<"include/ejabberd_sm.hrl">>,<<"include/translate.hrl">>, |
| 199 | + <<"include/mod_private.hrl">>,<<"include/mod_announce.hrl">>, |
| 200 | + <<"include/mod_muc.hrl">>,<<"include/mod_privacy.hrl">>, |
| 201 | + <<"include/logger.hrl">>,<<"include/adhoc.hrl">>, |
| 202 | + <<"include/ejabberd_oauth.hrl">>,<<"include/mod_caps.hrl">>, |
| 203 | + <<"include/mod_muc_room.hrl">>,<<"include/ejabberd_web_admin.hrl">>, |
| 204 | + <<"README.md">>,<<"COPYING">>]}. |
| 204 205 | {<<"licenses">>,[<<"GPLv2">>]}. |
| 205 206 | {<<"links">>, |
| 206 207 | [{<<"Documentation">>,<<"http://docs.ejabberd.im">>}, |
| @@ -278,7 +279,7 @@ | |
| 278 279 | {<<"name">>,<<"jiffy">>}, |
| 279 280 | {<<"optional">>,false}, |
| 280 281 | {<<"repository">>,<<"hexpm">>}, |
| 281 | - {<<"requirement">>,<<"~> 0.14.7">>}], |
| 282 | + {<<"requirement">>,<<"~> 1.0">>}], |
| 282 283 | [{<<"app">>,<<"p1_oauth2">>}, |
| 283 284 | {<<"name">>,<<"p1_oauth2">>}, |
| 284 285 | {<<"optional">>,false}, |
| @@ -314,13 +315,13 @@ | |
| 314 315 | {<<"optional">>,false}, |
| 315 316 | {<<"repository">>,<<"hexpm">>}, |
| 316 317 | {<<"requirement">>,<<"~> 1.8">>}], |
| 317 | - [{<<"app">>,<<"sqlite3">>}, |
| 318 | - {<<"name">>,<<"sqlite3">>}, |
| 318 | + [{<<"app">>,<<"idna">>}, |
| 319 | + {<<"name">>,<<"idna">>}, |
| 319 320 | {<<"optional">>,false}, |
| 320 321 | {<<"repository">>,<<"hexpm">>}, |
| 321 | - {<<"requirement">>,<<"~> 1.1">>}], |
| 322 | - [{<<"app">>,<<"eredis">>}, |
| 323 | - {<<"name">>,<<"eredis">>}, |
| 322 | + {<<"requirement">>,<<"~> 6.0">>}], |
| 323 | + [{<<"app">>,<<"p1_acme">>}, |
| 324 | + {<<"name">>,<<"p1_acme">>}, |
| 324 325 | {<<"optional">>,false}, |
| 325 326 | {<<"repository">>,<<"hexpm">>}, |
| 326 327 | {<<"requirement">>,<<"~> 1.0">>}], |
| @@ -328,15 +329,5 @@ | |
| 328 329 | {<<"name">>,<<"ezlib">>}, |
| 329 330 | {<<"optional">>,false}, |
| 330 331 | {<<"repository">>,<<"hexpm">>}, |
| 331 | - {<<"requirement">>,<<"~> 1.0">>}], |
| 332 | - [{<<"app">>,<<"epam">>}, |
| 333 | - {<<"name">>,<<"epam">>}, |
| 334 | - {<<"optional">>,false}, |
| 335 | - {<<"repository">>,<<"hexpm">>}, |
| 336 | - {<<"requirement">>,<<"~> 1.0">>}], |
| 337 | - [{<<"app">>,<<"luerl">>}, |
| 338 | - {<<"name">>,<<"luerl">>}, |
| 339 | - {<<"optional">>,false}, |
| 340 | - {<<"repository">>,<<"hexpm">>}, |
| 341 | - {<<"requirement">>,<<"~> 0.3.1">>}]]}. |
| 342 | - {<<"version">>,<<"19.8.0">>}. |
| 332 | + {<<"requirement">>,<<"~> 1.0">>}]]}. |
| 333 | + {<<"version">>,<<"19.9.0">>}. |
| @@ -1,53 +0,0 @@ | |
| 1 | - |
| 2 | - -record(challenge, { |
| 3 | - type = <<"http-01">> :: bitstring(), |
| 4 | - status = pending :: pending | valid | invalid, |
| 5 | - uri = "" :: url(), |
| 6 | - token = <<"">> :: bitstring() |
| 7 | - }). |
| 8 | - |
| 9 | - -record(data_acc, { |
| 10 | - id :: list(), |
| 11 | - ca_url :: url(), |
| 12 | - key :: jose_jwk:key() |
| 13 | - }). |
| 14 | - -type data_acc() :: #data_acc{}. |
| 15 | - |
| 16 | - -record(data_cert, { |
| 17 | - domain :: bitstring(), |
| 18 | - pem :: pem(), |
| 19 | - path :: string() |
| 20 | - }). |
| 21 | - -type data_cert() :: #data_cert{}. |
| 22 | - |
| 23 | - %% |
| 24 | - %% Types |
| 25 | - %% |
| 26 | - |
| 27 | - %% Acme configuration |
| 28 | - -type acme_config() :: [{ca_url, url()} | {contact, bitstring()}]. |
| 29 | - |
| 30 | - %% The main data type that ejabberd_acme keeps |
| 31 | - -type acme_data() :: proplist(). |
| 32 | - |
| 33 | - %% The list of certificates kept in data |
| 34 | - -type data_certs() :: proplist(bitstring(), data_cert()). |
| 35 | - |
| 36 | - %% The certificate saved in pem format |
| 37 | - -type pem() :: bitstring(). |
| 38 | - |
| 39 | - -type nonce() :: string(). |
| 40 | - -type url() :: string(). |
| 41 | - -type proplist() :: [{_, _}]. |
| 42 | - -type proplist(X,Y) :: [{X,Y}]. |
| 43 | - -type dirs() :: #{string() => url()}. |
| 44 | - -type jws() :: map(). |
| 45 | - -type handle_resp_fun() :: fun(({ok, proplist(), proplist()}) -> {ok, _, nonce()}). |
| 46 | - |
| 47 | - -type acme_challenge() :: #challenge{}. |
| 48 | - |
| 49 | - %% Options |
| 50 | - -type account_opt() :: string(). |
| 51 | - -type verbose_opt() :: string(). |
| 52 | - -type domains_opt() :: string(). |
| 53 | - |
| @@ -3,7 +3,7 @@ defmodule Ejabberd.Mixfile do | |
| 3 3 | |
| 4 4 | def project do |
| 5 5 | [app: :ejabberd, |
| 6 | - version: "19.8.0", |
| 6 | + version: "19.9.0", |
| 7 7 | description: description(), |
| 8 8 | elixir: "~> 1.4", |
| 9 9 | elixirc_paths: ["lib"], |
| @@ -29,7 +29,8 @@ defmodule Ejabberd.Mixfile do | |
| 29 29 | included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab, |
| 30 30 | :fast_tls, :stringprep, :fast_xml, :xmpp, :mqtree, |
| 31 31 | :stun, :fast_yaml, :esip, :jiffy, :p1_oauth2, |
| 32 | - :eimp, :base64url, :jose, :pkix, :os_mon, :yconf] |
| 32 | + :eimp, :base64url, :jose, :pkix, :os_mon, :yconf, |
| 33 | + :p1_acme, :idna] |
| 33 34 | ++ cond_apps()] |
| 34 35 | end |
| 35 36 | |
| @@ -81,7 +82,7 @@ defmodule Ejabberd.Mixfile do | |
| 81 82 | {:p1_mysql, "~> 1.0"}, |
| 82 83 | {:mqtree, "~> 1.0"}, |
| 83 84 | {:p1_pgsql, "~> 1.1"}, |
| 84 | - {:jiffy, "~> 0.14.7"}, |
| 85 | + {:jiffy, "~> 1.0"}, |
| 85 86 | {:p1_oauth2, "~> 0.6.1"}, |
| 86 87 | {:distillery, "~> 2.0"}, |
| 87 88 | {:pkix, "~> 1.0"}, |
| @@ -89,7 +90,9 @@ defmodule Ejabberd.Mixfile do | |
| 89 90 | {:eimp, "~> 1.0"}, |
| 90 91 | {:base64url, "~> 0.0.1"}, |
| 91 92 | {:yconf, "~> 1.0"}, |
| 92 | - {:jose, "~> 1.8"}] |
| 93 | + {:jose, "~> 1.8"}, |
| 94 | + {:idna, "~> 6.0"}, |
| 95 | + {:p1_acme, "~> 1.0"}] |
| 93 96 | ++ cond_deps() |
| 94 97 | end |
| @@ -1,144 +0,0 @@ | |
| 1 | - -module(acme_challenge). |
| 2 | - |
| 3 | - -export ([key_authorization/2, |
| 4 | - solve_challenge/3, |
| 5 | - process/2, |
| 6 | - register_hooks/1, |
| 7 | - unregister_hooks/1, |
| 8 | - acme_handler/3 |
| 9 | - ]). |
| 10 | - %% Challenge Types |
| 11 | - %% ================ |
| 12 | - %% 1. http-01: https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-7.2 |
| 13 | - %% 2. dns-01: https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-7.3 |
| 14 | - %% 3. tls-sni-01: https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-7.4 |
| 15 | - %% 4. (?) oob-01: https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-7.5 |
| 16 | - |
| 17 | - -include("logger.hrl"). |
| 18 | - -include("xmpp.hrl"). |
| 19 | - -include("ejabberd_http.hrl"). |
| 20 | - -include("ejabberd_acme.hrl"). |
| 21 | - |
| 22 | - %% This is the default endpoint for the http challenge |
| 23 | - %% This hooks is called from ejabberd_http |
| 24 | - acme_handler(Handlers, _Host, Request) -> |
| 25 | - case Request#request.path of |
| 26 | - [<<".well-known">>|_] -> |
| 27 | - [{[<<".well-known">>],acme_challenge}|Handlers]; |
| 28 | - _ -> |
| 29 | - Handlers |
| 30 | - end. |
| 31 | - |
| 32 | - %% TODO: Maybe validate request here?? |
| 33 | - process(LocalPath, _Request) -> |
| 34 | - Result = ets_get_key_authorization(LocalPath), |
| 35 | - {200, |
| 36 | - [{<<"Content-Type">>, <<"text/plain">>}], |
| 37 | - Result}. |
| 38 | - |
| 39 | - register_hooks(_Domain) -> |
| 40 | - ?INFO_MSG("Registering hook for ACME HTTP headers", []), |
| 41 | - ejabberd_hooks:add(http_request_handlers, ?MODULE, acme_handler, 50). |
| 42 | - |
| 43 | - unregister_hooks(_Domain) -> |
| 44 | - ?INFO_MSG("Unregistering hook for ACME HTTP headers", []), |
| 45 | - ejabberd_hooks:delete(http_request_handlers, ?MODULE, acme_handler, 50). |
| 46 | - |
| 47 | - -spec key_authorization(bitstring(), jose_jwk:key()) -> bitstring(). |
| 48 | - key_authorization(Token, Key) -> |
| 49 | - Thumbprint = jose_jwk:thumbprint(Key), |
| 50 | - KeyAuthorization = erlang:iolist_to_binary([Token, <<".">>, Thumbprint]), |
| 51 | - KeyAuthorization. |
| 52 | - |
| 53 | - -spec parse_challenge({proplist()}) -> {ok, acme_challenge()} | {error, _}. |
| 54 | - parse_challenge(Challenge0) -> |
| 55 | - try |
| 56 | - {Challenge} = Challenge0, |
| 57 | - {<<"type">>,Type} = proplists:lookup(<<"type">>, Challenge), |
| 58 | - {<<"status">>,Status} = proplists:lookup(<<"status">>, Challenge), |
| 59 | - {<<"uri">>,Uri} = proplists:lookup(<<"uri">>, Challenge), |
| 60 | - {<<"token">>,Token} = proplists:lookup(<<"token">>, Challenge), |
| 61 | - Res = |
| 62 | - #challenge{ |
| 63 | - type = Type, |
| 64 | - status = list_to_atom(bitstring_to_list(Status)), |
| 65 | - uri = bitstring_to_list(Uri), |
| 66 | - token = Token |
| 67 | - }, |
| 68 | - {ok, Res} |
| 69 | - catch |
| 70 | - _:Error -> |
| 71 | - {error, Error} |
| 72 | - end. |
| 73 | - |
| 74 | - |
| 75 | - |
| 76 | - -spec solve_challenge(bitstring(), [{proplist()}], _) -> |
| 77 | - {ok, url(), bitstring()} | {error, _}. |
| 78 | - solve_challenge(ChallengeType, Challenges, Options) -> |
| 79 | - ParsedChallenges = [parse_challenge(Chall) || Chall <- Challenges], |
| 80 | - case lists:any(fun is_error/1, ParsedChallenges) of |
| 81 | - true -> |
| 82 | - ?ERROR_MSG("Error parsing challenges: ~p~n", [Challenges]), |
| 83 | - {error, parse_challenge}; |
| 84 | - false -> |
| 85 | - case [C || {ok, C} <- ParsedChallenges, is_challenge_type(ChallengeType, C)] of |
| 86 | - [Challenge] -> |
| 87 | - solve_challenge1(Challenge, Options); |
| 88 | - _ -> |
| 89 | - ?ERROR_MSG("Challenge ~p not found in challenges: ~p~n", [ChallengeType, Challenges]), |
| 90 | - {error, not_found} |
| 91 | - end |
| 92 | - end. |
| 93 | - |
| 94 | - -spec solve_challenge1(acme_challenge(), {jose_jwk:key(), string()}) -> |
| 95 | - {ok, url(), bitstring()} | {error, _}. |
| 96 | - solve_challenge1(Chal = #challenge{type = <<"http-01">>, token=Tkn}, Key) -> |
| 97 | - KeyAuthz = key_authorization(Tkn, Key), |
| 98 | - %% save_key_authorization(Chal, Tkn, KeyAuthz, HttpDir); |
| 99 | - ets_put_key_authorization(Tkn, KeyAuthz), |
| 100 | - {ok, Chal#challenge.uri, KeyAuthz}; |
| 101 | - solve_challenge1(Challenge, _Key) -> |
| 102 | - ?ERROR_MSG("Unknown Challenge Type: ~p", [Challenge]), |
| 103 | - {error, unknown_challenge}. |
| 104 | - |
| 105 | - |
| 106 | - -spec ets_put_key_authorization(bitstring(), bitstring()) -> ok. |
| 107 | - ets_put_key_authorization(Tkn, KeyAuthz) -> |
| 108 | - Tab = ets_get_acme_table(), |
| 109 | - Key = [<<"acme-challenge">>, Tkn], |
| 110 | - ets:insert(Tab, {Key, KeyAuthz}), |
| 111 | - ok. |
| 112 | - |
| 113 | - -spec ets_get_key_authorization([bitstring()]) -> bitstring(). |
| 114 | - ets_get_key_authorization(Key) -> |
| 115 | - Tab = ets_get_acme_table(), |
| 116 | - case ets:lookup(Tab, Key) of |
| 117 | - [{Key, KeyAuthz}] -> |
| 118 | - ets:delete(Tab, Key), |
| 119 | - KeyAuthz; |
| 120 | - _ -> |
| 121 | - ?ERROR_MSG("Unable to serve key authorization in: ~p", [Key]), |
| 122 | - <<"">> |
| 123 | - end. |
| 124 | - |
| 125 | - -spec ets_get_acme_table() -> atom(). |
| 126 | - ets_get_acme_table() -> |
| 127 | - case ets:info(acme) of |
| 128 | - undefined -> |
| 129 | - ets:new(acme, [named_table, public]); |
| 130 | - _ -> |
| 131 | - acme |
| 132 | - end. |
| 133 | - |
| 134 | - %% Useful functions |
| 135 | - |
| 136 | - is_challenge_type(DesiredType, #challenge{type = Type}) when DesiredType =:= Type -> |
| 137 | - true; |
| 138 | - is_challenge_type(_DesiredType, #challenge{type = _Type}) -> |
| 139 | - false. |
| 140 | - |
| 141 | - -spec is_error({'error', _}) -> 'true'; |
| 142 | - ({'ok', _}) -> 'false'. |
| 143 | - is_error({error, _}) -> true; |
| 144 | - is_error(_) -> false. |
Loading more files…