fix(authz): placehodler regular escape
This commit is contained in:
parent
124ba7a071
commit
b41c41570a
|
@ -218,4 +218,3 @@ parse(TopicFilter = <<"$share/", Rest/binary>>, Options) ->
|
||||||
end;
|
end;
|
||||||
parse(TopicFilter, Options) ->
|
parse(TopicFilter, Options) ->
|
||||||
{TopicFilter, Options}.
|
{TopicFilter, Options}.
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("emqx/include/emqx_placeholder.hrl").
|
||||||
|
|
||||||
-import(emqx_topic,
|
-import(emqx_topic,
|
||||||
[ wildcard/1
|
[ wildcard/1
|
||||||
|
@ -183,9 +184,9 @@ t_feed_var(_) ->
|
||||||
?assertEqual(<<"$queue/client/clientId">>,
|
?assertEqual(<<"$queue/client/clientId">>,
|
||||||
feed_var(<<"$c">>, <<"clientId">>, <<"$queue/client/$c">>)),
|
feed_var(<<"$c">>, <<"clientId">>, <<"$queue/client/$c">>)),
|
||||||
?assertEqual(<<"username/test/client/x">>,
|
?assertEqual(<<"username/test/client/x">>,
|
||||||
feed_var(<<"%u">>, <<"test">>, <<"username/%u/client/x">>)),
|
feed_var(?PH_USERNAME, <<"test">>, <<"username/", ?PH_USERNAME/binary, "/client/x">>)),
|
||||||
?assertEqual(<<"username/test/client/clientId">>,
|
?assertEqual(<<"username/test/client/clientId">>,
|
||||||
feed_var(<<"%c">>, <<"clientId">>, <<"username/test/client/%c">>)).
|
feed_var(?PH_CLIENTID, <<"clientId">>, <<"username/test/client/", ?PH_CLIENTID/binary>>)).
|
||||||
|
|
||||||
long_topic() ->
|
long_topic() ->
|
||||||
iolist_to_binary([[integer_to_list(I), "/"] || I <- lists:seq(0, 66666)]).
|
iolist_to_binary([[integer_to_list(I), "/"] || I <- lists:seq(0, 66666)]).
|
||||||
|
|
|
@ -23,7 +23,7 @@ authz:{
|
||||||
keyfile: "etc/certs/client-key.pem"
|
keyfile: "etc/certs/client-key.pem"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sql: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = '%a' or username = '%u' or clientid = '%c'"
|
sql: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = ${peerhost} or username = ${username} or clientid = ${clientid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: postgresql
|
type: postgresql
|
||||||
|
@ -36,7 +36,7 @@ authz:{
|
||||||
auto_reconnect: true
|
auto_reconnect: true
|
||||||
ssl: {enable: false}
|
ssl: {enable: false}
|
||||||
}
|
}
|
||||||
sql: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"
|
sql: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = ${peerhost} or username = ${username} or username = '$all' or clientid = ${clientid}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: redis
|
type: redis
|
||||||
|
@ -48,7 +48,7 @@ authz:{
|
||||||
auto_reconnect: true
|
auto_reconnect: true
|
||||||
ssl: {enable: false}
|
ssl: {enable: false}
|
||||||
}
|
}
|
||||||
cmd: "HGETALL mqtt_authz:%u"
|
cmd: "HGETALL mqtt_authz:${username}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
principal: {username: "^admin?"}
|
principal: {username: "^admin?"}
|
||||||
|
|
|
@ -22,7 +22,7 @@ authorization {
|
||||||
# certfile: "{{ platform_etc_dir }}/certs/client-cert.pem"
|
# certfile: "{{ platform_etc_dir }}/certs/client-cert.pem"
|
||||||
# keyfile: "{{ platform_etc_dir }}/certs/client-key.pem"
|
# keyfile: "{{ platform_etc_dir }}/certs/client-key.pem"
|
||||||
# }
|
# }
|
||||||
# query: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = '%a' or username = '%u' or clientid = '%c'"
|
# query: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = ${peerhost} or username = ${username} or clientid = ${clientid}"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# type: postgresql
|
# type: postgresql
|
||||||
|
@ -33,7 +33,7 @@ authorization {
|
||||||
# password: public
|
# password: public
|
||||||
# auto_reconnect: true
|
# auto_reconnect: true
|
||||||
# ssl: {enable: false}
|
# ssl: {enable: false}
|
||||||
# query: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"
|
# query: "select ipaddress, username, clientid, action, permission, topic from mqtt_authz where ipaddr = ${peerhost} or username = ${username} or username = '$all' or clientid = ${clientid}"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# type: redis
|
# type: redis
|
||||||
|
@ -43,7 +43,7 @@ authorization {
|
||||||
# password: public
|
# password: public
|
||||||
# auto_reconnect: true
|
# auto_reconnect: true
|
||||||
# ssl: {enable: false}
|
# ssl: {enable: false}
|
||||||
# cmd: "HGETALL mqtt_authz:%u"
|
# cmd: "HGETALL mqtt_authz:${username}"
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# type: mongodb
|
# type: mongodb
|
||||||
|
@ -53,7 +53,7 @@ authorization {
|
||||||
# database: mqtt
|
# database: mqtt
|
||||||
# ssl: {enable: false}
|
# ssl: {enable: false}
|
||||||
# collection: mqtt_authz
|
# collection: mqtt_authz
|
||||||
# selector: { "$or": [ { "username": "%u" }, { "clientid": "%c" } ] }
|
# selector: { "$or": [ { "username": "${username}" }, { "clientid": "${clientid}" } ] }
|
||||||
# },
|
# },
|
||||||
{
|
{
|
||||||
type: built-in-database
|
type: built-in-database
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
-export([acl_conf_file/0]).
|
-export([acl_conf_file/0]).
|
||||||
|
|
||||||
|
-export([ph_to_re/1]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
-spec(register_metrics() -> ok).
|
||||||
register_metrics() ->
|
register_metrics() ->
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTHZ_METRICS).
|
lists:foreach(fun emqx_metrics:ensure/1, ?AUTHZ_METRICS).
|
||||||
|
@ -386,3 +388,6 @@ type(Unknown) -> error({unknown_authz_source_type, Unknown}). % should never hap
|
||||||
%% @doc where the acl.conf file is stored.
|
%% @doc where the acl.conf file is stored.
|
||||||
acl_conf_file() ->
|
acl_conf_file() ->
|
||||||
filename:join([emqx:data_dir(), "authz", "acl.conf"]).
|
filename:join([emqx:data_dir(), "authz", "acl.conf"]).
|
||||||
|
|
||||||
|
ph_to_re(VarPH) ->
|
||||||
|
re:replace(VarPH, "[\\$\\{\\}]", "\\\\&", [global, {return, list}]).
|
||||||
|
|
|
@ -87,19 +87,19 @@ replvar(Str0, PubSub, Topic,
|
||||||
}) when is_list(Str0);
|
}) when is_list(Str0);
|
||||||
is_binary(Str0) ->
|
is_binary(Str0) ->
|
||||||
NTopic = emqx_http_lib:uri_encode(Topic),
|
NTopic = emqx_http_lib:uri_encode(Topic),
|
||||||
Str1 = re:replace( Str0, ?PH_S_CLIENTID
|
Str1 = re:replace( Str0, emqx_authz:ph_to_re(?PH_S_CLIENTID)
|
||||||
, Clientid, [global, {return, binary}]),
|
, Clientid, [global, {return, binary}]),
|
||||||
Str2 = re:replace( Str1, ?PH_S_USERNAME
|
Str2 = re:replace( Str1, emqx_authz:ph_to_re(?PH_S_USERNAME)
|
||||||
, bin(Username), [global, {return, binary}]),
|
, bin(Username), [global, {return, binary}]),
|
||||||
Str3 = re:replace( Str2, ?PH_S_HOST
|
Str3 = re:replace( Str2, emqx_authz:ph_to_re(?PH_S_HOST)
|
||||||
, inet_parse:ntoa(IpAddress), [global, {return, binary}]),
|
, inet_parse:ntoa(IpAddress), [global, {return, binary}]),
|
||||||
Str4 = re:replace( Str3, ?PH_S_PROTONAME
|
Str4 = re:replace( Str3, emqx_authz:ph_to_re(?PH_S_PROTONAME)
|
||||||
, bin(Protocol), [global, {return, binary}]),
|
, bin(Protocol), [global, {return, binary}]),
|
||||||
Str5 = re:replace( Str4, ?PH_S_MOUNTPOINT
|
Str5 = re:replace( Str4, emqx_authz:ph_to_re(?PH_S_MOUNTPOINT)
|
||||||
, Mountpoint, [global, {return, binary}]),
|
, Mountpoint, [global, {return, binary}]),
|
||||||
Str6 = re:replace( Str5, ?PH_S_TOPIC
|
Str6 = re:replace( Str5, emqx_authz:ph_to_re(?PH_S_TOPIC)
|
||||||
, NTopic, [global, {return, binary}]),
|
, NTopic, [global, {return, binary}]),
|
||||||
Str7 = re:replace( Str6, ?PH_S_ACTION
|
Str7 = re:replace( Str6, emqx_authz:ph_to_re(?PH_S_ACTION)
|
||||||
, bin(PubSub), [global, {return, binary}]),
|
, bin(PubSub), [global, {return, binary}]),
|
||||||
Str7.
|
Str7.
|
||||||
|
|
||||||
|
|
|
@ -76,11 +76,11 @@ replvar(Selector, #{clientid := Clientid,
|
||||||
end || M <- V],
|
end || M <- V],
|
||||||
AccIn);
|
AccIn);
|
||||||
InFun(K, V, AccIn) when is_binary(V) ->
|
InFun(K, V, AccIn) when is_binary(V) ->
|
||||||
V1 = re:replace( V, ?PH_S_CLIENTID
|
V1 = re:replace( V, emqx_authz:ph_to_re(?PH_S_CLIENTID)
|
||||||
, bin(Clientid), [global, {return, binary}]),
|
, bin(Clientid), [global, {return, binary}]),
|
||||||
V2 = re:replace( V1, ?PH_S_USERNAME
|
V2 = re:replace( V1, emqx_authz:ph_to_re(?PH_S_USERNAME)
|
||||||
, bin(Username), [global, {return, binary}]),
|
, bin(Username), [global, {return, binary}]),
|
||||||
V3 = re:replace( V2, ?PH_S_HOST
|
V3 = re:replace( V2, emqx_authz:ph_to_re(?PH_S_HOST)
|
||||||
, inet_parse:ntoa(IpAddress), [global, {return, binary}]),
|
, inet_parse:ntoa(IpAddress), [global, {return, binary}]),
|
||||||
maps:put(K, V3, AccIn);
|
maps:put(K, V3, AccIn);
|
||||||
InFun(K, V, AccIn) -> maps:put(K, V, AccIn)
|
InFun(K, V, AccIn) -> maps:put(K, V, AccIn)
|
||||||
|
|
|
@ -71,8 +71,9 @@ replvar(Cmd, Client = #{username := Username}) ->
|
||||||
replvar(Cmd, _) ->
|
replvar(Cmd, _) ->
|
||||||
Cmd.
|
Cmd.
|
||||||
|
|
||||||
repl(S, _Var, undefined) ->
|
repl(S, _VarPH, undefined) ->
|
||||||
S;
|
S;
|
||||||
repl(S, Var, Val) ->
|
repl(S, VarPH, Val) ->
|
||||||
NVal = re:replace(Val, "&", "\\\\&", [global, {return, list}]),
|
NVal = re:replace(Val, "&", "\\\\&", [global, {return, list}]),
|
||||||
re:replace(S, Var, NVal, [{return, list}]).
|
NVarPH = emqx_authz:ph_to_re(VarPH),
|
||||||
|
re:replace(S, NVarPH, NVal, [{return, list}]).
|
||||||
|
|
Loading…
Reference in New Issue