Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for Google Authenticator #196

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions net/pfSense-pkg-freeradius2/files/usr/local/pkg/freeradius.inc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,14 @@ function freeradius_install_command() {
log_error("FreeRADIUS: Creating backup of the original file to " . FREERADIUS_ETC . "/raddb/files.backup");
copy(FREERADIUS_ETC . "/raddb/modules/files", FREERADIUS_ETC . "/raddb/files.backup");
}


// Install Google Authenticator scripts
if (!file_exists(FREERADIUS_ETC . "/raddb/scripts/googleauth.py")) {
copy(FREERADIUS_BASE . "/pkg/googleauth.py", FREERADIUS_ETC . "/raddb/scripts/");
exec("chmod +x " . FREERADIUS_ETC . "/raddb/scripts/googleauth.py");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHP provides a function to chmod(), consider using it

}
if (!file_exists(FREERADIUS_ETC . "/raddb/modules/googleauth")) { copy(FREERADIUS_BASE . "/pkg/googleauth", FREERADIUS_ETC . "/raddb/modules/");}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break this long line as is done on block just above it


// Disable virtual-server we do not need by default
if (file_exists(FREERADIUS_ETC . "/raddb/sites-enabled/control-socket")) { unlink(FREERADIUS_ETC . "/raddb/sites-enabled/control-socket"); }
if (file_exists(FREERADIUS_ETC . "/raddb/sites-enabled/inner-tunnel")) { unlink(FREERADIUS_ETC . "/raddb/sites-enabled/inner-tunnel"); }
Expand Down Expand Up @@ -439,7 +446,8 @@ if (is_array($arrusers) && !empty($arrusers)) {
$varuserspassword = $users['varuserspassword'];
}



$varusersauthmethod = $users['varusersauthmethod'];
$varusersmotpinitsecret = $users['varusersmotpinitsecret'];
$varusersmotppin = $users['varusersmotppin'];
$varusersmotpoffset = ($users['varusersmotpoffset']?$users['varusersmotpoffset']:'0');
Expand Down Expand Up @@ -1784,6 +1792,12 @@ authenticate {
motp
}

#
# Google-Authenticator authentication.
Auth-Type GOOGLEAUTH {
googleauth
}

#
# If you have a Cisco SIP server authenticating against
# FreeRADIUS, uncomment the following line, and the 'digest'
Expand Down
15 changes: 15 additions & 0 deletions net/pfSense-pkg-freeradius2/files/usr/local/pkg/freeradius.xml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,21 @@
<type>checkbox</type>
<enablefields>varusersmotpinitsecret,varusersmotppin,varusersmotpoffset</enablefields>
</field>
<field>
<fielddescr>Authentication Method</fielddescr>
<fieldname>varusersauthmethod</fieldname>
<description>
<![CDATA[
Select the authentication method for this user. Default: motp
]]>
</description>
<type>select</type>
<default_value>motp</default_value>
<options>
<option><name>Use mOTP</name><value>motp</value></option>
<option><name>Use Google-Authenticator</name><value>googleauth</value></option>
</options>
</field>
<field>
<fielddescr>Init-Secret</fielddescr>
<fieldname>varusersmotpinitsecret</fieldname>
Expand Down
4 changes: 4 additions & 0 deletions net/pfSense-pkg-freeradius2/files/usr/local/pkg/googleauth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
exec googleauth {
wait = yes
program = " /usr/local/etc/raddb/scripts/googleauth.py %{request:User-Name} %{reply:MOTP-Init-Secret} %{reply:MOTP-PIN} %{request:User-Password}"
}
57 changes: 57 additions & 0 deletions net/pfSense-pkg-freeradius2/files/usr/local/pkg/googleauth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/local/bin/python2.7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this code yours? It's missing license and copyright

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some code is from here:
http://www.brool.com/post/using-google-authenticator-for-your-website/

License is "CC0 1.0 Universal License"

import sys
import time
import struct
import hmac
import hashlib
import base64
import syslog

def authenticate(username, secretkey, pin, code_attempt):

if code_attempt.startswith(pin,0, len(pin)) == False:
syslog.syslog(syslog.LOG_ERR, "freeRADIUS: Google Authenticator - Authentication failed. User: " + username + ", Reason: wrong PIN")
return False

code_attempt = code_attempt[len(pin):]
tm = int(time.time() / 30)

secretkey = base64.b32decode(secretkey)

# try 30 seconds behind and ahead as well
for ix in [-1, 0, 1]:
# convert timestamp to raw bytes
b = struct.pack(">q", tm + ix)

# generate HMAC-SHA1 from timestamp based on secret key
hm = hmac.HMAC(secretkey, b, hashlib.sha1).digest()

# extract 4 bytes from digest based on LSB
offset = ord(hm[-1]) & 0x0F
truncatedHash = hm[offset:offset+4]

# get the code from it
code = struct.unpack(">L", truncatedHash)[0]
code &= 0x7FFFFFFF;
code %= 1000000;

if ("%06d" % code) == str(code_attempt):
syslog.syslog(syslog.LOG_NOTICE, "freeRADIUS: Google Authenticator - Authentication successful for user: " + username)
return True

syslog.syslog(syslog.LOG_ERR, "freeRADIUS: Google Authenticator - Authentication failed. User: " + username + ", Reason: wrong tokencode")
return False


# Check the length of the parameters
if len(sys.argv) != 5:
syslog.syslog(syslog.LOG_ERR, "freeRADIUS: Google Authenticator - wrong syntax - USAGE: googleauth.py Username, Secret-Key, PIN, Auth-Attempt")
exit(1)


auth = authenticate(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

if auth == True:
exit(0)

exit(1)