mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Add code for handling deprecations of get_stacktrace()
This commit is contained in:
parent
34ac21e66b
commit
c88a2d0569
27
include/ejabberd_stacktrace.hrl
Normal file
27
include/ejabberd_stacktrace.hrl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%%
|
||||||
|
%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
|
||||||
|
%%%
|
||||||
|
%%% This program is free software; you can redistribute it and/or
|
||||||
|
%%% modify it under the terms of the GNU General Public License as
|
||||||
|
%%% published by the Free Software Foundation; either version 2 of the
|
||||||
|
%%% License, or (at your option) any later version.
|
||||||
|
%%%
|
||||||
|
%%% This program is distributed in the hope that it will be useful,
|
||||||
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
%%% General Public License for more details.
|
||||||
|
%%%
|
||||||
|
%%% You should have received a copy of the GNU General Public License along
|
||||||
|
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
%%%
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-ifdef(DEPRECATED_GET_STACKTRACE).
|
||||||
|
-define(EX_RULE(Class, Reason, Stack), Class:Reason:Stack).
|
||||||
|
-define(EX_STACK(Stack), Stack).
|
||||||
|
-else.
|
||||||
|
-define(EX_RULE(Class, Reason, _), Class:Reason).
|
||||||
|
-define(EX_STACK(_), erlang:get_stacktrace()).
|
||||||
|
-endif.
|
9
mix.exs
9
mix.exs
@ -42,10 +42,19 @@ defmodule Ejabberd.Mixfile do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp if_version_above(ver, okResult) do
|
||||||
|
if :erlang.system_info(:otp_release) > ver do
|
||||||
|
okResult
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp erlc_options do
|
defp erlc_options do
|
||||||
# Use our own includes + includes from all dependencies
|
# Use our own includes + includes from all dependencies
|
||||||
includes = ["include"] ++ deps_include(["fast_xml", "xmpp", "p1_utils"])
|
includes = ["include"] ++ deps_include(["fast_xml", "xmpp", "p1_utils"])
|
||||||
[:debug_info, {:d, :ELIXIR_ENABLED}] ++ cond_options() ++ Enum.map(includes, fn(path) -> {:i, path} end) ++
|
[:debug_info, {:d, :ELIXIR_ENABLED}] ++ cond_options() ++ Enum.map(includes, fn(path) -> {:i, path} end) ++
|
||||||
|
if_version_above('20', [{:d, :DEPRECATED_GET_STACKTRACE}]) ++
|
||||||
if_function_exported(:crypto, :strong_rand_bytes, 1, [{:d, :STRONG_RAND_BYTES}]) ++
|
if_function_exported(:crypto, :strong_rand_bytes, 1, [{:d, :STRONG_RAND_BYTES}]) ++
|
||||||
if_function_exported(:rand, :uniform, 1, [{:d, :RAND_UNIFORM}]) ++
|
if_function_exported(:rand, :uniform, 1, [{:d, :RAND_UNIFORM}]) ++
|
||||||
if_function_exported(:gb_sets, :iterator_from, 2, [{:d, :GB_SETS_ITERATOR_FROM}]) ++
|
if_function_exported(:gb_sets, :iterator_from, 2, [{:d, :GB_SETS_ITERATOR_FROM}]) ++
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
{if_var_true, debug, debug_info},
|
{if_var_true, debug, debug_info},
|
||||||
{if_var_true, sip, {d, 'SIP'}},
|
{if_var_true, sip, {d, 'SIP'}},
|
||||||
{if_var_true, stun, {d, 'STUN'}},
|
{if_var_true, stun, {d, 'STUN'}},
|
||||||
|
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
|
||||||
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
|
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
|
||||||
{if_var_match, db_type, mssql, {d, 'mssql'}},
|
{if_var_match, db_type, mssql, {d, 'mssql'}},
|
||||||
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
|
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
-include("ejabberd_commands.hrl").
|
-include("ejabberd_commands.hrl").
|
||||||
-include("ejabberd_acme.hrl").
|
-include("ejabberd_acme.hrl").
|
||||||
-include_lib("public_key/include/public_key.hrl").
|
-include_lib("public_key/include/public_key.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-define(DEFAULT_CONFIG_CONTACT, <<"mailto:example-admin@example.com">>).
|
-define(DEFAULT_CONFIG_CONTACT, <<"mailto:example-admin@example.com">>).
|
||||||
-define(DEFAULT_CONFIG_CA_URL, "https://acme-v01.api.letsencrypt.org").
|
-define(DEFAULT_CONFIG_CA_URL, "https://acme-v01.api.letsencrypt.org").
|
||||||
@ -100,10 +101,10 @@ is_valid_domain_opt(DomainString) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
-spec is_valid_revoke_cert(string()) -> boolean().
|
-spec is_valid_revoke_cert(string()) -> boolean().
|
||||||
is_valid_revoke_cert(DomainOrFile) ->
|
is_valid_revoke_cert(DomainOrFile) ->
|
||||||
lists:prefix("file:", DomainOrFile) orelse
|
lists:prefix("file:", DomainOrFile) orelse
|
||||||
lists:prefix("domain:", DomainOrFile).
|
lists:prefix("domain:", DomainOrFile).
|
||||||
|
|
||||||
%% Commands
|
%% Commands
|
||||||
get_commands_spec() ->
|
get_commands_spec() ->
|
||||||
[#ejabberd_commands{name = get_certificates, tags = [acme],
|
[#ejabberd_commands{name = get_certificates, tags = [acme],
|
||||||
@ -142,7 +143,7 @@ get_commands_spec() ->
|
|||||||
%%
|
%%
|
||||||
-spec get_certificates(domains_opt()) -> string() | {'error', _}.
|
-spec get_certificates(domains_opt()) -> string() | {'error', _}.
|
||||||
get_certificates(Domains) ->
|
get_certificates(Domains) ->
|
||||||
case is_valid_domain_opt(Domains) of
|
case is_valid_domain_opt(Domains) of
|
||||||
true ->
|
true ->
|
||||||
try
|
try
|
||||||
CAUrl = get_config_ca_url(),
|
CAUrl = get_config_ca_url(),
|
||||||
@ -150,9 +151,8 @@ get_certificates(Domains) ->
|
|||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
{error, get_certificates}
|
{error, get_certificates}
|
||||||
end;
|
end;
|
||||||
false ->
|
false ->
|
||||||
@ -171,7 +171,7 @@ retrieve_or_create_account(CAUrl) ->
|
|||||||
case read_account_persistent() of
|
case read_account_persistent() of
|
||||||
none ->
|
none ->
|
||||||
create_save_new_account(CAUrl);
|
create_save_new_account(CAUrl);
|
||||||
|
|
||||||
{ok, AccId, CAUrl, PrivateKey} ->
|
{ok, AccId, CAUrl, PrivateKey} ->
|
||||||
{ok, AccId, PrivateKey};
|
{ok, AccId, PrivateKey};
|
||||||
{ok, _AccId, _, _PrivateKey} ->
|
{ok, _AccId, _, _PrivateKey} ->
|
||||||
@ -199,7 +199,7 @@ get_certificates2(CAUrl, PrivateKey, Hosts) ->
|
|||||||
%% Format the result to send back to ejabberdctl
|
%% Format the result to send back to ejabberdctl
|
||||||
format_get_certificates_result(SavedCerts).
|
format_get_certificates_result(SavedCerts).
|
||||||
|
|
||||||
-spec format_get_certificates_result([{'ok', bitstring(), _} |
|
-spec format_get_certificates_result([{'ok', bitstring(), _} |
|
||||||
{'error', bitstring(), _}]) ->
|
{'error', bitstring(), _}]) ->
|
||||||
string().
|
string().
|
||||||
format_get_certificates_result(Certs) ->
|
format_get_certificates_result(Certs) ->
|
||||||
@ -211,26 +211,26 @@ format_get_certificates_result(Certs) ->
|
|||||||
case Cond of
|
case Cond of
|
||||||
true ->
|
true ->
|
||||||
Result = io_lib:format("Success:~n~s", [FormattedCerts]),
|
Result = io_lib:format("Success:~n~s", [FormattedCerts]),
|
||||||
lists:flatten(Result);
|
lists:flatten(Result);
|
||||||
_ ->
|
_ ->
|
||||||
Result = io_lib:format("Error with one or more certificates~n~s", [FormattedCerts]),
|
Result = io_lib:format("Error with one or more certificates~n~s", [FormattedCerts]),
|
||||||
lists:flatten(Result)
|
lists:flatten(Result)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec format_get_certificate({'ok', bitstring(), _} |
|
-spec format_get_certificate({'ok', bitstring(), _} |
|
||||||
{'error', bitstring(), _}) ->
|
{'error', bitstring(), _}) ->
|
||||||
string().
|
string().
|
||||||
format_get_certificate({ok, Domain, saved}) ->
|
format_get_certificate({ok, Domain, saved}) ->
|
||||||
io_lib:format(" Certificate for domain: \"~s\" acquired and saved", [Domain]);
|
io_lib:format(" Certificate for domain: \"~s\" acquired and saved", [Domain]);
|
||||||
format_get_certificate({ok, Domain, not_found}) ->
|
format_get_certificate({ok, Domain, not_found}) ->
|
||||||
io_lib:format(" Certificate for domain: \"~s\" not found, so it was not renewed", [Domain]);
|
io_lib:format(" Certificate for domain: \"~s\" not found, so it was not renewed", [Domain]);
|
||||||
format_get_certificate({ok, Domain, no_expire}) ->
|
format_get_certificate({ok, Domain, no_expire}) ->
|
||||||
io_lib:format(" Certificate for domain: \"~s\" is not close to expiring", [Domain]);
|
io_lib:format(" Certificate for domain: \"~s\" is not close to expiring", [Domain]);
|
||||||
format_get_certificate({error, Domain, Reason}) ->
|
format_get_certificate({error, Domain, Reason}) ->
|
||||||
io_lib:format(" Error for domain: \"~s\", with reason: \'~s\'", [Domain, Reason]).
|
io_lib:format(" Error for domain: \"~s\", with reason: \'~s\'", [Domain, Reason]).
|
||||||
|
|
||||||
-spec get_certificate(url(), bitstring(), jose_jwk:key()) ->
|
-spec get_certificate(url(), bitstring(), jose_jwk:key()) ->
|
||||||
{'ok', bitstring(), pem()} |
|
{'ok', bitstring(), pem()} |
|
||||||
{'error', bitstring(), _}.
|
{'error', bitstring(), _}.
|
||||||
get_certificate(CAUrl, DomainName, PrivateKey) ->
|
get_certificate(CAUrl, DomainName, PrivateKey) ->
|
||||||
try
|
try
|
||||||
@ -243,9 +243,8 @@ get_certificate(CAUrl, DomainName, PrivateKey) ->
|
|||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
{error, DomainName, get_certificate}
|
{error, DomainName, get_certificate}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -267,23 +266,23 @@ create_save_new_account(CAUrl) ->
|
|||||||
|
|
||||||
%% TODO:
|
%% TODO:
|
||||||
%% Find a way to ask the user if he accepts the TOS
|
%% Find a way to ask the user if he accepts the TOS
|
||||||
-spec create_new_account(url(), bitstring(), jose_jwk:key()) -> {'ok', string()} |
|
-spec create_new_account(url(), bitstring(), jose_jwk:key()) -> {'ok', string()} |
|
||||||
no_return().
|
no_return().
|
||||||
create_new_account(CAUrl, Contact, PrivateKey) ->
|
create_new_account(CAUrl, Contact, PrivateKey) ->
|
||||||
try
|
try
|
||||||
{ok, Dirs, Nonce0} = ejabberd_acme_comm:directory(CAUrl),
|
{ok, Dirs, Nonce0} = ejabberd_acme_comm:directory(CAUrl),
|
||||||
Req0 = [{ <<"contact">>, [Contact]}],
|
Req0 = [{ <<"contact">>, [Contact]}],
|
||||||
{ok, {TOS, Account}, Nonce1} =
|
{ok, {TOS, Account}, Nonce1} =
|
||||||
ejabberd_acme_comm:new_account(Dirs, PrivateKey, Req0, Nonce0),
|
ejabberd_acme_comm:new_account(Dirs, PrivateKey, Req0, Nonce0),
|
||||||
{<<"id">>, AccIdInt} = lists:keyfind(<<"id">>, 1, Account),
|
{<<"id">>, AccIdInt} = lists:keyfind(<<"id">>, 1, Account),
|
||||||
AccId = integer_to_list(AccIdInt),
|
AccId = integer_to_list(AccIdInt),
|
||||||
Req1 = [{ <<"agreement">>, list_to_bitstring(TOS)}],
|
Req1 = [{ <<"agreement">>, list_to_bitstring(TOS)}],
|
||||||
{ok, _Account2, _Nonce2} =
|
{ok, _Account2, _Nonce2} =
|
||||||
ejabberd_acme_comm:update_account({CAUrl, AccId}, PrivateKey, Req1, Nonce1),
|
ejabberd_acme_comm:update_account({CAUrl, AccId}, PrivateKey, Req1, Nonce1),
|
||||||
{ok, AccId}
|
{ok, AccId}
|
||||||
catch
|
catch
|
||||||
E:R ->
|
E:R ->
|
||||||
?ERROR_MSG("Error: ~p creating an account for contact: ~p",
|
?ERROR_MSG("Error: ~p creating an account for contact: ~p",
|
||||||
[{E,R}, Contact]),
|
[{E,R}, Contact]),
|
||||||
throw({error,create_new_account})
|
throw({error,create_new_account})
|
||||||
end.
|
end.
|
||||||
@ -298,7 +297,7 @@ create_new_authorization(CAUrl, DomainName, PrivateKey) ->
|
|||||||
{[{<<"type">>, <<"dns">>},
|
{[{<<"type">>, <<"dns">>},
|
||||||
{<<"value">>, DomainName}]}},
|
{<<"value">>, DomainName}]}},
|
||||||
{<<"existing">>, <<"accept">>}],
|
{<<"existing">>, <<"accept">>}],
|
||||||
{ok, {AuthzUrl, Authz}, Nonce1} =
|
{ok, {AuthzUrl, Authz}, Nonce1} =
|
||||||
ejabberd_acme_comm:new_authz(Dirs, PrivateKey, Req0, Nonce0),
|
ejabberd_acme_comm:new_authz(Dirs, PrivateKey, Req0, Nonce0),
|
||||||
{ok, AuthzId} = location_to_id(AuthzUrl),
|
{ok, AuthzId} = location_to_id(AuthzUrl),
|
||||||
|
|
||||||
@ -321,7 +320,7 @@ create_new_authorization(CAUrl, DomainName, PrivateKey) ->
|
|||||||
acme_challenge:unregister_hooks(DomainName)
|
acme_challenge:unregister_hooks(DomainName)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec create_new_certificate(url(), {bitstring(), [bitstring()]}, jose_jwk:key()) ->
|
-spec create_new_certificate(url(), {bitstring(), [bitstring()]}, jose_jwk:key()) ->
|
||||||
{ok, bitstring(), pem()}.
|
{ok, bitstring(), pem()}.
|
||||||
create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
|
create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
|
||||||
try
|
try
|
||||||
@ -338,7 +337,7 @@ create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
|
|||||||
{ok, {IssuerCertLink, Certificate}, _Nonce1} =
|
{ok, {IssuerCertLink, Certificate}, _Nonce1} =
|
||||||
ejabberd_acme_comm:new_cert(Dirs, PrivateKey, Req, Nonce0),
|
ejabberd_acme_comm:new_cert(Dirs, PrivateKey, Req, Nonce0),
|
||||||
|
|
||||||
DecodedCert = public_key:pkix_decode_cert(list_to_binary(Certificate), plain),
|
DecodedCert = public_key:pkix_decode_cert(list_to_binary(Certificate), plain),
|
||||||
PemEntryCert = public_key:pem_entry_encode('Certificate', DecodedCert),
|
PemEntryCert = public_key:pem_entry_encode('Certificate', DecodedCert),
|
||||||
|
|
||||||
{ok, IssuerCert, _Nonce2} = ejabberd_acme_comm:get_issuer_cert(IssuerCertLink),
|
{ok, IssuerCert, _Nonce2} = ejabberd_acme_comm:get_issuer_cert(IssuerCertLink),
|
||||||
@ -351,7 +350,7 @@ create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
|
|||||||
PemCertKey = public_key:pem_encode([PemEntryKey, PemEntryCert, PemEntryIssuerCert]),
|
PemCertKey = public_key:pem_encode([PemEntryKey, PemEntryCert, PemEntryIssuerCert]),
|
||||||
|
|
||||||
{ok, DomainName, PemCertKey}
|
{ok, DomainName, PemCertKey}
|
||||||
catch
|
catch
|
||||||
E:R ->
|
E:R ->
|
||||||
?ERROR_MSG("Error: ~p getting an authorization for domain: ~p~n",
|
?ERROR_MSG("Error: ~p getting an authorization for domain: ~p~n",
|
||||||
[{E,R}, DomainName]),
|
[{E,R}, DomainName]),
|
||||||
@ -383,9 +382,8 @@ renew_certificates() ->
|
|||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
{error, get_certificates}
|
{error, get_certificates}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -406,8 +404,8 @@ renew_certificates0(CAUrl) ->
|
|||||||
%% Format the result to send back to ejabberdctl
|
%% Format the result to send back to ejabberdctl
|
||||||
format_get_certificates_result(SavedCerts).
|
format_get_certificates_result(SavedCerts).
|
||||||
|
|
||||||
-spec renew_certificate(url(), {bitstring(), data_cert()}, jose_jwk:key()) ->
|
-spec renew_certificate(url(), {bitstring(), data_cert()}, jose_jwk:key()) ->
|
||||||
{'ok', bitstring(), _} |
|
{'ok', bitstring(), _} |
|
||||||
{'error', bitstring(), _}.
|
{'error', bitstring(), _}.
|
||||||
renew_certificate(CAUrl, {DomainName, _} = Cert, PrivateKey) ->
|
renew_certificate(CAUrl, {DomainName, _} = Cert, PrivateKey) ->
|
||||||
case cert_to_expire(Cert) of
|
case cert_to_expire(Cert) of
|
||||||
@ -449,9 +447,8 @@ list_certificates(Verbose) ->
|
|||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
{error, list_certificates}
|
{error, list_certificates}
|
||||||
end;
|
end;
|
||||||
false ->
|
false ->
|
||||||
@ -492,34 +489,33 @@ format_certificate(DataCert, Verbose) ->
|
|||||||
format_certificate_verbose(DomainName, SANs, NotAfter, PemCert)
|
format_certificate_verbose(DomainName, SANs, NotAfter, PemCert)
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
fail_format_certificate(DomainName)
|
fail_format_certificate(DomainName)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec format_certificate_plain(bitstring(), [string()], {expired | ok, string()}, string())
|
-spec format_certificate_plain(bitstring(), [string()], {expired | ok, string()}, string())
|
||||||
-> string().
|
-> string().
|
||||||
format_certificate_plain(DomainName, SANs, NotAfter, Path) ->
|
format_certificate_plain(DomainName, SANs, NotAfter, Path) ->
|
||||||
Result = lists:flatten(io_lib:format(
|
Result = lists:flatten(io_lib:format(
|
||||||
" Domain: ~s~n"
|
" Domain: ~s~n"
|
||||||
"~s"
|
"~s"
|
||||||
" ~s~n"
|
" ~s~n"
|
||||||
" Path: ~s",
|
" Path: ~s",
|
||||||
[DomainName,
|
[DomainName,
|
||||||
lists:flatten([io_lib:format(" SAN: ~s~n", [SAN]) || SAN <- SANs]),
|
lists:flatten([io_lib:format(" SAN: ~s~n", [SAN]) || SAN <- SANs]),
|
||||||
format_validity(NotAfter), Path])),
|
format_validity(NotAfter), Path])),
|
||||||
Result.
|
Result.
|
||||||
|
|
||||||
-spec format_certificate_verbose(bitstring(), [string()], {expired | ok, string()}, bitstring())
|
-spec format_certificate_verbose(bitstring(), [string()], {expired | ok, string()}, bitstring())
|
||||||
-> string().
|
-> string().
|
||||||
format_certificate_verbose(DomainName, SANs, NotAfter, PemCert) ->
|
format_certificate_verbose(DomainName, SANs, NotAfter, PemCert) ->
|
||||||
Result = lists:flatten(io_lib:format(
|
Result = lists:flatten(io_lib:format(
|
||||||
" Domain: ~s~n"
|
" Domain: ~s~n"
|
||||||
"~s"
|
"~s"
|
||||||
" ~s~n"
|
" ~s~n"
|
||||||
" Certificate In PEM format: ~n~s",
|
" Certificate In PEM format: ~n~s",
|
||||||
[DomainName,
|
[DomainName,
|
||||||
lists:flatten([io_lib:format(" SAN: ~s~n", [SAN]) || SAN <- SANs]),
|
lists:flatten([io_lib:format(" SAN: ~s~n", [SAN]) || SAN <- SANs]),
|
||||||
format_validity(NotAfter), PemCert])),
|
format_validity(NotAfter), PemCert])),
|
||||||
Result.
|
Result.
|
||||||
@ -533,8 +529,8 @@ format_validity({ok, NotAfter}) ->
|
|||||||
-spec fail_format_certificate(bitstring()) -> string().
|
-spec fail_format_certificate(bitstring()) -> string().
|
||||||
fail_format_certificate(DomainName) ->
|
fail_format_certificate(DomainName) ->
|
||||||
Result = lists:flatten(io_lib:format(
|
Result = lists:flatten(io_lib:format(
|
||||||
" Domain: ~s~n"
|
" Domain: ~s~n"
|
||||||
" Failed to format Certificate",
|
" Failed to format Certificate",
|
||||||
[DomainName])),
|
[DomainName])),
|
||||||
Result.
|
Result.
|
||||||
|
|
||||||
@ -542,7 +538,7 @@ fail_format_certificate(DomainName) ->
|
|||||||
get_commonName(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
get_commonName(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
||||||
#'TBSCertificate'{
|
#'TBSCertificate'{
|
||||||
subject = {rdnSequence, SubjectList}
|
subject = {rdnSequence, SubjectList}
|
||||||
} = TbsCertificate,
|
} = TbsCertificate,
|
||||||
|
|
||||||
%% TODO: Not the best way to find the commonName
|
%% TODO: Not the best way to find the commonName
|
||||||
ShallowSubjectList = [Attribute || [Attribute] <- SubjectList],
|
ShallowSubjectList = [Attribute || [Attribute] <- SubjectList],
|
||||||
@ -560,9 +556,9 @@ get_notAfter(Certificate) ->
|
|||||||
true -> "19" ++ [Y1,Y2];
|
true -> "19" ++ [Y1,Y2];
|
||||||
_ -> "20" ++ [Y1,Y2]
|
_ -> "20" ++ [Y1,Y2]
|
||||||
end,
|
end,
|
||||||
NotAfter = lists:flatten(io_lib:format("~s-~s-~s ~s:~s:~s",
|
NotAfter = lists:flatten(io_lib:format("~s-~s-~s ~s:~s:~s",
|
||||||
[YEAR, [MO1,MO2], [D1,D2],
|
[YEAR, [MO1,MO2], [D1,D2],
|
||||||
[H1,H2], [MI1,MI2], [S1,S2]])),
|
[H1,H2], [MI1,MI2], [S1,S2]])),
|
||||||
|
|
||||||
case close_to_expire(UtcTime, 0) of
|
case close_to_expire(UtcTime, 0) of
|
||||||
true ->
|
true ->
|
||||||
@ -577,7 +573,7 @@ get_subjectAltNames(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
|||||||
extensions = Exts
|
extensions = Exts
|
||||||
} = TbsCertificate,
|
} = TbsCertificate,
|
||||||
|
|
||||||
EncodedSANs = [Val || #'Extension'{extnID = Oid, extnValue = Val} <- Exts,
|
EncodedSANs = [Val || #'Extension'{extnID = Oid, extnValue = Val} <- Exts,
|
||||||
Oid =:= attribute_oid(subjectAltName)],
|
Oid =:= attribute_oid(subjectAltName)],
|
||||||
|
|
||||||
lists:flatmap(
|
lists:flatmap(
|
||||||
@ -586,7 +582,7 @@ get_subjectAltNames(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
|||||||
[Name || {dNSName, Name} <- SANs0]
|
[Name || {dNSName, Name} <- SANs0]
|
||||||
end, EncodedSANs).
|
end, EncodedSANs).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-spec get_utc_validity(#'Certificate'{}) -> string().
|
-spec get_utc_validity(#'Certificate'{}) -> string().
|
||||||
get_utc_validity(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
get_utc_validity(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
||||||
@ -618,18 +614,17 @@ revoke_certificates(DomainOrFile) ->
|
|||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
{error, revoke_certificate}
|
{error, revoke_certificate}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec revoke_certificate0(url(), string()) -> {ok, deleted}.
|
-spec revoke_certificate0(url(), string()) -> {ok, deleted}.
|
||||||
revoke_certificate0(CAUrl, DomainOrFile) ->
|
revoke_certificate0(CAUrl, DomainOrFile) ->
|
||||||
ParsedCert = parse_revoke_cert_argument(DomainOrFile),
|
ParsedCert = parse_revoke_cert_argument(DomainOrFile),
|
||||||
revoke_certificate1(CAUrl, ParsedCert).
|
revoke_certificate1(CAUrl, ParsedCert).
|
||||||
|
|
||||||
-spec revoke_certificate1(url(), {domain, bitstring()} | {file, file:filename()}) ->
|
-spec revoke_certificate1(url(), {domain, bitstring()} | {file, file:filename()}) ->
|
||||||
{ok, deleted}.
|
{ok, deleted}.
|
||||||
revoke_certificate1(CAUrl, {domain, Domain}) ->
|
revoke_certificate1(CAUrl, {domain, Domain}) ->
|
||||||
case domain_certificate_exists(Domain) of
|
case domain_certificate_exists(Domain) of
|
||||||
@ -650,7 +645,7 @@ revoke_certificate1(CAUrl, {file, File}) ->
|
|||||||
?ERROR_MSG("Error: ~p reading pem certificate-key file: ~p", [Reason, File]),
|
?ERROR_MSG("Error: ~p reading pem certificate-key file: ~p", [Reason, File]),
|
||||||
throw({error, Reason})
|
throw({error, Reason})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec revoke_certificate2(url(), pem()) -> ok.
|
-spec revoke_certificate2(url(), pem()) -> ok.
|
||||||
revoke_certificate2(CAUrl, PemEncodedCert) ->
|
revoke_certificate2(CAUrl, PemEncodedCert) ->
|
||||||
@ -676,10 +671,10 @@ prepare_certificate_revoke(PemEncodedCert) ->
|
|||||||
DerCert = public_key:der_encode('Certificate', PemCert),
|
DerCert = public_key:der_encode('Certificate', PemCert),
|
||||||
Base64Cert = base64url:encode(DerCert),
|
Base64Cert = base64url:encode(DerCert),
|
||||||
|
|
||||||
{ok, Key} = find_private_key_in_pem(PemEncodedCert),
|
{ok, Key} = find_private_key_in_pem(PemEncodedCert),
|
||||||
{Base64Cert, Key}.
|
{Base64Cert, Key}.
|
||||||
|
|
||||||
-spec domain_certificate_exists(bitstring()) -> {bitstring(), data_cert()} | false.
|
-spec domain_certificate_exists(bitstring()) -> {bitstring(), data_cert()} | false.
|
||||||
domain_certificate_exists(Domain) ->
|
domain_certificate_exists(Domain) ->
|
||||||
Certs = read_certificates_persistent(),
|
Certs = read_certificates_persistent(),
|
||||||
lists:keyfind(Domain, 1, Certs).
|
lists:keyfind(Domain, 1, Certs).
|
||||||
@ -693,7 +688,7 @@ domain_certificate_exists(Domain) ->
|
|||||||
%% For now we accept only generating a key of
|
%% For now we accept only generating a key of
|
||||||
%% specific type for signing the csr
|
%% specific type for signing the csr
|
||||||
|
|
||||||
-spec make_csr(proplist(), [{dNSName, bitstring()}])
|
-spec make_csr(proplist(), [{dNSName, bitstring()}])
|
||||||
-> {binary(), jose_jwk:key()}.
|
-> {binary(), jose_jwk:key()}.
|
||||||
make_csr(Attributes, SANs) ->
|
make_csr(Attributes, SANs) ->
|
||||||
Key = generate_key(),
|
Key = generate_key(),
|
||||||
@ -749,9 +744,9 @@ extension(SANs) ->
|
|||||||
extension_request(SANs) ->
|
extension_request(SANs) ->
|
||||||
#'AttributePKCS-10'{
|
#'AttributePKCS-10'{
|
||||||
type = ?'pkcs-9-at-extensionRequest',
|
type = ?'pkcs-9-at-extensionRequest',
|
||||||
values = [{'asn1_OPENTYPE',
|
values = [{'asn1_OPENTYPE',
|
||||||
public_key:der_encode(
|
public_key:der_encode(
|
||||||
'ExtensionRequest',
|
'ExtensionRequest',
|
||||||
[extension(SANs)])}]
|
[extension(SANs)])}]
|
||||||
}.
|
}.
|
||||||
|
|
||||||
@ -918,7 +913,7 @@ find_private_key_in_pem(Pem) ->
|
|||||||
JoseKey = jose_jwk:from_key(Key),
|
JoseKey = jose_jwk:from_key(Key),
|
||||||
{ok, JoseKey}
|
{ok, JoseKey}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec find_private_key_in_pem1([public_key:pki_asn1_type()],
|
-spec find_private_key_in_pem1([public_key:pki_asn1_type()],
|
||||||
[public_key:pem_entry()]) ->
|
[public_key:pem_entry()]) ->
|
||||||
@ -948,10 +943,10 @@ private_key_types() ->
|
|||||||
find_all_sub_domains(DomainName) ->
|
find_all_sub_domains(DomainName) ->
|
||||||
AllRoutes = ejabberd_router:get_all_routes(),
|
AllRoutes = ejabberd_router:get_all_routes(),
|
||||||
DomainLen = size(DomainName),
|
DomainLen = size(DomainName),
|
||||||
[Route || Route <- AllRoutes,
|
[Route || Route <- AllRoutes,
|
||||||
binary:longest_common_suffix([DomainName, Route])
|
binary:longest_common_suffix([DomainName, Route])
|
||||||
=:= DomainLen].
|
=:= DomainLen].
|
||||||
|
|
||||||
|
|
||||||
-spec is_error(_) -> boolean().
|
-spec is_error(_) -> boolean().
|
||||||
is_error({error, _}) -> true;
|
is_error({error, _}) -> true;
|
||||||
@ -981,13 +976,13 @@ data_get_account(Data) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
-spec data_set_account(acme_data(), {list(), url(), jose_jwk:key()}) -> acme_data().
|
-spec data_set_account(acme_data(), {list(), url(), jose_jwk:key()}) -> acme_data().
|
||||||
data_set_account(Data, {AccId, CAUrl, PrivateKey}) ->
|
data_set_account(Data, {AccId, CAUrl, PrivateKey}) ->
|
||||||
NewAcc = {account, #data_acc{id = AccId, ca_url = CAUrl, key = PrivateKey}},
|
NewAcc = {account, #data_acc{id = AccId, ca_url = CAUrl, key = PrivateKey}},
|
||||||
lists:keystore(account, 1, Data, NewAcc).
|
lists:keystore(account, 1, Data, NewAcc).
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Certificates
|
%% Certificates
|
||||||
%%
|
%%
|
||||||
|
|
||||||
-spec data_get_certificates(acme_data()) -> data_certs().
|
-spec data_get_certificates(acme_data()) -> data_certs().
|
||||||
data_get_certificates(Data) ->
|
data_get_certificates(Data) ->
|
||||||
@ -999,7 +994,7 @@ data_get_certificates(Data) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
-spec data_set_certificates(acme_data(), data_certs()) -> acme_data().
|
-spec data_set_certificates(acme_data(), data_certs()) -> acme_data().
|
||||||
data_set_certificates(Data, NewCerts) ->
|
data_set_certificates(Data, NewCerts) ->
|
||||||
lists:keystore(certs, 1, Data, {certs, NewCerts}).
|
lists:keystore(certs, 1, Data, {certs, NewCerts}).
|
||||||
|
|
||||||
%% ATM we preserve one certificate for each domain
|
%% ATM we preserve one certificate for each domain
|
||||||
@ -1053,7 +1048,7 @@ write_persistent(Data) ->
|
|||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("Error: ~p writing acme data file", [Reason]),
|
?ERROR_MSG("Error: ~p writing acme data file", [Reason]),
|
||||||
throw({error, Reason})
|
throw({error, Reason})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec create_persistent() -> ok | no_return().
|
-spec create_persistent() -> ok | no_return().
|
||||||
create_persistent() ->
|
create_persistent() ->
|
||||||
@ -1069,7 +1064,7 @@ create_persistent() ->
|
|||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("Error: ~p creating acme data file", [Reason]),
|
?ERROR_MSG("Error: ~p creating acme data file", [Reason]),
|
||||||
throw({error, Reason})
|
throw({error, Reason})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec write_account_persistent({list(), url(), jose_jwk:key()}) -> ok | no_return().
|
-spec write_account_persistent({list(), url(), jose_jwk:key()}) -> ok | no_return().
|
||||||
write_account_persistent({AccId, CAUrl, PrivateKey}) ->
|
write_account_persistent({AccId, CAUrl, PrivateKey}) ->
|
||||||
@ -1099,7 +1094,7 @@ remove_certificate_persistent(DataCert) ->
|
|||||||
NewData = data_remove_certificate(Data, DataCert),
|
NewData = data_remove_certificate(Data, DataCert),
|
||||||
ok = write_persistent(NewData).
|
ok = write_persistent(NewData).
|
||||||
|
|
||||||
-spec save_certificate({ok, bitstring(), binary()} | {error, _, _}) ->
|
-spec save_certificate({ok, bitstring(), binary()} | {error, _, _}) ->
|
||||||
{ok, bitstring(), saved} | {error, bitstring(), _}.
|
{ok, bitstring(), saved} | {error, bitstring(), _}.
|
||||||
save_certificate({error, _, _} = Error) ->
|
save_certificate({error, _, _} = Error) ->
|
||||||
Error;
|
Error;
|
||||||
@ -1123,13 +1118,12 @@ save_certificate({ok, DomainName, Cert}) ->
|
|||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
|
||||||
?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
|
|
||||||
{error, DomainName, saving}
|
{error, DomainName, saving}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec save_renewed_certificate({ok, bitstring(), _} | {error, _, _}) ->
|
-spec save_renewed_certificate({ok, bitstring(), _} | {error, _, _}) ->
|
||||||
{ok, bitstring(), _} | {error, bitstring(), _}.
|
{ok, bitstring(), _} | {error, bitstring(), _}.
|
||||||
save_renewed_certificate({error, _, _} = Error) ->
|
save_renewed_certificate({error, _, _} = Error) ->
|
||||||
Error;
|
Error;
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
-include("ejabberd_ctl.hrl").
|
-include("ejabberd_ctl.hrl").
|
||||||
-include("ejabberd_commands.hrl").
|
-include("ejabberd_commands.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-define(DEFAULT_VERSION, 1000000).
|
-define(DEFAULT_VERSION, 1000000).
|
||||||
|
|
||||||
@ -327,9 +328,9 @@ try_call_command(Args, Auth, AccessCommands, Version) ->
|
|||||||
catch
|
catch
|
||||||
throw:Error ->
|
throw:Error ->
|
||||||
{io_lib:format("~p", [Error]), ?STATUS_ERROR};
|
{io_lib:format("~p", [Error]), ?STATUS_ERROR};
|
||||||
A:Why ->
|
?EX_RULE(A, Why, Stack) ->
|
||||||
Stack = erlang:get_stacktrace(),
|
{io_lib:format("Problem '~p ~p' occurred executing the command.~nStacktrace: ~p",
|
||||||
{io_lib:format("Problem '~p ~p' occurred executing the command.~nStacktrace: ~p", [A, Why, Stack]), ?STATUS_ERROR}
|
[A, Why, ?EX_STACK(Stack)]), ?STATUS_ERROR}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType}
|
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType}
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
terminate/2]).
|
terminate/2]).
|
||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-record(state, {}).
|
-record(state, {}).
|
||||||
-type local_hook() :: { Seq :: integer(), Module :: atom(), Function :: atom()}.
|
-type local_hook() :: { Seq :: integer(), Module :: atom(), Function :: atom()}.
|
||||||
@ -129,14 +130,14 @@ delete_dist(Hook, Node, Module, Function, Seq) ->
|
|||||||
delete_dist(Hook, Host, Node, Module, Function, Seq) ->
|
delete_dist(Hook, Host, Node, Module, Function, Seq) ->
|
||||||
gen_server:call(ejabberd_hooks, {delete, Hook, Host, Node, Module, Function, Seq}).
|
gen_server:call(ejabberd_hooks, {delete, Hook, Host, Node, Module, Function, Seq}).
|
||||||
|
|
||||||
-spec delete_all_hooks() -> true.
|
-spec delete_all_hooks() -> true.
|
||||||
|
|
||||||
%% @doc Primarily for testing / instrumentation
|
%% @doc Primarily for testing / instrumentation
|
||||||
delete_all_hooks() ->
|
delete_all_hooks() ->
|
||||||
gen_server:call(ejabberd_hooks, {delete_all}).
|
gen_server:call(ejabberd_hooks, {delete_all}).
|
||||||
|
|
||||||
-spec get_handlers(atom(), binary() | global) -> [local_hook() | distributed_hook()].
|
-spec get_handlers(atom(), binary() | global) -> [local_hook() | distributed_hook()].
|
||||||
%% @doc Returns currently set handler for hook name
|
%% @doc Returns currently set handler for hook name
|
||||||
get_handlers(Hookname, Host) ->
|
get_handlers(Hookname, Host) ->
|
||||||
gen_server:call(ejabberd_hooks, {get_handlers, Hookname, Host}).
|
gen_server:call(ejabberd_hooks, {get_handlers, Hookname, Host}).
|
||||||
|
|
||||||
@ -264,7 +265,7 @@ handle_delete(Hook, Host, El) ->
|
|||||||
ok;
|
ok;
|
||||||
[] ->
|
[] ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
%% Func: handle_cast/2
|
%% Func: handle_cast/2
|
||||||
@ -379,15 +380,11 @@ safe_apply(Hook, Module, Function, Args) ->
|
|||||||
true ->
|
true ->
|
||||||
apply(Module, Function, Args)
|
apply(Module, Function, Args)
|
||||||
end
|
end
|
||||||
catch E:R when E /= exit; R /= normal ->
|
catch ?EX_RULE(E, R, St) when E /= exit; R /= normal ->
|
||||||
St = get_stacktrace(),
|
|
||||||
?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n"
|
?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n"
|
||||||
"** Reason = ~p~n"
|
"** Reason = ~p~n"
|
||||||
"** Arguments = ~p",
|
"** Arguments = ~p",
|
||||||
[Hook, Module, Function, length(Args),
|
[Hook, Module, Function, length(Args),
|
||||||
{E, R, St}, Args]),
|
{E, R, ?EX_STACK(St)}, Args]),
|
||||||
'EXIT'
|
'EXIT'
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_stacktrace() ->
|
|
||||||
[{Mod, Fun, Loc, Args} || {Mod, Fun, Args, Loc} <- erlang:get_stacktrace()].
|
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include_lib("stdlib/include/ms_transform.hrl").
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-record(state, {}).
|
-record(state, {}).
|
||||||
|
|
||||||
@ -70,10 +71,9 @@ start_link() ->
|
|||||||
-spec route(stanza()) -> any().
|
-spec route(stanza()) -> any().
|
||||||
route(Packet) ->
|
route(Packet) ->
|
||||||
try do_route(Packet)
|
try do_route(Packet)
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
||||||
[xmpp:pp(Packet), {E, {R, St}}])
|
[xmpp:pp(Packet), {E, {R, ?EX_STACK(St)}}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec route_iq(iq(), function()) -> ok.
|
-spec route_iq(iq(), function()) -> ok.
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
-define(NEED_RESET, [local_content, type]).
|
-define(NEED_RESET, [local_content, type]).
|
||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-record(state, {tables = #{} :: map(),
|
-record(state, {tables = #{} :: map(),
|
||||||
schema = [] :: [{atom(), [{atom(), any()}]}]}).
|
schema = [] :: [{atom(), [{atom(), any()}]}]}).
|
||||||
@ -385,8 +386,8 @@ do_transform(OldAttrs, Attrs, Old) ->
|
|||||||
transform_fun(Module, Name) ->
|
transform_fun(Module, Name) ->
|
||||||
fun(Obj) ->
|
fun(Obj) ->
|
||||||
try Module:transform(Obj)
|
try Module:transform(Obj)
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
StackTrace = erlang:get_stacktrace(),
|
StackTrace = ?EX_STACK(St),
|
||||||
?ERROR_MSG("Failed to transform Mnesia table ~s:~n"
|
?ERROR_MSG("Failed to transform Mnesia table ~s:~n"
|
||||||
"** Record: ~p~n"
|
"** Record: ~p~n"
|
||||||
"** Reason: ~p~n"
|
"** Reason: ~p~n"
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
-define(CALL_TIMEOUT, 60*1000). %% 60 seconds
|
-define(CALL_TIMEOUT, 60*1000). %% 60 seconds
|
||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-record(state, {connection :: pid() | undefined,
|
-record(state, {connection :: pid() | undefined,
|
||||||
num :: pos_integer(),
|
num :: pos_integer(),
|
||||||
@ -106,9 +107,9 @@ multi(F) ->
|
|||||||
{error, _} = Err -> Err;
|
{error, _} = Err -> Err;
|
||||||
Result -> get_result(Result)
|
Result -> get_result(Result)
|
||||||
end
|
end
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
erlang:erase(?TR_STACK),
|
erlang:erase(?TR_STACK),
|
||||||
erlang:raise(E, R, erlang:get_stacktrace())
|
erlang:raise(E, R, ?EX_STACK(St))
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
erlang:error(nested_transaction)
|
erlang:error(nested_transaction)
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_router.hrl").
|
-include("ejabberd_router.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-callback init() -> any().
|
-callback init() -> any().
|
||||||
-callback register_route(binary(), binary(), local_hint(),
|
-callback register_route(binary(), binary(), local_hint(),
|
||||||
@ -90,10 +91,9 @@ start_link() ->
|
|||||||
-spec route(stanza()) -> ok.
|
-spec route(stanza()) -> ok.
|
||||||
route(Packet) ->
|
route(Packet) ->
|
||||||
try do_route(Packet)
|
try do_route(Packet)
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
||||||
[xmpp:pp(Packet), {E, {R, St}}])
|
[xmpp:pp(Packet), {E, {R, ?EX_STACK(St)}}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec route(jid(), jid(), xmlel() | stanza()) -> ok.
|
-spec route(jid(), jid(), xmlel() | stanza()) -> ok.
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_sql_pt.hrl").
|
-include("ejabberd_sql_pt.hrl").
|
||||||
-include("ejabberd_router.hrl").
|
-include("ejabberd_router.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
@ -121,12 +122,11 @@ row_to_route(Domain, {ServerHost, NodeS, PidS, LocalHintS} = Row) ->
|
|||||||
local_hint = dec_local_hint(LocalHintS)}]
|
local_hint = dec_local_hint(LocalHintS)}]
|
||||||
catch _:{bad_node, _} ->
|
catch _:{bad_node, _} ->
|
||||||
[];
|
[];
|
||||||
E:R ->
|
?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to decode row from 'route' table:~n"
|
?ERROR_MSG("failed to decode row from 'route' table:~n"
|
||||||
"Row = ~p~n"
|
"Row = ~p~n"
|
||||||
"Domain = ~s~n"
|
"Domain = ~s~n"
|
||||||
"Reason = ~p",
|
"Reason = ~p",
|
||||||
[Row, Domain, {E, {R, St}}]),
|
[Row, Domain, {E, {R, ?EX_STACK(St)}}]),
|
||||||
[]
|
[]
|
||||||
end.
|
end.
|
||||||
|
@ -55,12 +55,10 @@
|
|||||||
transform_options/1, opt_type/1]).
|
transform_options/1, opt_type/1]).
|
||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-include("ejabberd_commands.hrl").
|
-include("ejabberd_commands.hrl").
|
||||||
|
|
||||||
-include_lib("public_key/include/public_key.hrl").
|
-include_lib("public_key/include/public_key.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
|
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
|
||||||
|
|
||||||
@ -94,10 +92,9 @@ start_link() ->
|
|||||||
|
|
||||||
route(Packet) ->
|
route(Packet) ->
|
||||||
try do_route(Packet)
|
try do_route(Packet)
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
||||||
[xmpp:pp(Packet), {E, {R, St}}])
|
[xmpp:pp(Packet), {E, {R, ?EX_STACK(St)}}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
clean_temporarily_blocked_table() ->
|
clean_temporarily_blocked_table() ->
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
|
|
||||||
-include("ejabberd_commands.hrl").
|
-include("ejabberd_commands.hrl").
|
||||||
-include("ejabberd_sm.hrl").
|
-include("ejabberd_sm.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-callback init() -> ok | {error, any()}.
|
-callback init() -> ok | {error, any()}.
|
||||||
-callback set_session(#session{}) -> ok | {error, any()}.
|
-callback set_session(#session{}) -> ok | {error, any()}.
|
||||||
@ -140,11 +141,10 @@ route(Packet) ->
|
|||||||
?DEBUG("hook dropped stanza:~n~s", [xmpp:pp(Packet)]);
|
?DEBUG("hook dropped stanza:~n~s", [xmpp:pp(Packet)]);
|
||||||
Packet1 ->
|
Packet1 ->
|
||||||
try do_route(Packet1), ok
|
try do_route(Packet1), ok
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
|
||||||
[xmpp:pp(Packet1),
|
[xmpp:pp(Packet1),
|
||||||
{E, {R, St}}])
|
{E, {R, ?EX_STACK(St)}}])
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_sql_pt.hrl").
|
-include("ejabberd_sql_pt.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-record(state,
|
-record(state,
|
||||||
{db_ref = self() :: pid(),
|
{db_ref = self() :: pid(),
|
||||||
@ -516,24 +517,26 @@ outer_transaction(F, NRestarts, _Reason) ->
|
|||||||
end,
|
end,
|
||||||
sql_query_internal([<<"begin;">>]),
|
sql_query_internal([<<"begin;">>]),
|
||||||
put(?NESTING_KEY, PreviousNestingLevel + 1),
|
put(?NESTING_KEY, PreviousNestingLevel + 1),
|
||||||
Result = (catch F()),
|
try F() of
|
||||||
put(?NESTING_KEY, PreviousNestingLevel),
|
Res ->
|
||||||
case Result of
|
sql_query_internal([<<"commit;">>]),
|
||||||
{aborted, Reason} when NRestarts > 0 ->
|
{atomic, Res}
|
||||||
sql_query_internal([<<"rollback;">>]),
|
catch
|
||||||
outer_transaction(F, NRestarts - 1, Reason);
|
?EX_RULE(throw, {aborted, Reason}, _) when NRestarts > 0 ->
|
||||||
{aborted, Reason} when NRestarts =:= 0 ->
|
sql_query_internal([<<"rollback;">>]),
|
||||||
?ERROR_MSG("SQL transaction restarts exceeded~n** "
|
outer_transaction(F, NRestarts - 1, Reason);
|
||||||
"Restarts: ~p~n** Last abort reason: "
|
?EX_RULE(throw, {aborted, Reason}, Stack) when NRestarts =:= 0 ->
|
||||||
"~p~n** Stacktrace: ~p~n** When State "
|
?ERROR_MSG("SQL transaction restarts exceeded~n** "
|
||||||
"== ~p",
|
"Restarts: ~p~n** Last abort reason: "
|
||||||
[?MAX_TRANSACTION_RESTARTS, Reason,
|
"~p~n** Stacktrace: ~p~n** When State "
|
||||||
erlang:get_stacktrace(), get(?STATE_KEY)]),
|
"== ~p",
|
||||||
sql_query_internal([<<"rollback;">>]),
|
[?MAX_TRANSACTION_RESTARTS, Reason,
|
||||||
{aborted, Reason};
|
?EX_STACK(Stack), get(?STATE_KEY)]),
|
||||||
{'EXIT', Reason} ->
|
sql_query_internal([<<"rollback;">>]),
|
||||||
sql_query_internal([<<"rollback;">>]), {aborted, Reason};
|
{aborted, Reason};
|
||||||
Res -> sql_query_internal([<<"commit;">>]), {atomic, Res}
|
?EX_RULE(exit, Reason, _) ->
|
||||||
|
sql_query_internal([<<"rollback;">>]),
|
||||||
|
{aborted, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
execute_bloc(F) ->
|
execute_bloc(F) ->
|
||||||
@ -599,10 +602,9 @@ sql_query_internal(#sql_query{} = Query) ->
|
|||||||
{error, <<"killed">>};
|
{error, <<"killed">>};
|
||||||
exit:{normal, _} ->
|
exit:{normal, _} ->
|
||||||
{error, <<"terminated unexpectedly">>};
|
{error, <<"terminated unexpectedly">>};
|
||||||
Class:Reason ->
|
?EX_RULE(Class, Reason, Stack) ->
|
||||||
ST = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("Internal error while processing SQL query: ~p",
|
?ERROR_MSG("Internal error while processing SQL query: ~p",
|
||||||
[{Class, Reason, ST}]),
|
[{Class, Reason, ?EX_STACK(Stack)}]),
|
||||||
{error, <<"internal error">>}
|
{error, <<"internal error">>}
|
||||||
end,
|
end,
|
||||||
check_error(Res, Query);
|
check_error(Res, Query);
|
||||||
@ -737,12 +739,11 @@ sql_query_format_res({selected, _, Rows}, SQLQuery) ->
|
|||||||
try
|
try
|
||||||
[(SQLQuery#sql_query.format_res)(Row)]
|
[(SQLQuery#sql_query.format_res)(Row)]
|
||||||
catch
|
catch
|
||||||
Class:Reason ->
|
?EX_RULE(Class, Reason, Stack) ->
|
||||||
ST = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("Error while processing "
|
?ERROR_MSG("Error while processing "
|
||||||
"SQL query result: ~p~n"
|
"SQL query result: ~p~n"
|
||||||
"row: ~p",
|
"row: ~p",
|
||||||
[{Class, Reason, ST}, Row]),
|
[{Class, Reason, ?EX_STACK(Stack)}, Row]),
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
end, Rows),
|
end, Rows),
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("translate.hrl").
|
-include("translate.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-type component() :: ejabberd_sm | ejabberd_local.
|
-type component() :: ejabberd_sm | ejabberd_local.
|
||||||
|
|
||||||
@ -113,10 +114,9 @@ process_iq(_Host, Module, Function, IQ) ->
|
|||||||
ejabberd_router:route(ResIQ);
|
ejabberd_router:route(ResIQ);
|
||||||
ignore ->
|
ignore ->
|
||||||
ok
|
ok
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to process iq:~n~s~nReason = ~p",
|
?ERROR_MSG("failed to process iq:~n~s~nReason = ~p",
|
||||||
[xmpp:pp(IQ), {E, {R, St}}]),
|
[xmpp:pp(IQ), {E, {R, ?EX_STACK(St)}}]),
|
||||||
Txt = <<"Module failed to handle the query">>,
|
Txt = <<"Module failed to handle the query">>,
|
||||||
Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
|
Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
|
||||||
ejabberd_router:route_error(IQ, Err)
|
ejabberd_router:route_error(IQ, Err)
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include_lib("stdlib/include/ms_transform.hrl").
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-record(ejabberd_module,
|
-record(ejabberd_module,
|
||||||
{module_host = {undefined, <<"">>} :: {atom(), binary()},
|
{module_host = {undefined, <<"">>} :: {atom(), binary()},
|
||||||
@ -217,8 +218,8 @@ start_module(Host, Module, Opts0, Order, NeedValidation) ->
|
|||||||
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
||||||
Err -> erlang:error({bad_return, Module, Err})
|
Err -> erlang:error({bad_return, Module, Err})
|
||||||
end
|
end
|
||||||
catch Class:Reason ->
|
catch ?EX_RULE(Class, Reason, Stack) ->
|
||||||
StackTrace = erlang:get_stacktrace(),
|
StackTrace = ?EX_STACK(Stack),
|
||||||
ets:delete(ejabberd_modules, {Module, Host}),
|
ets:delete(ejabberd_modules, {Module, Host}),
|
||||||
ErrorText = format_module_error(
|
ErrorText = format_module_error(
|
||||||
Module, start, 2,
|
Module, start, 2,
|
||||||
@ -282,8 +283,8 @@ reload_module(Host, Module, NewOpts, OldOpts, Order) ->
|
|||||||
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
||||||
Err -> erlang:error({bad_return, Module, Err})
|
Err -> erlang:error({bad_return, Module, Err})
|
||||||
end
|
end
|
||||||
catch Class:Reason ->
|
catch ?EX_RULE(Class, Reason, Stack) ->
|
||||||
StackTrace = erlang:get_stacktrace(),
|
StackTrace = ?EX_STACK(Stack),
|
||||||
ErrorText = format_module_error(
|
ErrorText = format_module_error(
|
||||||
Module, reload, 3,
|
Module, reload, 3,
|
||||||
NewOpts, Class, Reason,
|
NewOpts, Class, Reason,
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_http.hrl").
|
-include("ejabberd_http.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-define(DEFAULT_API_VERSION, 0).
|
-define(DEFAULT_API_VERSION, 0).
|
||||||
|
|
||||||
@ -192,9 +193,8 @@ process([Call], #request{method = 'POST', data = Data, ip = IPPort} = Req) ->
|
|||||||
_:{error,{_,invalid_json}} = _Err ->
|
_:{error,{_,invalid_json}} = _Err ->
|
||||||
?DEBUG("Bad Request: ~p", [_Err]),
|
?DEBUG("Bad Request: ~p", [_Err]),
|
||||||
badrequest_response(<<"Invalid JSON input">>);
|
badrequest_response(<<"Invalid JSON input">>);
|
||||||
_:_Error ->
|
?EX_RULE(_Class, _Error, Stack) ->
|
||||||
St = erlang:get_stacktrace(),
|
?DEBUG("Bad Request: ~p ~p", [_Error, ?EX_STACK(Stack)]),
|
||||||
?DEBUG("Bad Request: ~p ~p", [_Error, St]),
|
|
||||||
badrequest_response()
|
badrequest_response()
|
||||||
end;
|
end;
|
||||||
process([Call], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) ->
|
process([Call], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) ->
|
||||||
@ -210,9 +210,8 @@ process([Call], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) ->
|
|||||||
%% TODO We need to refactor to remove redundant error return formatting
|
%% TODO We need to refactor to remove redundant error return formatting
|
||||||
throw:{error, unknown_command} ->
|
throw:{error, unknown_command} ->
|
||||||
json_format({404, 44, <<"Command not found.">>});
|
json_format({404, 44, <<"Command not found.">>});
|
||||||
_:_Error ->
|
?EX_RULE(_, _Error, Stack) ->
|
||||||
St = erlang:get_stacktrace(),
|
?DEBUG("Bad Request: ~p ~p", [_Error, ?EX_STACK(Stack)]),
|
||||||
?DEBUG("Bad Request: ~p ~p", [_Error, St]),
|
|
||||||
badrequest_response()
|
badrequest_response()
|
||||||
end;
|
end;
|
||||||
process([_Call], #request{method = 'OPTIONS', data = <<>>}) ->
|
process([_Call], #request{method = 'OPTIONS', data = <<>>}) ->
|
||||||
@ -302,9 +301,8 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
|
|||||||
{400, misc:atom_to_binary(Error)};
|
{400, misc:atom_to_binary(Error)};
|
||||||
throw:Msg when is_list(Msg); is_binary(Msg) ->
|
throw:Msg when is_list(Msg); is_binary(Msg) ->
|
||||||
{400, iolist_to_binary(Msg)};
|
{400, iolist_to_binary(Msg)};
|
||||||
_Error ->
|
?EX_RULE(Class, Error, Stack) ->
|
||||||
St = erlang:get_stacktrace(),
|
?ERROR_MSG("REST API Error: ~p:~p ~p", [Class, Error, ?EX_STACK(Stack)]),
|
||||||
?ERROR_MSG("REST API Error: ~p ~p", [_Error, St]),
|
|
||||||
{500, <<"internal_error">>}
|
{500, <<"internal_error">>}
|
||||||
end;
|
end;
|
||||||
{error, Msg} ->
|
{error, Msg} ->
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("translate.hrl").
|
-include("translate.hrl").
|
||||||
-include("mod_muc_room.hrl").
|
-include("mod_muc_room.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-define(MAX_USERS_DEFAULT_LIST,
|
-define(MAX_USERS_DEFAULT_LIST,
|
||||||
[5, 10, 20, 30, 50, 100, 200, 500, 1000, 2000, 5000]).
|
[5, 10, 20, 30, 50, 100, 200, 500, 1000, 2000, 5000]).
|
||||||
@ -2765,7 +2766,7 @@ process_item_change(Item, SD, UJID) ->
|
|||||||
maybe_send_affiliation(JID, A, SD1),
|
maybe_send_affiliation(JID, A, SD1),
|
||||||
SD1
|
SD1
|
||||||
end
|
end
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
FromSuffix = case UJID of
|
FromSuffix = case UJID of
|
||||||
#jid{} ->
|
#jid{} ->
|
||||||
JidString = jid:encode(UJID),
|
JidString = jid:encode(UJID),
|
||||||
@ -2773,9 +2774,8 @@ process_item_change(Item, SD, UJID) ->
|
|||||||
undefined ->
|
undefined ->
|
||||||
<<"">>
|
<<"">>
|
||||||
end,
|
end,
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to set item ~p~s: ~p",
|
?ERROR_MSG("failed to set item ~p~s: ~p",
|
||||||
[Item, FromSuffix, {E, {R, St}}]),
|
[Item, FromSuffix, {E, {R, ?EX_STACK(St)}}]),
|
||||||
{error, xmpp:err_internal_server_error()}
|
{error, xmpp:err_internal_server_error()}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -53,14 +53,11 @@
|
|||||||
depends/2]).
|
depends/2]).
|
||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
|
|
||||||
-include("ejabberd_http.hrl").
|
-include("ejabberd_http.hrl").
|
||||||
|
|
||||||
-include("ejabberd_web_admin.hrl").
|
-include("ejabberd_web_admin.hrl").
|
||||||
|
-include("ejabberd_stacktrace.hrl").
|
||||||
|
|
||||||
-define(ROSTER_CACHE, roster_cache).
|
-define(ROSTER_CACHE, roster_cache).
|
||||||
-define(ROSTER_ITEM_CACHE, roster_item_cache).
|
-define(ROSTER_ITEM_CACHE, roster_item_cache).
|
||||||
@ -320,10 +317,9 @@ process_iq_get(#iq{to = To, lang = Lang,
|
|||||||
#roster_query{items = Items,
|
#roster_query{items = Items,
|
||||||
ver = Version}
|
ver = Version}
|
||||||
end)
|
end)
|
||||||
catch E:R ->
|
catch ?EX_RULE(E, R, St) ->
|
||||||
St = erlang:get_stacktrace(),
|
|
||||||
?ERROR_MSG("failed to process roster get for ~s: ~p",
|
?ERROR_MSG("failed to process roster get for ~s: ~p",
|
||||||
[jid:encode(To), {E, {R, St}}]),
|
[jid:encode(To), {E, {R, ?EX_STACK(St)}}]),
|
||||||
Txt = <<"Roster module has failed">>,
|
Txt = <<"Roster module has failed">>,
|
||||||
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
|
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user