From 4a1fcd4e9e9de8b2906ef988196d58b4dd72ad3b Mon Sep 17 00:00:00 2001 From: Alexander Wilke Date: Tue, 7 Feb 2012 22:54:59 +0100 Subject: OTP support --- config/freeradius2/freeradius.inc | 205 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 197 insertions(+), 8 deletions(-) diff --git a/config/freeradius2/freeradius.inc b/config/freeradius2/freeradius.inc index 83c8d4cd..51029711 100644 --- a/config/freeradius2/freeradius.inc +++ b/config/freeradius2/freeradius.inc @@ -378,6 +378,7 @@ EOD; freeradius_modulesmschap_resync(); freeradius_modulesrealm_resync(); freeradius_plainmacauth_resync(); + freeradius_motp_resync(); // This is to fix the mysqlclient.so which gets lost after reboot exec("ldconfig -m /usr/local/lib/mysql"); @@ -397,8 +398,14 @@ if (is_array($arrusers) && !empty($arrusers)) { foreach ($arrusers as $users) { // Variables for users file defined parameters + $varusersusername = $users['varusersusername']; $varuserspassword = $users['varuserspassword']; + + $varusersmotpinitsecret = $users['varusersmotpinitsecret']; + $varusersmotppin = $users['varusersmotppin']; + $varusersmotpoffset = ($users['varusersmotpoffset']?$users['varusersmotpoffset']:'0'); + $varuserssimultaneousconnect = ($users['varuserssimultaneousconnect']?$users['varuserssimultaneousconnect']:''); $varuserswisprredirectionurl = $users['varuserswisprredirectionurl']; $varusersframedipaddress = $users['varusersframedipaddress']; @@ -456,14 +463,22 @@ if (is_array($arrusers) && !empty($arrusers)) { $varuserscheckitem = ''; $varusersreplyitem = ''; - // If someone does not want to use username/password but entry "DEFAULT" instead then we can disable this - if (($users['varusersusername'] == '') && ($users['varuserspassword'] == '')) { - $varuserscheckitem = ''; - } - else { - // Add the user attributes to each user. - $varuserscheckitem = '"' . $varusersusername . '"' . " Cleartext-Password := " . '"' . $varuserspassword .'"'; - } + // check if mobile otp is disabled + if ($users['varusersmotpenable'] == '') { + // If someone does not want to use username/password but entry "DEFAULT" instead then we can disable this + if (($users['varusersusername'] == '') && ($users['varuserspassword'] == '')) { + $varuserscheckitem = ''; + } + else { + // Add the user attributes to each user. + $varuserscheckitem = '"' . $varusersusername . '"' . " Cleartext-Password := " . '"' . $varuserspassword .'"'; + } + } // end of check if otp is enabled + + // 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 = Accept"; + } // Add additional CHECK-ITEMS here. Different formatting in "users" file needed. if ($varuserssimultaneousconnect != '') { @@ -488,6 +503,14 @@ if (is_array($arrusers) && !empty($arrusers)) { $varuserscheckitem .= ", $varusersadditionaloptionscheckitems"; } + // this is the part for mobile otp + if ($users['varusersmotpenable'] == 'on') { + $varusersreplyitem .= 'Exec-Program-Wait = "/usr/local/bin/bash /usr/local/bin/otpverify.sh %{User-Name} %{User-Password} ' . "$varusersmotpinitsecret " . "$varusersmotppin " . "$varusersmotpoffset" . '"'; + } + else { + $varusersreplyitem .= ''; + } + // Add additional REPLY-ITEMS here. Different formatting in "users" file needed. if ($varusersframedipaddress != '') { if ($varusersreplyitem != '') { $varusersreplyitem .=","; } @@ -3824,4 +3847,170 @@ EOD; } +function freeradius_motp_resync() { + global $config; + $conf = ''; + + $varsettings = $config['installedpackages']['freeradiussettings']['config'][0]; + + // check if disabled then we delete bash und otpverify.sh script + if ($varsettings['varsettingsmotpenable'] == '') { + unlink("/usr/local/bin/otpverify.sh"); + exec("cd /var/db/pkg && pkg_delete `ls | grep bash`"); + log_error('FreeRADIUS: Uninstalling package "bash-4.1.7" which comes with Mobile-One-Time-Password (motp) if not already done.'); + } + + // check if enabled then we need to download "bash" + else { + if (exec("cd /var/db/pkg && ls | grep bash") != "bash-4.1.7") { + log_error('FreeRADIUS: Downloading and installing package "bash-4.1.7" to use Mobile-One-Time-Password (motp).'); + exec("pkg_add -r http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/ports/`uname -m`/packages-8.1-release/All/bash-4.1.7.tbz"); + } + + $conf .= << +# +# Version 1.05a +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# arguments: \$1 \$2 \$3 \$4 \$5 +# \$1 - username +# \$2 - one-time-password that is to be checked +# \$3 - init-secred from token (to init token: #**#) +# \$4 - user PIN +# \$5 - time difference between token and server in 10s of seconds (360 = 1 hour) +# +# one-time-password must match md5(EPOCHTIME+SECRET+PIN) +# +# +# otpverify.sh version 1.04b, Feb. 2003 +# otpverify.sh version 1.04c, Nov. 2008 +# changed line 1 to ksh because of problems with todays bash an sh +# otpverify.sh version 1.05a, Jan. 2011 +# changed back to bash and added in shopts line to ensure aliases handled +# correctly (bash is always available on any modern *nix unlike ksh) +# + +PATH=\$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + + alias checksum=md5 + have_md5="true" + +# ensure aliases are expanded by bash +shopt -s expand_aliases + +if [ -e "`which md5 2>/dev/null`" ] +then + alias checksum=md5 + have_md5="true" +fi +if [ -e "`which md5sum 2>/dev/null`" ] +then + alias checksum=md5sum + have_md5="true" +fi + +if [ \$have_md5 != "true" ] +then + echo "No md5 or md5sum available on server!" + exit 16 +fi + +function chop +{ + num=`echo -n "\$1" | wc -c | sed 's/ //g' ` + nummin1=`expr \$num "-" 1` + echo -n "\$1" | cut -b 1-\$nummin1 +} + +if [ ! \$# -eq 5 ] ; then +echo "USAGE: otpverify.sh Username, OTP, Init-Secret, PIN, Offset" +logger -f /var/log/system.log "FreeRADIUS: Mobile-One-Time-Password - wrong syntax - USAGE: otpverify.sh Username, OTP, Init-Secret, PIN, Offset"; +exit 14 +fi + +mkdir /var/log/motp 2>/dev/null +mkdir /var/log/motp/cache 2>/dev/null +mkdir /var/log/motp/users 2>/dev/null +chmod og-rxw /var/log/motp 2>/dev/null || { echo "FAIL! Need write-access to /var/log/motp";logger -f /var/log/system.log "FreeRADIUS: Mobile-One-Time-Password - need write-access to /var/log/motp"; exit 17; } +chmod og-rxw /var/log/motp/cache +chmod og-rxw /var/log/motp/users + +USERNAME=`echo -n "\$1" | sed 's/[^0-9a-zA-Z._-]/X/g' ` +PASSWD=`echo -n "\$2" | sed 's/[^0-9a-f]/0/g' ` +SECRET=`echo -n "\$3" | sed 's/[^0-9a-f]/0/g' ` +PIN=`echo -n "\$4" | sed 's/[^0-9]/0/g' ` +OFFSET=`echo -n "\$5" | sed 's/[^0-9]/0/g' ` +EPOCHTIME=`date +%s` ; EPOCHTIME=`chop \$EPOCHTIME` + +# delete old logins +find /var/log/motp/cache -type f -cmin +5 | xargs rm 2>/dev/null + +if [ -e "/var/log/motp/cache/\$PASSWD" ]; then + echo "FAIL" + logger -f /var/log/system.log "FreeRADIUS: Authentication failed! Mobile-One-Time-Password incorrect or expired!" + exit 15 +fi + +# account locked? +if [ "`cat /var/log/motp/users/\$USERNAME 2>/dev/null`" == "8" ]; then + echo "FAIL" + logger -f /var/log/system.log "FreeRADIUS: Authentication failed! Mobile-One-Time-Password incorrect or expired!" + exit 13 +fi + +I=0 +EPOCHTIME=`expr \$EPOCHTIME - 18` +EPOCHTIME=`expr \$EPOCHTIME + \$OFFSET` +while [ \$I -lt 36 ] ; do # 3 minutes before and after + OTP=`printf \$EPOCHTIME\$SECRET\$PIN|checksum|cut -b 1-6` + if [ "\$OTP" = "\$PASSWD" ] ; then + touch /var/log/motp/cache/\$OTP || { echo "FAIL! Need write-access to /var/log/motp";logger -f /var/log/system.log "FreeRADIUS: Mobile-One-Time-Password - need write-access to /var/log/motp/cache"; exit 17; } + echo "ACCEPT" + logger -f /var/log/system.log "FreeRADIUS: Authentication success! Mobile-One-Time-Password is correct!" + rm "/var/log/motp/users/\$USERNAME" 2>/dev/null + exit 0 + fi + I=`expr \$I + 1` + EPOCHTIME=`expr \$EPOCHTIME + 1` +done + +echo "FAIL" +NUMFAILS=`cat "/var/log/motp/users/\$USERNAME" 2>/dev/null` +if [ "\$NUMFAILS" = "" ]; then + NUMFAILS=0 +fi +NUMFAILS=`expr \$NUMFAILS + 1` +echo \$NUMFAILS > "/var/log/motp/users/\$USERNAME" +logger -f /var/log/system.log "FreeRADIUS: Authentication failed! Mobile-One-Time-Password incorrect or expired!" +exit 11 + + +EOD; + + $filename = '/usr/local/bin/otpverify.sh'; + conf_mount_rw(); + file_put_contents($filename, $conf); + chmod($filename, 0775); + conf_mount_ro(); + + // end of above 'check if enabled then we need to download "bash"' + } + +} + ?> \ No newline at end of file -- cgit v1.2.3