Current section

56 Versions

Jump to

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…