module Duo
A Ruby implementation of the Duo
WebSDK
Constants
- AKEY_LEN
- APP_EXPIRE
- APP_PREFIX
- AUTH_PREFIX
- DUO_EXPIRE
- DUO_PREFIX
- ERR_AKEY
- ERR_IKEY
- ERR_SKEY
- ERR_USER
- IKEY_LEN
- SKEY_LEN
Public Instance Methods
sign_request(ikey, skey, akey, username)
click to toggle source
Sign a Duo
2FA request @param ikey [String] The Duo
IKEY @param skey [String] The Duo
SKEY @param akey [String] The Duo
AKEY @param username [String] Username to authenticate as
# File lib/duo_web.rb, line 29 def sign_request(ikey, skey, akey, username) return Duo::ERR_USER if !username || username.empty? return Duo::ERR_USER if username.include? '|' return Duo::ERR_IKEY if !ikey || ikey.to_s.length != Duo::IKEY_LEN return Duo::ERR_SKEY if !skey || skey.to_s.length != Duo::SKEY_LEN return Duo::ERR_AKEY if !akey || akey.to_s.length < Duo::AKEY_LEN vals = [username, ikey] duo_sig = sign_vals(skey, vals, Duo::DUO_PREFIX, Duo::DUO_EXPIRE) app_sig = sign_vals(akey, vals, Duo::APP_PREFIX, Duo::APP_EXPIRE) return [duo_sig, app_sig].join(':') end
verify_response(ikey, skey, akey, sig_response)
click to toggle source
Verify a Duo
2FA request @param ikey [String] The Duo
IKEY @param skey [String] The Duo
SKEY @param akey [String] The Duo
AKEY @param sig_response [String] Response from Duo
service
# File lib/duo_web.rb, line 49 def verify_response(ikey, skey, akey, sig_response) begin auth_sig, app_sig = sig_response.to_s.split(':') auth_user = parse_vals(skey, auth_sig, Duo::AUTH_PREFIX, ikey) app_user = parse_vals(akey, app_sig, Duo::APP_PREFIX, ikey) rescue return nil end return nil if auth_user != app_user return auth_user end
Private Instance Methods
hmac_sha1(key, data)
click to toggle source
# File lib/duo_web.rb, line 65 def hmac_sha1(key, data) OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), key, data.to_s) end
parse_vals(key, val, prefix, ikey)
click to toggle source
# File lib/duo_web.rb, line 82 def parse_vals(key, val, prefix, ikey) ts = Time.now.to_i parts = val.to_s.split('|') return nil if parts.length != 3 u_prefix, u_b64, u_sig = parts sig = hmac_sha1(key, [u_prefix, u_b64].join('|')) return nil if hmac_sha1(key, sig) != hmac_sha1(key, u_sig) return nil if u_prefix != prefix cookie_parts = Base64.decode64(u_b64).to_s.split('|') return nil if cookie_parts.length != 3 user, u_ikey, exp = cookie_parts return nil if u_ikey != ikey return nil if ts >= exp.to_i return user end
sign_vals(key, vals, prefix, expire)
click to toggle source
# File lib/duo_web.rb, line 69 def sign_vals(key, vals, prefix, expire) exp = Time.now.to_i + expire val_list = vals + [exp] val = val_list.join('|') b64 = Base64.encode64(val).delete("\n") cookie = prefix + '|' + b64 sig = hmac_sha1(key, cookie) return [cookie, sig].join('|') end