Check presence of some files during option validation

This commit is contained in:
Evgeniy Khramtsov 2017-05-12 09:34:57 +03:00
parent 9fe16a29e1
commit d3c8fb7705
14 changed files with 56 additions and 77 deletions

View File

@ -904,10 +904,10 @@ transform_listen_option(Opt, Opts) ->
(resource_conflict) -> fun((resource_conflict()) -> resource_conflict());
(disable_sasl_mechanisms) -> fun((binary() | [binary()]) -> [binary()]);
(atom()) -> [atom()].
opt_type(c2s_certfile) -> fun iolist_to_binary/1;
opt_type(c2s_ciphers) -> fun iolist_to_binary/1;
opt_type(c2s_dhfile) -> fun iolist_to_binary/1;
opt_type(c2s_cafile) -> fun iolist_to_binary/1;
opt_type(c2s_certfile) -> fun misc:try_read_file/1;
opt_type(c2s_ciphers) -> fun misc:try_read_file/1;
opt_type(c2s_dhfile) -> fun misc:try_read_file/1;
opt_type(c2s_cafile) -> fun misc:try_read_file/1;
opt_type(c2s_protocol_options) ->
fun (Options) -> str:join(Options, <<"|">>) end;
opt_type(c2s_tls_compression) ->

View File

@ -1417,7 +1417,7 @@ opt_type(cache_life_time) ->
(unlimited) -> infinity
end;
opt_type(domain_certfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
opt_type(shared_key) ->
fun iolist_to_binary/1;
opt_type(node_start) ->

View File

@ -926,11 +926,11 @@ opt_type(_) -> [trusted_proxies].
listen_opt_type(tls) ->
fun(B) when is_boolean(B) -> B end;
listen_opt_type(certfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
listen_opt_type(ciphers) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
listen_opt_type(dhfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
listen_opt_type(protocol_options) ->
fun(Options) -> str:join(Options, <<"|">>) end;
listen_opt_type(tls_compression) ->

View File

@ -90,14 +90,7 @@ start(Port, Module, Opts) ->
%% @spec(Port, Module, Opts) -> {ok, Pid} | {error, ErrorMessage}
start_dependent(Port, Module, Opts) ->
try check_listener_options(Opts) of
ok ->
proc_lib:start_link(?MODULE, init, [Port, Module, Opts])
catch
throw:{error, Error} ->
?ERROR_MSG(Error, []),
{error, Error}
end.
proc_lib:start_link(?MODULE, init, [Port, Module, Opts]).
init(PortIP, Module, RawOpts) ->
{Port, IPT, IPS, IPV, Proto, OptsClean} = parse_listener_portip(PortIP, RawOpts),
@ -456,48 +449,6 @@ config_reloaded() ->
%%%
%%% Check options
%%%
check_listener_options(Opts) ->
case includes_deprecated_ssl_option(Opts) of
false -> ok;
true ->
Error = "There is a problem with your ejabberd configuration file: "
"the option 'ssl' for listening sockets is no longer available."
" To get SSL encryption use the option 'tls'.",
throw({error, Error})
end,
case certfile_readable(Opts) of
true -> ok;
{false, Path} ->
ErrorText = "There is a problem in the configuration: "
"the specified file is not readable: ",
throw({error, ErrorText ++ Path})
end,
ok.
%% Parse the options of the socket,
%% and return if the deprecated option 'ssl' is included
%% @spec (Opts) -> true | false
includes_deprecated_ssl_option(Opts) ->
case lists:keysearch(ssl, 1, Opts) of
{value, {ssl, _SSLOpts}} ->
true;
_ ->
lists:member(ssl, Opts)
end.
%% @spec (Opts) -> true | {false, Path::string()}
certfile_readable(Opts) ->
case proplists:lookup(certfile, Opts) of
none -> true;
{certfile, Path} ->
PathS = binary_to_list(Path),
case ejabberd_config:is_file_readable(PathS) of
true -> true;
false -> {false, PathS}
end
end.
get_proto(Opts) ->
case proplists:get_value(proto, Opts) of
undefined ->

View File

@ -709,10 +709,10 @@ opt_type(route_subdomains) ->
end;
opt_type(s2s_access) ->
fun acl:access_rules_validator/1;
opt_type(s2s_certfile) -> fun iolist_to_binary/1;
opt_type(s2s_ciphers) -> fun iolist_to_binary/1;
opt_type(s2s_dhfile) -> fun iolist_to_binary/1;
opt_type(s2s_cafile) -> fun iolist_to_binary/1;
opt_type(s2s_certfile) -> fun misc:try_read_file/1;
opt_type(s2s_ciphers) -> fun misc:try_read_file/1;
opt_type(s2s_dhfile) -> fun misc:try_read_file/1;
opt_type(s2s_cafile) -> fun misc:try_read_file/1;
opt_type(s2s_protocol_options) ->
fun (Options) -> str:join(Options, <<"|">>) end;
opt_type(s2s_tls_compression) ->

View File

@ -276,10 +276,10 @@ transform_listen_option(Opt, Opts) ->
(atom()) -> [atom()].
listen_opt_type(access) -> fun acl:access_rules_validator/1;
listen_opt_type(shaper_rule) -> fun acl:shaper_rules_validator/1;
listen_opt_type(certfile) -> fun iolist_to_binary/1;
listen_opt_type(ciphers) -> fun iolist_to_binary/1;
listen_opt_type(dhfile) -> fun iolist_to_binary/1;
listen_opt_type(cafile) -> fun iolist_to_binary/1;
listen_opt_type(certfile) -> fun misc:try_read_file/1;
listen_opt_type(ciphers) -> fun misc:try_read_file/1;
listen_opt_type(dhfile) -> fun misc:try_read_file/1;
listen_opt_type(cafile) -> fun misc:try_read_file/1;
listen_opt_type(protocol_options) ->
fun(Options) -> str:join(Options, <<"|">>) end;
listen_opt_type(tls_compression) -> fun(B) when is_boolean(B) -> B end;

View File

@ -47,7 +47,7 @@ socket_type() ->
raw.
listen_opt_type(certfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
listen_opt_type(tls) ->
fun(B) when is_boolean(B) -> B end;
listen_opt_type(_) ->

View File

@ -1104,8 +1104,8 @@ opt_type(sql_server) -> fun iolist_to_binary/1;
opt_type(sql_username) -> fun iolist_to_binary/1;
opt_type(sql_ssl) -> fun(B) when is_boolean(B) -> B end;
opt_type(sql_ssl_verify) -> fun(B) when is_boolean(B) -> B end;
opt_type(sql_ssl_certfile) -> fun iolist_to_binary/1;
opt_type(sql_ssl_cafile) -> fun iolist_to_binary/1;
opt_type(sql_ssl_certfile) -> fun misc:try_read_file/1;
opt_type(sql_ssl_cafile) -> fun misc:try_read_file/1;
opt_type(sql_query_timeout) ->
fun (I) when is_integer(I), I > 0 -> I end;
opt_type(sql_connect_timeout) ->

View File

@ -114,7 +114,7 @@ listen_opt_type(auth_realm) ->
listen_opt_type(tls) ->
fun(B) when is_boolean(B) -> B end;
listen_opt_type(certfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
listen_opt_type(turn_min_port) ->
fun(P) when is_integer(P), P > 0, P =< 65535 -> P end;
listen_opt_type(turn_max_port) ->

View File

@ -367,7 +367,7 @@ opt_type(ldap_rootdn) -> fun iolist_to_binary/1;
opt_type(ldap_servers) ->
fun (L) -> [iolist_to_binary(H) || H <- L] end;
opt_type(ldap_tls_cacertfile) ->
fun(S) -> binary_to_list(iolist_to_binary(S)) end;
fun(S) -> binary_to_list(misc:try_read_file(S)) end;
opt_type(ldap_tls_depth) ->
fun (I) when is_integer(I), I >= 0 -> I end;
opt_type(ldap_tls_verify) ->

View File

@ -33,7 +33,11 @@
hex_to_bin/1, hex_to_base64/1, expand_keyword/3,
atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1,
l2i/1, i2l/1, i2l/2, expr_to_term/1, term_to_expr/1,
encode_pid/1, decode_pid/2, compile_exprs/2, join_atoms/2]).
encode_pid/1, decode_pid/2, compile_exprs/2, join_atoms/2,
try_read_file/1]).
-include("logger.hrl").
-include_lib("kernel/include/file.hrl").
%%%===================================================================
%%% API
@ -241,6 +245,30 @@ compile_exprs(Mod, Exprs) ->
join_atoms(Atoms, Sep) ->
str:join([io_lib:format("~p", [A]) || A <- Atoms], Sep).
%% @doc Checks if the file is readable and converts its name to binary.
%% Fails with `badarg` otherwise. The function is intended for usage
%% in configuration validators only.
-spec try_read_file(file:filename_all()) -> binary().
try_read_file(Path) ->
Res = case file:read_file_info(Path) of
{ok, #file_info{type = Type, access = Access}} ->
case {Type, Access} of
{regular, read} -> ok;
{regular, read_write} -> ok;
{regular, _} -> {error, file:format_error(eaccess)};
_ -> {error, "not a regular file"}
end;
{error, Why} ->
{error, file:format_error(Why)}
end,
case Res of
ok ->
iolist_to_binary(Path);
{error, Reason} ->
?ERROR_MSG("Failed to read ~s: ~s", [Path, Reason]),
erlang:error(badarg)
end.
%%%===================================================================
%%% Internal functions
%%%===================================================================

View File

@ -1170,7 +1170,7 @@ has_no_permanent_store_hint(Packet) ->
mod_opt_type(access_log) ->
fun acl:access_rules_validator/1;
mod_opt_type(cssfile) -> fun iolist_to_binary/1;
mod_opt_type(cssfile) -> fun misc:try_read_file/1;
mod_opt_type(dirname) ->
fun (room_jid) -> room_jid;
(room_name) -> room_name

View File

@ -603,9 +603,9 @@ mod_opt_type(ldap_rootdn) -> fun iolist_to_binary/1;
mod_opt_type(ldap_servers) ->
fun (L) -> [iolist_to_binary(H) || H <- L] end;
mod_opt_type(ldap_tls_cacertfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
mod_opt_type(ldap_tls_certfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
mod_opt_type(ldap_tls_depth) ->
fun (I) when is_integer(I), I >= 0 -> I end;
mod_opt_type(ldap_tls_verify) ->

View File

@ -467,9 +467,9 @@ mod_opt_type(ldap_rootdn) -> fun iolist_to_binary/1;
mod_opt_type(ldap_servers) ->
fun (L) -> [iolist_to_binary(H) || H <- L] end;
mod_opt_type(ldap_tls_cacertfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
mod_opt_type(ldap_tls_certfile) ->
fun iolist_to_binary/1;
fun misc:try_read_file/1;
mod_opt_type(ldap_tls_depth) ->
fun (I) when is_integer(I), I >= 0 -> I end;
mod_opt_type(ldap_tls_verify) ->