From c0f7008e96b8159367d025c61f5230685a8c5993 Mon Sep 17 00:00:00 2001 From: Badlop Date: Mon, 1 Jun 2020 10:35:28 +0200 Subject: [PATCH] Use old http_uri, crypto and pg2 only with old Erlang/OTP (#3284) --- rebar.config | 3 +++ src/ejabberd_config_transformer.erl | 4 ++-- src/eldap_pool.erl | 24 +++++++++++++++++++++--- src/misc.erl | 23 ++++++++++++++++++++++- src/mod_http_upload.erl | 6 +++--- src/mod_mix.erl | 2 +- src/mod_s2s_dialback.erl | 2 +- src/mod_sip.erl | 4 ++-- src/mod_stun_disco.erl | 2 +- 9 files changed, 56 insertions(+), 14 deletions(-) diff --git a/rebar.config b/rebar.config index 04b617ad7..efcea966f 100644 --- a/rebar.config +++ b/rebar.config @@ -94,7 +94,10 @@ {if_var_true, sip, {d, 'SIP'}}, {if_var_true, stun, {d, 'STUN'}}, {if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}}, + {if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}}, {if_version_below, "22", {d, 'LAGER'}}, + {if_version_below, "23", {d, 'USE_OLD_CRYPTO_HMAC'}}, + {if_version_below, "23", {d, 'USE_OLD_PG2'}}, {if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}}, {if_var_match, db_type, mssql, {d, 'mssql'}}, {if_var_true, elixir, {d, 'ELIXIR_ENABLED'}}, diff --git a/src/ejabberd_config_transformer.erl b/src/ejabberd_config_transformer.erl index 62fb87f9d..8fd8be80d 100644 --- a/src/ejabberd_config_transformer.erl +++ b/src/ejabberd_config_transformer.erl @@ -102,8 +102,8 @@ transform(_Host, certfiles, CertFiles1, Acc) -> transform(_Host, acme, ACME, Acc) -> ACME1 = lists:map( fun({ca_url, URL} = Opt) -> - case http_uri:parse(binary_to_list(URL)) of - {ok, {_, _, "acme-v01.api.letsencrypt.org", _, _, _}} -> + case misc:uri_parse(URL) of + {ok, _, "acme-v01.api.letsencrypt.org", _, _} -> NewURL = ejabberd_acme:default_directory_url(), ?WARNING_MSG("ACME directory URL ~ts defined in " "option acme->ca_url is deprecated " diff --git a/src/eldap_pool.erl b/src/eldap_pool.erl index 004b28db3..a29b0c88f 100644 --- a/src/eldap_pool.erl +++ b/src/eldap_pool.erl @@ -33,6 +33,24 @@ -include("logger.hrl"). +-ifdef(USE_OLD_PG2). +pg_create(PoolName) -> pg2:create(PoolName). +pg_join(PoolName, Pid) -> pg2:join(PoolName, Pid). +pg_get_closest_pid(Name) -> pg2:get_closest_pid(Name). +-else. +pg_create(_) -> pg:start_link(). +pg_join(PoolName, Pid) -> pg:join(PoolName, Pid). +pg_get_closest_pid(Group) -> + case pg:get_local_members(Group) of + [] -> + case pg:get_members(Group) of + [] -> {error, {no_process, Group}}; + [Pid | _] -> Pid + end; + [Pid | _] -> Pid + end. +-endif. + %%==================================================================== %% API %%==================================================================== @@ -48,14 +66,14 @@ modify_passwd(PoolName, DN, Passwd) -> start_link(Name, Hosts, Backups, Port, Rootdn, Passwd, Opts) -> PoolName = make_id(Name), - pg2:create(PoolName), + pg_create(PoolName), lists:foreach(fun (Host) -> ID = list_to_binary(erlang:ref_to_list(make_ref())), case catch eldap:start_link(ID, [Host | Backups], Port, Rootdn, Passwd, Opts) of - {ok, Pid} -> pg2:join(PoolName, Pid); + {ok, Pid} -> pg_join(PoolName, Pid); Err -> ?ERROR_MSG("Err = ~p", [Err]), error @@ -67,7 +85,7 @@ start_link(Name, Hosts, Backups, Port, Rootdn, Passwd, %% Internal functions %%==================================================================== do_request(Name, {F, Args}) -> - case pg2:get_closest_pid(make_id(Name)) of + case pg_get_closest_pid(make_id(Name)) of Pid when is_pid(Pid) -> case catch apply(eldap, F, [Pid | Args]) of {'EXIT', {timeout, _}} -> diff --git a/src/misc.erl b/src/misc.erl index 3b65aa557..c91809015 100644 --- a/src/misc.erl +++ b/src/misc.erl @@ -41,6 +41,7 @@ intersection/2, format_val/1, cancel_timer/1, unique_timestamp/0, is_mucsub_message/1, best_match/2, pmap/2, peach/2, format_exception/4, get_my_ipv4_address/0, get_my_ipv6_address/0, parse_ip_mask/1, + crypto_hmac/3, crypto_hmac/4, uri_parse/1, match_ip_mask/3, format_hosts_list/1, format_cycle/1, delete_dir/1]). %% Deprecated functions @@ -54,6 +55,26 @@ -type distance_cache() :: #{{string(), string()} => non_neg_integer()}. +-ifdef(USE_OLD_HTTP_URI). +uri_parse(URL) when is_binary(URL) -> + uri_parse(binary_to_list(URL)); +uri_parse(URL) -> + {ok, {Scheme, _UserInfo, Host, Port, Path, _Query}} = http_uri:parse(URL), + {ok, Scheme, Host, Port, Path}. +-else. +uri_parse(URL) -> + #{scheme:=Scheme,host:=Host,port:=Port,path:=Path} = uri_string:parse(URL), + {ok, Scheme, Host, Port, Path}. +-endif. + +-ifdef(USE_OLD_CRYPTO_HMAC). +crypto_hmac(Type, Key, Data) -> crypto:hmac(Type, Key, Data). +crypto_hmac(Type, Key, Data, MacL) -> crypto:hmac(Type, Key, Data, MacL). +-else. +crypto_hmac(Type, Key, Data) -> crypto:mac(hmac, Type, Key, Data). +crypto_hmac(Type, Key, Data, MacL) -> crypto:macN(hmac, Type, Key, Data, MacL). +-endif. + %%%=================================================================== %%% API %%%=================================================================== @@ -328,7 +349,7 @@ try_url(URL0) -> V when is_binary(V) -> binary_to_list(V); _ -> URL0 end, - case http_uri:parse(URL) of + case uri_parse(URL) of {ok, {Scheme, _, _, _, _, _}} when Scheme /= http, Scheme /= https -> ?ERROR_MSG("Unsupported URI scheme: ~ts", [URL]), erlang:error(badarg); diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 51d7761ab..cf4ab0d1e 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -711,8 +711,8 @@ get_proc_name(ServerHost, ModuleName) -> -spec get_proc_name(binary(), atom(), binary()) -> atom(). get_proc_name(ServerHost, ModuleName, PutURL) -> %% Once we depend on OTP >= 20.0, we can use binaries with http_uri. - {ok, {_Scheme, _UserInfo, Host0, _Port, Path0, _Query}} = - http_uri:parse(binary_to_list(expand_host(PutURL, ServerHost))), + {ok, _Scheme, Host0, _Port, Path0} = + misc:uri_parse(expand_host(PutURL, ServerHost)), Host = jid:nameprep(iolist_to_binary(Host0)), Path = str:strip(iolist_to_binary(Path0), right, $/), ProcPrefix = <>, @@ -934,7 +934,7 @@ make_query_string(Slot, Size, #state{external_secret = Key}) when Key /= <<>> -> UrlPath = str:join(Slot, <<$/>>), SizeStr = integer_to_binary(Size), Data = <>, - HMAC = str:to_hexlist(crypto:hmac(sha256, Key, Data)), + HMAC = str:to_hexlist(misc:crypto_hmac(sha256, Key, Data)), <<"?v=", HMAC/binary>>; make_query_string(_Slot, _Size, _State) -> <<>>. diff --git a/src/mod_mix.erl b/src/mod_mix.erl index 29fa6e4ac..3b43cfa0d 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -642,7 +642,7 @@ notify_participant_left(Mod, LServer, To, ID) -> -spec make_id(jid(), binary()) -> binary(). make_id(JID, Key) -> Data = jid:encode(jid:tolower(jid:remove_resource(JID))), - xmpp_util:hex(crypto:hmac(sha256, Data, Key, 10)). + xmpp_util:hex(misc:crypto_hmac(sha256, Data, Key, 10)). %%%=================================================================== %%% Error generators diff --git a/src/mod_s2s_dialback.erl b/src/mod_s2s_dialback.erl index 91e2554ad..fdf4fa270 100644 --- a/src/mod_s2s_dialback.erl +++ b/src/mod_s2s_dialback.erl @@ -305,7 +305,7 @@ s2s_out_tls_verify(_, #{server_host := ServerHost, remote_server := RServer}) -> make_key(From, To, StreamID) -> Secret = ejabberd_config:get_shared_key(), str:to_hexlist( - crypto:hmac(sha256, str:to_hexlist(crypto:hash(sha256, Secret)), + misc:crypto_hmac(sha256, str:to_hexlist(crypto:hash(sha256, Secret)), [To, " ", From, " ", StreamID])). -spec send_verify_request(ejabberd_s2s_out:state()) -> ejabberd_s2s_out:state(). diff --git a/src/mod_sip.erl b/src/mod_sip.erl index bb25a0eab..c473fe82f 100644 --- a/src/mod_sip.erl +++ b/src/mod_sip.erl @@ -357,8 +357,8 @@ mod_opt_type(via) -> (econf:and_then( econf:url([tls, tcp, udp]), fun(URI) -> - {ok, {Type, _, Host, Port, _, _}} = - http_uri:parse(binary_to_list(URI)), + {ok, Type, Host, Port, _} = + misc:uri_parse(URI), {Type, {unicode:characters_to_binary(Host), Port}} end))(U) end, [unique]). diff --git a/src/mod_stun_disco.erl b/src/mod_stun_disco.erl index 6231c7f44..94241e3f4 100644 --- a/src/mod_stun_disco.erl +++ b/src/mod_stun_disco.erl @@ -555,7 +555,7 @@ make_username(ExpireAt, Hash) -> -spec make_password(binary(), binary()) -> binary(). make_password(Username, Secret) -> - base64:encode(crypto:hmac(sha, Secret, Username)). + base64:encode(misc:crypto_hmac(sha, Secret, Username)). -spec get_password(binary(), binary()) -> binary(). get_password(Username, HostHash) ->