1%% This Source Code Form is subject to the terms of the Mozilla Public
2%% License, v. 2.0. If a copy of the MPL was not distributed with this
3%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4%%
5%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates.  All rights reserved.
6%%
7
8-module(rabbit_auth_mechanism_amqplain).
9-include_lib("rabbit_common/include/rabbit.hrl").
10
11-behaviour(rabbit_auth_mechanism).
12
13-export([description/0, should_offer/1, init/1, handle_response/2]).
14
15-rabbit_boot_step({?MODULE,
16                   [{description, "auth mechanism amqplain"},
17                    {mfa,         {rabbit_registry, register,
18                                   [auth_mechanism, <<"AMQPLAIN">>, ?MODULE]}},
19                    {requires,    rabbit_registry},
20                    {enables,     kernel_ready}]}).
21
22%% AMQPLAIN, as used by Qpid Python test suite. The 0-8 spec actually
23%% defines this as PLAIN, but in 0-9 that definition is gone, instead
24%% referring generically to "SASL security mechanism", i.e. the above.
25
26description() ->
27    [{description, <<"QPid AMQPLAIN mechanism">>}].
28
29should_offer(_Sock) ->
30    true.
31
32init(_Sock) ->
33    [].
34
35-define(IS_STRING_TYPE(Type), Type =:= longstr orelse Type =:= shortstr).
36
37handle_response(Response, _State) ->
38    LoginTable = rabbit_binary_parser:parse_table(Response),
39    case {lists:keysearch(<<"LOGIN">>, 1, LoginTable),
40          lists:keysearch(<<"PASSWORD">>, 1, LoginTable)} of
41        {{value, {_, UserType, User}},
42         {value, {_, PassType, Pass}}} when ?IS_STRING_TYPE(UserType);
43                                            ?IS_STRING_TYPE(PassType) ->
44            rabbit_access_control:check_user_pass_login(User, Pass);
45        {{value, {_, _UserType, _User}},
46         {value, {_, _PassType, _Pass}}} ->
47           {protocol_error,
48            "AMQPLAIN auth info ~w uses unsupported type for LOGIN or PASSWORD field",
49            [LoginTable]};
50        _ ->
51            {protocol_error,
52             "AMQPLAIN auth info ~w is missing LOGIN or PASSWORD field",
53             [LoginTable]}
54    end.
55