fix(authn): fix password hash algorithm for mysql and pgsql authn
This commit is contained in:
parent
a6b95afda8
commit
76d6949cd1
|
@ -16,7 +16,7 @@
|
|||
|
||||
-module(emqx_authn_utils).
|
||||
|
||||
-export([ replace_placeholder/2
|
||||
-export([ replace_placeholders/2
|
||||
, gen_salt/0
|
||||
]).
|
||||
|
||||
|
@ -24,23 +24,23 @@
|
|||
%% APIs
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
replace_placeholder(PlaceHolders, Data) ->
|
||||
replace_placeholder(PlaceHolders, Data, []).
|
||||
replace_placeholders(PlaceHolders, Data) ->
|
||||
replace_placeholders(PlaceHolders, Data, []).
|
||||
|
||||
replace_placeholder([], _Data, Acc) ->
|
||||
replace_placeholders([], _Data, Acc) ->
|
||||
lists:reverse(Acc);
|
||||
replace_placeholder([<<"${mqtt-username}">> | More], #{username := Username} = Data, Acc) ->
|
||||
replace_placeholder(More, Data, [convert_to_sql_param(Username) | Acc]);
|
||||
replace_placeholder([<<"${mqtt-clientid}">> | More], #{clientid := ClientID} = Data, Acc) ->
|
||||
replace_placeholder(More, Data, [convert_to_sql_param(ClientID) | Acc]);
|
||||
replace_placeholder([<<"${ip-address}">> | More], #{peerhost := IPAddress} = Data, Acc) ->
|
||||
replace_placeholder(More, Data, [convert_to_sql_param(IPAddress) | Acc]);
|
||||
replace_placeholder([<<"${cert-subject}">> | More], #{dn := Subject} = Data, Acc) ->
|
||||
replace_placeholder(More, Data, [convert_to_sql_param(Subject) | Acc]);
|
||||
replace_placeholder([<<"${cert-common-name}">> | More], #{cn := CommonName} = Data, Acc) ->
|
||||
replace_placeholder(More, Data, [convert_to_sql_param(CommonName) | Acc]);
|
||||
replace_placeholder([_ | More], Data, Acc) ->
|
||||
replace_placeholder(More, Data, [null | Acc]).
|
||||
replace_placeholders([<<"${mqtt-username}">> | More], #{username := Username} = Data, Acc) ->
|
||||
replace_placeholders(More, Data, [convert_to_sql_param(Username) | Acc]);
|
||||
replace_placeholders([<<"${mqtt-clientid}">> | More], #{clientid := ClientID} = Data, Acc) ->
|
||||
replace_placeholders(More, Data, [convert_to_sql_param(ClientID) | Acc]);
|
||||
replace_placeholders([<<"${ip-address}">> | More], #{peerhost := IPAddress} = Data, Acc) ->
|
||||
replace_placeholders(More, Data, [convert_to_sql_param(IPAddress) | Acc]);
|
||||
replace_placeholders([<<"${cert-subject}">> | More], #{dn := Subject} = Data, Acc) ->
|
||||
replace_placeholders(More, Data, [convert_to_sql_param(Subject) | Acc]);
|
||||
replace_placeholders([<<"${cert-common-name}">> | More], #{cn := CommonName} = Data, Acc) ->
|
||||
replace_placeholders(More, Data, [convert_to_sql_param(CommonName) | Acc]);
|
||||
replace_placeholders([_ | More], Data, Acc) ->
|
||||
replace_placeholders(More, Data, [null | Acc]).
|
||||
|
||||
gen_salt() ->
|
||||
<<X:128/big-unsigned-integer>> = crypto:strong_rand_bytes(16),
|
||||
|
|
|
@ -46,25 +46,12 @@ fields(config) ->
|
|||
, {query, fun query/1}
|
||||
, {query_timeout, fun query_timeout/1}
|
||||
] ++ emqx_connector_schema_lib:relational_db_fields()
|
||||
++ emqx_connector_schema_lib:ssl_fields();
|
||||
++ emqx_connector_schema_lib:ssl_fields().
|
||||
|
||||
fields(bcrypt) ->
|
||||
[ {name, {enum, [bcrypt]}}
|
||||
, {salt_rounds, fun salt_rounds/1}
|
||||
];
|
||||
|
||||
fields(other_algorithms) ->
|
||||
[ {name, {enum, [plain, md5, sha, sha256, sha512]}}
|
||||
].
|
||||
|
||||
password_hash_algorithm(type) -> {union, [hoconsc:ref(bcrypt), hoconsc:ref(other_algorithms)]};
|
||||
password_hash_algorithm(default) -> #{<<"name">> => sha256};
|
||||
password_hash_algorithm(type) -> {enum, [plain, md5, sha, sha256, sha512, bcrypt]};
|
||||
password_hash_algorithm(default) -> sha256;
|
||||
password_hash_algorithm(_) -> undefined.
|
||||
|
||||
salt_rounds(type) -> integer();
|
||||
salt_rounds(default) -> 10;
|
||||
salt_rounds(_) -> undefined.
|
||||
|
||||
salt_position(type) -> {enum, [prefix, suffix]};
|
||||
salt_position(default) -> prefix;
|
||||
salt_position(_) -> undefined.
|
||||
|
@ -118,7 +105,7 @@ authenticate(#{password := Password} = Credential,
|
|||
placeholders := PlaceHolders,
|
||||
query := Query,
|
||||
query_timeout := Timeout} = State) ->
|
||||
Params = emqx_authn_utils:replace_placeholder(PlaceHolders, Credential),
|
||||
Params = emqx_authn_utils:replace_placeholders(PlaceHolders, Credential),
|
||||
case emqx_resource:query(ResourceID, {sql, Query, Params, Timeout}) of
|
||||
{ok, _Columns, []} -> ignore;
|
||||
{ok, Columns, Rows} ->
|
||||
|
@ -137,7 +124,7 @@ destroy(#{resource_id := ResourceID}) ->
|
|||
%% Internal functions
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
check_password(undefined, _Algorithm, _Selected) ->
|
||||
check_password(undefined, _Selected, _State) ->
|
||||
{error, bad_username_or_password};
|
||||
check_password(Password,
|
||||
#{password_hash := Hash},
|
||||
|
|
|
@ -45,7 +45,8 @@ fields(config) ->
|
|||
] ++ emqx_connector_schema_lib:relational_db_fields()
|
||||
++ emqx_connector_schema_lib:ssl_fields().
|
||||
|
||||
password_hash_algorithm(type) -> string();
|
||||
password_hash_algorithm(type) -> {enum, [plain, md5, sha, sha256, sha512, bcrypt]};
|
||||
password_hash_algorithm(default) -> sha256;
|
||||
password_hash_algorithm(_) -> undefined.
|
||||
|
||||
query(type) -> string();
|
||||
|
@ -90,7 +91,7 @@ authenticate(#{password := Password} = Credential,
|
|||
#{resource_id := ResourceID,
|
||||
query := Query,
|
||||
placeholders := PlaceHolders} = State) ->
|
||||
Params = emqx_authn_utils:replace_placeholder(PlaceHolders, Credential),
|
||||
Params = emqx_authn_utils:replace_placeholders(PlaceHolders, Credential),
|
||||
case emqx_resource:query(ResourceID, {sql, Query, Params}) of
|
||||
{ok, _Columns, []} -> ignore;
|
||||
{ok, Columns, Rows} ->
|
||||
|
@ -109,7 +110,7 @@ destroy(#{resource_id := ResourceID}) ->
|
|||
%% Internal functions
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
check_password(undefined, _Algorithm, _Selected) ->
|
||||
check_password(undefined, _Selected, _State) ->
|
||||
{error, bad_username_or_password};
|
||||
check_password(Password,
|
||||
#{password_hash := Hash},
|
||||
|
|
|
@ -149,11 +149,14 @@ connect(Opts) ->
|
|||
WorkerOptions = proplists:get_value(worker_options, Opts, []),
|
||||
mongo_api:connect(Type, Hosts, Options, WorkerOptions).
|
||||
|
||||
mongo_query(Conn, find, Collection, Selector, Docs) ->
|
||||
mongo_api:find(Conn, Collection, Selector, Docs);
|
||||
mongo_query(Conn, find, Collection, Selector, Projector) ->
|
||||
mongo_api:find(Conn, Collection, Selector, Projector);
|
||||
|
||||
mongo_query(Conn, find_one, Collection, Selector, Projector) ->
|
||||
mongo_api:find_one(Conn, Collection, Selector, Projector);
|
||||
|
||||
%% Todo xxx
|
||||
mongo_query(_Conn, _Action, _Collection, _Selector, _Docs) ->
|
||||
mongo_query(_Conn, _Action, _Collection, _Selector, _Projector) ->
|
||||
ok.
|
||||
|
||||
do_start(InstId, Opts0, Config = #{mongo_type := Type,
|
||||
|
|
Loading…
Reference in New Issue