net/freeradius: quote password values literally so % is not expanded - #5695
net/freeradius: quote password values literally so % is not expanded#5695dotCooCoo wants to merge 1 commit into
Conversation
| <label>Password</label> | ||
| <type>password</type> | ||
| <help><![CDATA[Set the password for the user. Allowed characters are 0-9, a-z, A-Z, and ,._-!$%/()+#=:& with up to 128 characters.]]></help> | ||
| <help><![CDATA[Set the password for the user. Any printable ASCII character is allowed, with up to 128 characters.]]></help> |
There was a problem hiding this comment.
FWIW: feels spurious to mention all characters are supported
There was a problem hiding this comment.
I agree. I have removed the help text changes, and the help texts and masks are now the same as on master.
| @@ -1,9 +1,10 @@ | |||
| {%- macro q(value) -%}'{{ value | replace('\\', '\\\\') | replace("'", "\\'") }}'{%- endmacro -%} | |||
There was a problem hiding this comment.
I'm not really looking forward to reviewing if this is safe. Depending on concerns this may miss the bar for inclusion to not introduce other issues. In these cases a simpler fix may be the better approach.
There was a problem hiding this comment.
I have removed the macro. All three masks reject \ and ', which are the only characters that need escaping inside single quotes, so the password and both Tunnel-Password values are now written as '{{ value }}' without any escaping. The details are in my comment on the pull request.
FreeRADIUS expands single-letter % codes and %{...} inside double-quoted
values. A Cleartext-Password that contains one of them is compared
against a different string, and the user is rejected. An unterminated %{
fails to expand at all; rlm_files then drops the check items for that
entry, and the user is rejected. Both Tunnel-Password attributes were
written without quotes, and an unquoted value stops at the first parser
token. One of those tokens in the value, such as a parenthesis or an
equals sign, then causes a parse error in the users file, rlm_files
fails to load, and the server does not start.
The template now writes all three values in single quotes. FreeRADIUS
does not expand single-quoted values, and the only characters that need
escaping inside them are backslash and single quote. None of the three
masks allows either.
2f8b576 to
06c88e9
Compare
|
I have cut the pull request down to the quoting change. It now changes three lines, all in I tested each way of quoting against FreeRADIUS 3.2.10, the version on my 26.7.3_8 install. I loaded about 500 generated
If the masks are widened later, only My comment on #5678 is wrong about |
Important notices
Before you submit a pull request, we ask you kindly to acknowledge the following:
Describe the problem
User.xmlallows%in the password field, and theuserstemplate writes the value in double quotes. Inside a double-quoted string, FreeRADIUS expands%followed by one ofc d e l m n t v C D G H I M S T Y, and it expands%{...}. FreeRADIUS then compares the password the client sent against the expanded string, and PAP reportsCleartext password does not match "known good" password. The generated file still shows the text that was typed. #5678 lists the result for each character. An unterminated%{fails to expand at all.rlm_fileslogsFailed parsing expanded value for check item, skipping entry, drops the check items for that entry, and the user is rejected.The two
Tunnel-Passwordvalues at lines 28 and 124 are written without quotes. An unquoted value stops at the first parser token, and thetunnel_passwordmasks allow several of them:( ) { } = #and the operators== := += -= ++ !=. A tunnel password containing one of these producesParse error (reply) ... Expected end of line or comma.rlm_filesthen fails to load, and the server does not start.The password has been written in double quotes since the plugin's first commit in 2017.
Describe the proposed solution
The template now writes all three values in single quotes. FreeRADIUS does not expand single-quoted strings, so
%and%{...}are taken literally, and a parser token no longer ends the value. The only characters that need escaping inside single quotes are\and', and none of the three masks allows either, so the template does not escape anything.The masks are unchanged. Widening them would require escaping
\and'inside the single quotes, and that is not part of this change.clients.confandmods-enabled-sqlwrite their secrets in double quotes, andproxy.confwrites its secret without quotes. Those three are covered by #5696 and are not part of this change. Their model fields have no mask, so an admin may already have escaped the secret by hand, as #1655 advised.Verification
I loaded about 500 generated
usersentries into FreeRADIUS 3.2.10, read each value back through a reply attribute, and authenticated with PAP using a client that sends the exact password bytes:% $ { } ( ) # = : & + !%{...}listed above, and an unterminated%{gets the user rejected( ) { } = # , ; < > == := += -= ++ != =~ =*I rendered the template from master and the patched template against the same stubbed configuration and compared the output. The number of lines is the same, and only the intended lines differ.
On a live OPNsense 26.7.3_8 install with os-freeradius 1.10.2 and FreeRADIUS 3.2.10, I applied the single-quoted template. A 62-character password containing
%cand$$went from Access-Reject to Access-Accept, and a second user whose password was not affected could still log in.Related issue
Closes #5678. I opened #5694 for the same problem before finding #5678 and closed it as a duplicate.