diff options
| author | Michael Klishin <mklishin@pivotal.io> | 2019-06-22 18:39:53 +0300 |
|---|---|---|
| committer | Michael Klishin <mklishin@pivotal.io> | 2019-06-22 18:39:53 +0300 |
| commit | 35035cef2def2f406efdfde72351114a77e2a3b8 (patch) | |
| tree | b2dafcfd210df8f546d71b23a6fbf6811b260366 /src | |
| parent | 9a371273abf8877b8cde4b6df5a2746fa035349c (diff) | |
| download | rabbitmq-server-git-35035cef2def2f406efdfde72351114a77e2a3b8.tar.gz | |
WIP: credential expiration support prototyping
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_access_control.erl | 30 | ||||
| -rw-r--r-- | src/rabbit_auth_backend_internal.erl | 6 | ||||
| -rw-r--r-- | src/rabbit_auth_mechanism_plain.erl | 3 | ||||
| -rw-r--r-- | src/rabbit_reader.erl | 23 |
4 files changed, 58 insertions, 4 deletions
diff --git a/src/rabbit_access_control.erl b/src/rabbit_access_control.erl index d04f0047de..2727e555ac 100644 --- a/src/rabbit_access_control.erl +++ b/src/rabbit_access_control.erl @@ -21,6 +21,8 @@ -export([check_user_pass_login/2, check_user_login/2, check_user_loopback/2, check_vhost_access/4, check_resource_access/4, check_topic_access/4]). +-export([update_state/2]). + %%---------------------------------------------------------------------------- -export_type([permission_atom/0]). @@ -217,3 +219,31 @@ check_access(Fun, Module, ErrStr, ErrArgs, ErrName) -> rabbit_log:error(FullErrStr, FullErrArgs), rabbit_misc:protocol_error(ErrName, FullErrStr, FullErrArgs) end. + +-spec update_state(User :: rabbit_types:user(), NewState :: term()) -> + {'ok', rabbit_types:auth_user()} | + {'refused', string(), [any()]} | + {'error', any()}. + +update_state(User = #user{authz_backends = Backends0}, NewState) -> + %% N.B.: we use foldl/3 and prepending, so the final list of + %% backends + Backends = lists:foldl( + fun({Module, Impl}, {ok, Acc}) -> + case Module:state_can_expire() of + true -> + case Module:update_state(auth_user(User, Impl), NewState) of + {ok, #auth_user{impl = Impl1}} -> + {ok, [{Module, Impl1} | Acc]}; + Else -> Else + end; + false -> + {ok, [{Module, Impl} | Acc]} + end; + (_, {error, _} = Err) -> Err; + (_, {refused, _, _} = Err) -> Err + end, {ok, []}, Backends0), + case Backends of + {ok, Pairs} -> {ok, User#user{authz_backends = lists:reverse(Pairs)}}; + Else -> Else + end. diff --git a/src/rabbit_auth_backend_internal.erl b/src/rabbit_auth_backend_internal.erl index e16b14734b..e675ad188b 100644 --- a/src/rabbit_auth_backend_internal.erl +++ b/src/rabbit_auth_backend_internal.erl @@ -40,6 +40,8 @@ list_user_vhost_permissions/2, list_user_topic_permissions/1, list_vhost_topic_permissions/1, list_user_vhost_topic_permissions/2]). +-export([state_can_expire/0]). + %% for testing -export([hashing_module_for_user/1, expand_topic_permission/2]). @@ -93,6 +95,8 @@ user_login_authentication(Username, AuthProps) -> false -> exit({unknown_auth_props, Username, AuthProps}) end. +state_can_expire() -> false. + user_login_authorization(Username, _AuthProps) -> case user_login_authentication(Username, []) of {ok, #auth_user{impl = Impl, tags = Tags}} -> {ok, Impl, Tags}; @@ -123,7 +127,7 @@ check_vhost_access(#auth_user{username = Username}, VHostPath, _AuthzData) -> check_resource_access(#auth_user{username = Username}, #resource{virtual_host = VHostPath, name = Name}, - Permission, + Permission, _AuthContext) -> case mnesia:dirty_read({rabbit_user_permission, #user_vhost{username = Username, diff --git a/src/rabbit_auth_mechanism_plain.erl b/src/rabbit_auth_mechanism_plain.erl index cfc1a0ce18..706e5eedfa 100644 --- a/src/rabbit_auth_mechanism_plain.erl +++ b/src/rabbit_auth_mechanism_plain.erl @@ -31,9 +31,6 @@ %% SASL PLAIN, as used by the Qpid Java client and our clients. Also, %% apparently, by OpenAMQ. -%% TODO: reimplement this using the binary module? - that makes use of -%% BIFs to do binary matching and will thus be much faster. - description() -> [{description, <<"SASL PLAIN authentication mechanism">>}]. diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl index 8f64a70b5f..5eb8032bea 100644 --- a/src/rabbit_reader.erl +++ b/src/rabbit_reader.erl @@ -1273,6 +1273,29 @@ handle_method0(#'connection.close_ok'{}, State = #v1{connection_state = closed}) -> self() ! terminate_connection, State; +handle_method0(#'connection.update_secret'{new_secret = NewSecret, reason = Reason}, + State = #v1{connection = + #connection{protocol = Protocol, + user = User = #user{username = Username}, + log_name = ConnName}, + sock = Sock}) when ?IS_RUNNING(State) -> + rabbit_log_connection:debug( + "connection ~p (~s): " + "user '~s' attempts to update secret, reason: ~s~n", + [self(), dynamic_connection_name(ConnName), Username, Reason]), + case rabbit_access_control:update_state(User, NewSecret) of + {ok, User1} -> + rabbit_log_connection:debug("User1: ~p", [User1]), + ok = send_on_channel0(Sock, #'connection.update_secret_ok'{}, Protocol), + rabbit_log_connection:info( + "connection ~p (~s): " + "user '~s' updated secret, reason: ~s~n", + [self(), dynamic_connection_name(ConnName), Username, Reason]), + State; + Else -> + rabbit_log_connection:info("Secret update failed: ~p", [Else]), + State + end; handle_method0(_Method, State) when ?IS_STOPPING(State) -> State; handle_method0(_Method, #v1{connection_state = S}) -> |
