-
Notifications
You must be signed in to change notification settings - Fork 581
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
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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"); | ||
} | ||
if (!file_exists(FREERADIUS_ETC . "/raddb/modules/googleauth")) { copy(FREERADIUS_BASE . "/pkg/googleauth", FREERADIUS_ETC . "/raddb/modules/");} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"); } | ||
|
@@ -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'); | ||
|
@@ -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' | ||
|
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}" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/local/bin/python2.7 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this code yours? It's missing license and copyright There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some code is from here: 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) |
There was a problem hiding this comment.
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