Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of store_type/1 in auth backends #2254

Merged
merged 4 commits into from
Apr 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions big_tests/tests/login_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ end_per_suite(Config) ->

init_per_group(GroupName, Config) when
GroupName == login_scram; GroupName == login_scram_store_plain ->
case get_store_type() of
external ->
{skip, "external store type requires plain password"};
_ ->
case supports_password_type(scram) of
false ->
{skip, "scram password type not supported"};
true ->
config_password_format(GroupName),
Config2 = escalus:create_users(Config, escalus:get_users([alice, bob])),
assert_password_format(GroupName, Config2)
Expand All @@ -96,14 +96,21 @@ end_per_group(login_scram, Config) ->
end_per_group(_GroupName, Config) ->
escalus:delete_users(Config, escalus:get_users([alice, bob])).

init_per_testcase(DigestOrScram, Config) when
DigestOrScram =:= log_one_digest; DigestOrScram =:= log_non_existent_digest;
DigestOrScram =:= log_one_scram; DigestOrScram =:= log_non_existent_scram ->
case get_store_type() of
external ->
{skip, "external store type requires plain password"};
_ ->
escalus:init_per_testcase(DigestOrScram, Config)
init_per_testcase(CaseName, Config) when
CaseName =:= log_one_digest; CaseName =:= log_non_existent_digest ->
case supports_password_type(digest) of
false ->
{skip, "digest password type not supported"};
true ->
escalus:init_per_testcase(CaseName, Config)
end;
init_per_testcase(CaseName, Config) when
CaseName =:= log_one_scram; CaseName =:= log_non_existent_scram ->
case supports_password_type(scram) of
false ->
{skip, "scram password type not supported"};
true ->
escalus:init_per_testcase(CaseName, Config)
end;
init_per_testcase(message_zlib_limit, Config) ->
Listeners = [Listener
Expand Down Expand Up @@ -206,10 +213,10 @@ message_zlib_limit(Config) ->
%% Helpers
%%--------------------------------------------------------------------

get_store_type() ->
supports_password_type(PasswordType) ->
XMPPDomain = escalus_ejabberd:unify_str_arg(
ct:get_config({hosts, mim, domain})),
rpc(mim(), ejabberd_auth, store_type, [XMPPDomain]).
rpc(mim(), ejabberd_auth, supports_password_type, [XMPPDomain, PasswordType]).

set_store_password(Type) ->
XMPPDomain = escalus_ejabberd:unify_str_arg(
Expand Down
15 changes: 3 additions & 12 deletions big_tests/tests/oauth_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,9 @@ init_per_group(GroupName, Config0) ->
commands -> ejabberd_node_utils:init(Config0);
_ -> Config0
end,
case get_auth_method() of
external ->
{skip, "external authentication requires plain password"};
_ ->
config_password_format(GroupName),
Config2 = escalus:create_users(Config, escalus:get_users([bob, alice])),
assert_password_format(GroupName, Config2)
end.
config_password_format(GroupName),
Config2 = escalus:create_users(Config, escalus:get_users([bob, alice])),
assert_password_format(GroupName, Config2).

end_per_group(cleanup, Config) ->
escalus:delete_users(Config, escalus:get_users([alice]));
Expand Down Expand Up @@ -360,10 +355,6 @@ extract_tokens(#xmlel{name = <<"iq">>, children = [#xmlel{name = <<"items">>} =
RTD = exml_query:path(Items, [{element, <<"refresh_token">>}, cdata]),
{base64:decode(ATD), base64:decode(RTD)}.

get_auth_method() ->
XMPPDomain = escalus_ejabberd:unify_str_arg(ct:get_config({hosts, mim, domain})),
rpc(mim(), ejabberd_auth, store_type, [XMPPDomain]).

set_store_password(Type) ->
XMPPDomain = escalus_ejabberd:unify_str_arg(ct:get_config({hosts, mim, domain})),
AuthOpts = rpc(mim(), ejabberd_config, get_local_option, [{auth_opts, XMPPDomain}]),
Expand Down
26 changes: 22 additions & 4 deletions doc/Advanced-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ Retaining the default layout is recommended so that the experienced MongooseIM u
### Authentication

* **auth_method** (local)
* **Description:** Chooses an authentication module or a list of modules. Modules from a list are queried one after another until one of them replies positively.
* **Valid values:** `internal` (Mnesia), `rdbms`, `external`, `anonymous`, `ldap`, `jwt`, `riak`, `http`
* **Warning:** `external`, `jwt` and `ldap` work only with `PLAIN` SASL mechanism.
* **Description:** Chooses an authentication module or a list of modules. Modules from the list are queried one after another until one of them replies positively.
* **Valid values:** `internal` (Mnesia), `rdbms`, `external`, `anonymous`, `ldap`, `jwt`, `riak`, `http`, `pki`
* **Warning:** Authentication backends support only specific SASL mechanisms, see [auth backends capabilities](#authentication-backend-capabilities).
* **Examples:** `rdbms`, `[internal, anonymous]`

* **auth_opts** (local)
Expand All @@ -213,7 +213,7 @@ Retaining the default layout is recommended so that the experienced MongooseIM u

* **sasl_mechanisms** (local)
* **Description:** Specifies a list of allowed SASL mechanisms. It affects the methods announced during stream negotiation and is enforced eventually (user can't pick mechanism not listed here but available in the source code).
* **Warning:** This list is still filtered by auth backends capabilities, e.g. LDAP authentication requires a password provided via SASL PLAIN.
* **Warning:** This list is still filtered by [auth backends capabilities](#authentication-backend-capabilities)
* **Valid values:** `cyrsasl_plain, cyrsasl_digest, cyrsasl_scram, cyrsasl_anonymous, cyrsasl_oauth, cyrsasl_external`
* **Default:** `[cyrsasl_plain, cyrsasl_digest, cyrsasl_scram, cyrsasl_anonymous, cyrsasl_oauth, cyrsasl_external]`
* **Examples:** `[cyrsasl_plain]`, `[cyrsasl_anonymous, cyrsasl_scram]`
Expand All @@ -223,6 +223,24 @@ Retaining the default layout is recommended so that the experienced MongooseIM u
* **Syntax:** `{extauth_instances, Count}.`
* **Default:** 1

#### Authentication backend capabilities

The table below shows the supported SASL mechanisms for each authentication backend module.

| | cyrsasl<br>plain | cyrsasl<br>digest | cyrsasl<br>scram | cyrsasl<br>anonymous | cyrsasl<br>external |
|-----------|:----------------:|:-----------------:|:----------------:|:--------------------:|:-------------------:|
| internal | x | x | x | | |
| rdbms | x | x | x | | |
| external | x | | | | |
| anonymous | x | x | x | x | |
| ldap | x | | | | |
| jwt | x | | | | |
| riak | x | x | x | | |
| http | x | x | x | | |
| pki | | | | | x |

`cyrsasl_oauth` does not use the auth backends at all and requires the `mod_auth_token` module enabled instead.

### Outgoing connections setup

* **outgoing_pools** (local)
Expand Down
12 changes: 0 additions & 12 deletions doc/authentication-methods/client-certificate.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,6 @@ For the details please refer to [XEP-0178 Best Practices for Use of SASL EXTERNA
Please modify [`auth_opts` option](../Advanced-configuration.md#authentication) in MongooseIM's config file to include proper item.
Also, [`pki` backend](../authentication-backends/PKI-authentication-module.md) is recommended for `SASL EXTERNAL`.

### WARNING!

Some authentication backends may enforce `plain` password storage format, which automatically disables `SASL EXTERNAL`.
Below you may find a list of backends that are safe to use with `cyrsasl_external` mechanism.

* `pki`
* `anonymous`
* `http` **without** `{is_external, true}` option
* `internal`
* `rdbms`
* `riak`

### Self-signed certificates

By default MongooseIM doesn't accept self-signed certs for the SASL-EXTERNAL authentication.
Expand Down
19 changes: 4 additions & 15 deletions src/auth/ejabberd_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
is_user_exists_in_other_modules/3,
remove_user/2,
remove_user/3,
store_type/1,
supports_password_type/2,
entropy/1
]).

Expand Down Expand Up @@ -122,20 +122,9 @@ get_opt(Host, Opt, Default) ->
get_opt(Host, Opt) ->
get_opt(Host, Opt, undefined).

store_type(Server) ->
lists:foldl(
fun(_, external) ->
external;
(M, scram) ->
case M:store_type(Server) of
external ->
external;
_Else ->
scram
end;
(M, plain) ->
M:store_type(Server)
end, plain, auth_modules(Server)).
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(Server, PasswordType) ->
lists:any(fun(M) -> M:supports_password_type(Server, PasswordType) end, auth_modules(Server)).

-spec authorize(mongoose_credentials:t()) -> {ok, mongoose_credentials:t()}
| {error, any()}.
Expand Down
12 changes: 8 additions & 4 deletions src/auth/ejabberd_auth_anonymous.erl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1,
supports_password_type/2,
get_vh_registered_users/2,
get_vh_registered_users_number/1,
get_vh_registered_users_number/2,
Expand Down Expand Up @@ -342,13 +342,17 @@ remove_user(_LUser, _LServer) ->
remove_user(_LUser, _LServer, _Password) ->
{error, not_allowed}.


store_type(_) ->
plain.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, plain) -> true;
supports_password_type(_, scram) -> true;
supports_password_type(_, digest) -> true;
supports_password_type(_, _) -> false.

get_vh_registered_users_number(_LServer) -> 0.

get_vh_registered_users_number(_LServer, _Opts) -> 0.

%% @doc gen_auth unimplemented callbacks
get_password_s(_LUser, _LServer) -> erlang:error(not_implemented).


6 changes: 3 additions & 3 deletions src/auth/ejabberd_auth_external.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1
supports_password_type/2
]).

%% Internal
Expand Down Expand Up @@ -88,8 +88,8 @@ check_cache_last_options(Server) ->
end
end.

store_type(_) ->
external.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, Type) -> Type =:= plain.

-spec authorize(mongoose_credentials:t()) -> {ok, mongoose_credentials:t()}
| {error, any()}.
Expand Down
19 changes: 6 additions & 13 deletions src/auth/ejabberd_auth_http.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1,
supports_password_type/2,
stop/1]).

%% Pre-mongoose_credentials API
Expand All @@ -45,18 +45,11 @@
start(_Host) ->
ok.

-spec store_type(binary()) -> plain | external | scram.
store_type(Server) ->
case scram:enabled(Server) of
false ->
case ejabberd_auth:get_opt(Server, is_external) of
true ->
external;
_ ->
plain
end;
true -> scram
end.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, plain) -> true;
supports_password_type(_, scram) -> true;
supports_password_type(Host, digest) -> not scram:enabled(Host);
supports_password_type(_, _) -> false.

-spec authorize(mongoose_credentials:t()) -> {ok, mongoose_credentials:t()}
| {error, any()}.
Expand Down
12 changes: 6 additions & 6 deletions src/auth/ejabberd_auth_internal.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1
supports_password_type/2
]).

-export([scram_passwords/0]).
Expand Down Expand Up @@ -103,11 +103,11 @@ update_reg_users_counter_table(Server) ->
end,
mnesia:sync_dirty(F).

store_type(Server) ->
case scram:enabled(Server) of
false -> plain;
true -> scram
end.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, plain) -> true;
supports_password_type(_, scram) -> true;
supports_password_type(Host, digest) -> not scram:enabled(Host);
supports_password_type(_, _) -> false.

-spec authorize(mongoose_credentials:t()) -> {ok, mongoose_credentials:t()}
| {error, any()}.
Expand Down
6 changes: 3 additions & 3 deletions src/auth/ejabberd_auth_jwt.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1
supports_password_type/2
]).


Expand All @@ -72,8 +72,8 @@ start(Host) ->
stop(_Host) ->
ok.

store_type(_Server) ->
external.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, PasswordType) -> PasswordType =:= plain.

-spec authorize(mongoose_credentials:t()) -> {ok, mongoose_credentials:t()}
| {error, any()}.
Expand Down
5 changes: 3 additions & 2 deletions src/auth/ejabberd_auth_ldap.erl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1
supports_password_type/2
]).

%% Internal
Expand Down Expand Up @@ -134,7 +134,8 @@ init(Host) ->
State#state.password, State#state.tls_options),
{ok, State}.

store_type(_) -> external.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, PasswordType) -> PasswordType =:= plain.

config_change(Acc, Host, ldap, _NewConfig) ->
stop(Host),
Expand Down
6 changes: 3 additions & 3 deletions src/auth/ejabberd_auth_pki.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
%% ejabberd_gen_auth API
-export([start/1,
stop/1,
store_type/1,
supports_password_type/2,
set_password/3,
authorize/1,
try_register/3,
Expand All @@ -48,8 +48,8 @@ start(_) -> ok.
-spec stop(Host :: ejabberd:lserver()) -> ok.
stop(_) -> ok.

-spec store_type(Host :: ejabberd:lserver()) -> scram | plain | external.
store_type(_) -> scram.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, PasswordType) -> PasswordType =:= cert.

-spec set_password( User :: ejabberd:luser(),
Server :: ejabberd:lserver(),
Expand Down
12 changes: 6 additions & 6 deletions src/auth/ejabberd_auth_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
does_user_exist/2,
remove_user/2,
remove_user/3,
store_type/1
supports_password_type/2
]).

%% Internal
Expand Down Expand Up @@ -84,11 +84,11 @@ start(_Host) ->
stop(_Host) ->
ok.

store_type(Server) ->
case scram:enabled(Server) of
false -> plain;
true -> scram
end.
-spec supports_password_type(jid:lserver(), cyrsasl:password_type()) -> boolean().
supports_password_type(_, plain) -> true;
supports_password_type(_, scram) -> true;
supports_password_type(Host, digest) -> not scram:enabled(Host);
supports_password_type(_, _) -> false.

-spec authorize(mongoose_credentials:t()) -> {ok, mongoose_credentials:t()}
| {error, any()}.
Expand Down
Loading