Skip to content

net/freeradius: Some Cleartext-Password values containing % fail PAP authentication #5678

Open

Description

@fgrueau

Environment

  • OPNsense 26.1.x
  • FreeRADIUS plugin
  • Authentication method: PAP
  • Password type: Cleartext-Password
  • Users configured through the OPNsense FreeRADIUS plugin

Problem

Some passwords containing % followed by specific characters are accepted by the OPNsense FreeRADIUS user configuration and are correctly written to the generated authorize file, but authentication fails.

FreeRADIUS reports:

Login incorrect (pap: Cleartext password does not match "known good" password)

The password entered by the client is identical to the password configured in OPNsense.

Steps to reproduce

  1. Create a FreeRADIUS user in OPNsense.
  2. Set Password Encryption to Cleartext-Password.
  3. Use the following password:
AA%cAAAA
  1. Apply the FreeRADIUS configuration.
  2. Verify the generated configuration:
grep 'user@example.com' /usr/local/etc/raddb/mods-config/files/authorize

The resulting entry is correct, for example:

user@example.com Cleartext-Password := "AA%cAAAA", Simultaneous-Use := "3"
  1. Try to authenticate the user using PAP.

Authentication fails with:

Login incorrect (pap: Cleartext password does not match "known good" password)

Reproducible test results

The following passwords fail:

AA%cAAAA    FAIL
AA%dAAAA    FAIL
AA%eAAAA    FAIL

The following passwords authenticate successfully:

AA%aAAAA    OK
AA%bAAAA    OK
AA%fAAAA    OK
AA%iAAAA    OK
AA%oAAAA    OK
AA%pAAAA    OK
AA%sAAAA    OK
AA%uAAAA    OK
AA%xAAAA    OK
AA%1AAAA    OK
AA%$AAAA    OK

A real randomly generated password containing %c also exhibited the issue:

WX%ci$9k    FAIL

Other randomly generated passwords containing % but not one of the problematic sequences authenticate successfully.

Expected behavior

Any password accepted as valid by the OPNsense FreeRADIUS user model and written unchanged as a Cleartext-Password should authenticate successfully with PAP.

Actual behavior

Certain sequences beginning with %, reproducibly %c, %d and %e, cause PAP authentication to fail even though the generated authorize entry contains the expected password.

The FreeRADIUS log reports a mismatch between the supplied password and the "known good" cleartext password.

Additional information

The issue does not appear to affect % characters in general. It depends on the character following %.

As a workaround, I have removed % from the character set used by my password generator.

This may be related to interpretation/expansion of some % sequences somewhere between the generated FreeRADIUS configuration and PAP password comparison.

Activity

  1. OPNsense-bot commented on Aug 27, 2026

    @OPNsense-bot

    Thank you for creating an issue.
    Since the ticket doesn't seem to be using one of our templates, we're marking this issue as low priority until further notice.

    For more information about the policies for this repository,
    please read https://github.com/opnsense/plugins/blob/master/CONTRIBUTING.md for further details.

    The easiest option to gain traction is to close this ticket and open a new one using one of our templates.

  2. dotCooCoo commented on Sep 2, 2026

    @dotCooCoo

    Your %c / %d / %e split is the key to this, and it points at the cause.

    The users template renders the password inside double quotes:

    {{ user_list.username }} {{ user_list.passwordencryption }} := "{{ user_list.password }}"
    

    FreeRADIUS applies dynamic expansion to double-quoted strings, and % starts an expansion
    sequence. That explains the table exactly. %c, %d and %e are valid single-letter
    expansions, so FreeRADIUS substitutes them and compares the client's password against the
    expanded string, which no longer matches. %a, %b, %f and the rest are not expansions, so
    they pass through and authentication succeeds.

    This is also why the generated authorize file looks correct. The file holds the literal
    text you typed, and the substitution happens when rlm_files loads it, so grepping the file
    cannot show the problem.

    There is a second failure mode from the same cause. A sequence that is not a valid expansion
    at all, such as %7, fails to parse rather than substituting, and rlm_files discards the
    entire user entry:

    files: WARNING: Failed parsing expanded value for check item, skipping entry:
    Auth: Login incorrect (No Auth-Type found: rejecting the user via Post-Auth-Type = Reject)
    

    So a password containing % either authenticates against a silently different value, which is
    what you hit, or removes the user from the file, depending on which character follows the %.

    #5695 fixes both by rendering the value single-quoted, which FreeRADIUS does not expand. I
    confirmed it against a 62 character password containing %cB and %7T on OPNsense 26.7.3_8
    with FreeRADIUS 3.2.10, where authentication went from Access-Reject to Access-Accept with the
    password unchanged.

    I opened #5694 for this before finding your report. Closing mine as the duplicate, since yours
    came first and carries the better reproduction data.

  3. dotCooCoo commented on Sep 5, 2026

    @dotCooCoo

    My comment above is wrong about %7. FreeRADIUS leaves a digit after % unchanged. What fails to expand is an unterminated %{; when that happens, rlm_files drops the check items for that entry and the user is rejected. The single-letter codes that FreeRADIUS expands inside a double-quoted value are %c %d %e %l %m %n %t %v %C %D %G %H %I %M %S %T %Y. I checked this against FreeRADIUS 3.2.10 while reworking #5695.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    incompleteIssue template missing info

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions