Last active
August 31, 2018 06:48
-
-
Save grizmin/f9b704f3406f33ffe9979208945fe659 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@@ execute after patch @@@ | |
@@@ chmod +x /usr/local/etc/raddb/scripts/googleauth.py @@@ | |
@@@ patch with System_Patches package @@@ | |
diff -Naur --new-file /usr/local/pkg/freeradius.inc /usr/local/pkg/freeradius.inc | |
--- /usr/local/pkg/freeradius.inc 2016-05-16 22:59:15.000000000 +0300 | |
+++ /usr/local/pkg/freeradius.inc 2016-06-27 01:43:28.388579000 +0300 | |
@@ -119,6 +119,10 @@ | |
freeradius_datacounter_acct_resync(); | |
freeradius_datacounter_auth_resync(); | |
+ // Install the Google Authenticator files | |
+ if (!file_exists(FREERADIUS_ETC . "/radd/usr/local/pkg/scripts/googleauth.py")) { copy("googleauth.py", FREERADIUS_ETC . "/radd/usr/local/pkg/scripts/");} | |
+ if (!file_exists(FREERADIUS_ETC . "/radd/usr/local/pkg/modules/googleauth")) { copy("googleauth", FREERADIUS_ETC . "/radd/usr/local/pkg/modules/");} | |
+ | |
// Some initial module configuration | |
freeradius_modulesmschap_resync(); | |
freeradius_modulesrealm_resync(); | |
@@ -537,7 +541,8 @@ | |
// if otp is enabled we need to set Auth-Type to accept because password will be checked when the otp script gets executed in reply-item list | |
else { | |
- $varuserscheckitem = '"' . $varusersusername . '"' . " Auth-Type = motp"; | |
+ //$varuserscheckitem = '"' . $varusersusername . '"' . " Auth-Type = motp"; | |
+ $varuserscheckitem = '"' . $varusersusername . '"' . " Auth-Type = " . $users['varusersauthmethod']; | |
} | |
// Add additional CHECK-ITEMS here. Different formatting in "users" file needed. | |
@@ -1791,6 +1796,11 @@ | |
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' | |
diff -Naur --new-file /usr/local/pkg/freeradius.xml /usr/local/pkg/freeradius.xml | |
--- /usr/local/pkg/freeradius.xml 2016-05-16 22:59:15.000000000 +0300 | |
+++ /usr/local/pkg/freeradius.xml 2016-06-27 01:43:28.388623000 +0300 | |
@@ -210,7 +210,19 @@ | |
]]> | |
</sethelp> | |
<type>checkbox</type> | |
- <enablefields>varusersmotpinitsecret,varusersmotppin,varusersmotpoffset</enablefields> | |
+ <enablefields>varusersauthmethod,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> | |
diff -Naur googleauth /usr/local/pkg/googleauth | |
--- /usr/local/etc/raddb/modules/googleauth 1970-01-01 02:00:00.000000000 +0200 | |
+++ /usr/local/etc/raddb/modules/googleauth 2016-06-27 01:49:30.714867000 +0300 | |
@@ -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}" | |
+} | |
diff -Naur googleauth.py /usr/local/pkg/googleauth.py | |
--- /usr/local/etc/raddb/scripts/googleauth.py 1970-01-01 02:00:00.000000000 +0200 | |
+++ /usr/local/etc/raddb/scripts/googleauth.py 2016-06-27 01:49:30.714920000 +0300 | |
@@ -0,0 +1,57 @@ | |
+#!/usr/local/bin/python2.7 | |
+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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment