Merge pull request #11737 from lafirest/fix/ldap_backslash

fix(ldap): escape the escape character (\)
This commit is contained in:
lafirest 2023-10-10 15:59:43 +08:00 committed by GitHub
commit 24a68401d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 11 deletions

View File

@ -241,7 +241,12 @@ user_seeds() ->
New(<<"mqttuser0006">>, <<"mqttuser0006">>, {error, user_disabled}),
%% IsSuperuser
New(<<"mqttuser0007">>, <<"mqttuser0007">>, {ok, #{is_superuser => true}}),
New(<<"mqttuser0008 (test)">>, <<"mqttuser0008 (test)">>, {ok, #{is_superuser => true}})
New(<<"mqttuser0008 (test)">>, <<"mqttuser0008 (test)">>, {ok, #{is_superuser => true}}),
New(
<<"mqttuser0009 \\\\test\\\\">>,
<<"mqttuser0009 \\\\test\\\\">>,
{ok, #{is_superuser => true}}
)
| Valid
].

View File

@ -235,7 +235,7 @@ user_seeds() ->
lists:seq(1, 5)
),
Specials = [<<"mqttuser0008 (test)">>],
Specials = [<<"mqttuser0008 (test)">>, <<"mqttuser0009 \\\\test\\\\">>],
Valid =
lists:map(

View File

@ -319,10 +319,8 @@ do_prepare_template([], State) ->
filter_escape(Binary) when is_binary(Binary) ->
filter_escape(erlang:binary_to_list(Binary));
filter_escape([$\\ | T]) ->
[$\\, $\\ | filter_escape(T)];
filter_escape([Char | T]) ->
case lists:member(Char, filter_control_chars()) of
case lists:member(Char, filter_special_chars()) of
true ->
[$\\, Char | filter_escape(T)];
_ ->
@ -331,5 +329,5 @@ filter_escape([Char | T]) ->
filter_escape([]) ->
[].
filter_control_chars() ->
[$(, $), $&, $|, $=, $!, $~, $>, $<, $:, $*, $\t, $\n, $\r].
filter_special_chars() ->
[$(, $), $&, $|, $=, $!, $~, $>, $<, $:, $*, $\t, $\n, $\r, $\\].

View File

@ -2,8 +2,8 @@ Definitions.
Control = [()&|!=~><:*]
White = [\s\t\n\r]+
StringChars = [^()&|!=~><:*\t\n\r]
Escape = \\{Control}|\\{White}
StringChars = [^()&|!=~><:*\t\n\r\\]
Escape = \\\\|\\{Control}|\\{White}
String = ({Escape}|{StringChars})+
Rules.
@ -23,7 +23,7 @@ Rules.
{White} : skip_token.
{String} : {token, {string, TokenLine, to_string(TokenChars)}}.
%% Leex will hang if a composite operation is missing a character
{Control} : {error, lists:flatten(io_lib:format("Unexpected Tokens:~ts", [TokenChars]))}.
{Control} : {error, format("Unexpected Tokens:~ts", [TokenChars])}.
Erlang code.
@ -34,4 +34,19 @@ Erlang code.
%% so after the tokenization we should remove all escape character
to_string(TokenChars) ->
String = string:trim(TokenChars),
lists:flatten(string:replace(String, "\\", "", all)).
trim_escape(String).
%% because of the below situation, we can't directly use the `replace` to trim the escape character
%%trim_escape([$\\, $\\ | T]) ->
%% [$\\ | trim_escape(T)];
trim_escape([$\\, Char | T]) ->
[Char | trim_escape(T)];
%% the underneath is impossible to occur because it is not valid in the lexer
%% trim_escape([$\\])
trim_escape([Char | T]) ->
[Char | trim_escape(T)];
trim_escape([]) ->
[].
format(Fmt, Args) ->
lists:flatten(io_lib:format(Fmt, Args)).

View File

@ -166,6 +166,15 @@ uid: mqttuser0008 (test)
isSuperuser: TRUE
userPassword: {SHA}FCzJLOp66OwsZ9DQzXSxdTd9c0U=
objectClass: top
dn:uid=mqttuser0009 \\test\\,ou=testdevice,dc=emqx,dc=io
objectClass: mqttUser
objectClass: mqttDevice
objectClass: mqttSecurity
uid: mqttuser0009 \\test\\
isSuperuser: TRUE
userPassword: {SHA}awxXARLqWYx+xy0677D/TLjlyHA=
## Try to test with base DN 'ou=dashboard,dc=emqx,dc=io'
## with a filter ugroup=group1
## this should return 2 users in the query and fail the test

View File

@ -235,6 +235,10 @@ t_escape(_Config) ->
?assertEqual(
'or'([equalityMatch("a", "name (1) *")]),
parse("(|(a=name\\ \\(1\\) \\*))")
),
?assertEqual(
'and'([equalityMatch("a", "\\value\\")]),
parse("(&(a=\\\\value\\\\))")
).
t_value_eql_dn(_Config) ->