Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save grizmin/f9b704f3406f33ffe9979208945fe659 to your computer and use it in GitHub Desktop.
Save grizmin/f9b704f3406f33ffe9979208945fe659 to your computer and use it in GitHub Desktop.
@@@ 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