<s> import base64 <EOL> import hashlib <EOL> import hmac <EOL> import time <EOL> DUO_PREFIX = '<STR_LIT>' <EOL> APP_PREFIX = '<STR_LIT>' <EOL> AUTH_PREFIX = '<STR_LIT>' <EOL> DUO_EXPIRE = <NUM_LIT> <EOL> APP_EXPIRE = <NUM_LIT> <EOL> IKEY_LEN = <NUM_LIT:20> <EOL> SKEY_LEN = <NUM_LIT> <EOL> AKEY_LEN = <NUM_LIT> <EOL> ERR_USER = '<STR_LIT>' <EOL> ERR_IKEY = '<STR_LIT>' <EOL> ERR_SKEY = '<STR_LIT>' <EOL> ERR_AKEY = '<STR_LIT>' % AKEY_LEN <EOL> ERR_UNKNOWN = '<STR_LIT>' <EOL> def _hmac_sha1 ( key , msg ) : <EOL> ctx = hmac . new ( key , msg , hashlib . sha1 ) <EOL> return ctx . hexdigest ( ) <EOL> def _sign_vals ( key , vals , prefix , expire ) : <EOL> exp = str ( int ( time . time ( ) ) + expire ) <EOL> val = '<STR_LIT:|>' . join ( vals + [ exp ] ) <EOL> b64 = base64 . b64encode ( val ) <EOL> cookie = '<STR_LIT>' % ( prefix , b64 ) <EOL> sig = _hmac_sha1 ( key , cookie ) <EOL> return '<STR_LIT>' % ( cookie , sig ) <EOL> def _parse_vals ( key , val , prefix ) : <EOL> ts = int ( time . time ( ) ) <EOL> u_prefix , u_b64 , u_sig = val . split ( '<STR_LIT:|>' ) <EOL> sig = _hmac_sha1 ( key , '<STR_LIT>' % ( u_prefix , u_b64 ) ) <EOL> if _hmac_sha1 ( key , sig ) != _hmac_sha1 ( key , u_sig ) : <EOL> return None <EOL> if u_prefix != prefix : <EOL> return None <EOL> user , ikey , exp = base64 . b64decode ( u_b64 ) . split ( '<STR_LIT:|>' ) <EOL> if ts >= int ( exp ) : <EOL> return None <EOL> return user <EOL> def sign_request ( ikey , skey , akey , username ) : <EOL> """<STR_LIT>""" <EOL> if not username : <EOL> return ERR_USER <EOL> if not ikey or len ( ikey ) != IKEY_LEN : <EOL> return ERR_IKEY <EOL> if not skey or len ( skey ) != SKEY_LEN : <EOL> return ERR_SKEY <EOL> if not akey or len ( akey ) < AKEY_LEN : <EOL> return ERR_AKEY <EOL> vals = [ username , ikey ] <EOL> try : <EOL> duo_sig = _sign_vals ( skey , vals , DUO_PREFIX , DUO_EXPIRE ) <EOL> app_sig = _sign_vals ( akey , vals , APP_PREFIX , APP_EXPIRE ) <EOL> except : <EOL> return ERR_UNKNOWN <EOL> return '<STR_LIT>' % ( duo_sig , app_sig ) <EOL> def verify_response ( ikey , skey , akey , sig_response ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> auth_sig , app_sig = sig_response . split ( '<STR_LIT::>' ) <EOL> auth_user = _parse_vals ( skey , auth_sig , AUTH_PREFIX ) <EOL> app_user = _parse_vals ( akey , app_sig , APP_PREFIX ) <EOL> except : <EOL> return None <EOL> if auth_user != app_user : <EOL> return None <EOL> return auth_user </s>
