0

I do have to set up a RADIUS server for authentication with a captive portal of pfSense. Unfortunately, all passwords in the RADIUS' database are hashed with a certain algorithm. I do use a MySQL-database.

Since the user are submitting their passwords in plaintext to the RADIUS-server, I do wonder whether I can hash the submitted passwort on the RADIUS-server and checking the existence of the username and hashed password afterwards.

If it is avoidable, I don't want to hash the password on the client-side. pfSense's captive portal is currently the only application using the RADIUS-server. But if I want to extend my infrastructure, I would have to implement the hashing-algorithm on every client.

Is there in general a possiblity to modify the RADIUS-server this way? Maybe with modifying the core? Unfortunately I don't in which file the submitted data are looked up in the database.

Does anyone have a tip for me where I do have to look?

(I do use Ubuntu Server 12.04 x86, freeradius, freeradius-mysql)

Drudge
  • 125
  • 2
  • 10

2 Answers2

1

Configure an instance of the rlm_sql module.

Add a query to authorize {} to retrieve the hashed password.

update control {
    <password-attribute> := "%{sql:SELECT password FROM foo_table WHERE user=%{User-Name}}"
}

Password-Attribute may be one of Cleartext-Password MD5-Password SMD5-Password Crypt-Password SHA2-Password SHA-Password SSHA-Password LM-Pasword NT-Password.

Then call the pap module. The pap module should set the Auth-Type to be pap and will hash the User-Password value to match the scheme used for the password-attribute value and compare them.

Arran Cudbard-Bell
  • 1,514
  • 1
  • 9
  • 18
  • Thanks a lot for your reply. Can i define my own password-attribute? My passwords are hashed with Django, so I do have a pbkdf2_sha256 encryption. I wrote a python-script that generateas the hash as the Django framework does. But I don't know how to implement it in the rlm_sql module. – Drudge May 10 '14 at 13:18
  • You can't add your own hashing schemes unless you know C and want to enhance the rlm_pap module (which is where you'd add the code, not SQL). If you give me a link to a formal description of the hashing scheme i'll have a look and see how hard it would be. – Arran Cudbard-Bell May 10 '14 at 16:51
  • Thanks for your help. Actually I got it on my own :) Shame on me, but I don't know what this encryption is.. it is used by the Django framework. Your hint with "update control" lead me to the correct way to implement it. I did it as the following: In the authorize{} section I added `update control{ Auth-Type := "/usr/bin/php5 -f /path/to/cpauth.php '%{User-Name}' '%{User-Password}' } ` The script passes the password to the Django hash routine and the username and password will be looked up in the database. On success, the php script simply echoes "Accept", else "Reject" – Drudge May 10 '14 at 16:58
  • The pkbdf2_sha256 can be found here https://pythonhosted.org/passlib/lib/passlib.utils.pbkdf2.html or directly in the Django framework (in my case) – Drudge May 10 '14 at 16:58
  • Ah, that works, it'll probably won't scale well, but if you're auth rate is small that's fine :). – Arran Cudbard-Bell May 10 '14 at 17:14
  • Unfortunatey, my RADIUS was misconfigured. It did not used the php-file which I found out now. The problem is, that even if my php-script echoes "Accept", my request is rejected. Any idea why? Suprisingly, if I create a php-file which only says `` then it works. The output of both files are the same but with my script I want to use it doesn't work. Any idea? – Drudge May 10 '14 at 19:30
  • added it as another answer (easier to format) – Arran Cudbard-Bell May 10 '14 at 20:01
0

Alternatively if you want to use an external PHP script you could place the following in authorize:

authorize {
    update {
        Tmp-String-0 := `/usr/bin/php5 -f /path/to/cpauth.php '%{User-Name}' '%{User-Password}'`
    }

    if (Tmp-String-0 == 'Accept') {
        update control {
            Auth-type := Accept
        }
    }
    else {
        reject
    }
}

Then echo 'Accept' or 'Reject'.

Arran Cudbard-Bell
  • 1,514
  • 1
  • 9
  • 18
  • Thanks for your answer again! My main problem is that if I execute the php-file with `/usr/bin/php5 -f /usr/customrad/cpauth.php user pass` I can see "Accept" in my terminal. When I do call the script in the authorize {} routine, I found out by debugging that mysqli returns an empty result. That's why I always get the "Reject"-package. Maybe there is a restriction that external called php-scripts cannot execute mysql-statements or so? If you want, I can try to upload the php-code to pastebin, if I find out, how to copy it from my virtual machine :) – Drudge May 10 '14 at 20:16
  • Try `sudo -su ` and run the script, check the result is the same running under the radius user. It might be permissions issues. – Arran Cudbard-Bell May 10 '14 at 20:54
  • There was a problem with my mysqli-query. I forgot to `$dbQueryGetPwd->store_result();` after binding my result. Now it works fine. Thank you again for your great help :) – Drudge May 10 '14 at 21:48