Advertisement
Guest User

F5 - APM ga_code_verify

a guest
Jan 8th, 2018
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.75 KB | None | 0 0
  1. when ACCESS_POLICY_AGENT_EVENT {
  2.  
  3. if { [ACCESS::policy agent_id] eq "ga_code_verify" } {
  4. ### Google Authenticator verification settings ###
  5.  
  6. # lock the user out after x attempts for a period of x seconds
  7. set static::lockout_attempts 3
  8. set static::lockout_period 30
  9.  
  10. # logon page session variable name for code attempt form field
  11. set static::ga_code_form_field "ga_code_attempt"
  12.  
  13. # key (shared secret) storage method: ldap, ad, or datagroup
  14. set static::ga_key_storage "datagroup"
  15.  
  16. # LDAP attribute for key if storing in LDAP (optional)
  17. set static::ga_key_ldap_attr "google_auth_key"
  18.  
  19. # Active Directory attribute for key if storing in AD (optional)
  20. set static::ga_key_ad_attr "google_auth_key"
  21.  
  22. # datagroup name if storing key in a datagroup (optional)
  23. set static::ga_key_dg "google_auth_keys"
  24.  
  25.  
  26. #####################################
  27. ### DO NOT MODIFY BELOW THIS LINE ###
  28. #####################################
  29.  
  30. # set lockout table
  31. set static::lockout_state_table "[virtual name]_lockout_status"
  32.  
  33. # set variables from APM logon page
  34. set username [ACCESS::session data get session.logon.last.username]
  35. set ga_code_attempt [ACCESS::session data get session.logon.last.$static::ga_code_form_field]
  36.  
  37. # retrieve key from specified storage
  38. set ga_key ""
  39.  
  40. switch $static::ga_key_storage {
  41. ldap {
  42. set ga_key [ACCESS::session data get session.ldap.last.attr.$static::ga_key_ldap_attr]
  43. }
  44. ad {
  45. set ga_key [ACCESS::session data get session.ad.last.attr.$static::ga_key_ad_attr]
  46. }
  47. datagroup {
  48. set ga_key [class lookup $username $static::ga_key_dg]
  49. }
  50. }
  51.  
  52. # increment the number of login attempts for the user
  53. set prev_attempts [table incr -notouch -subtable $static::lockout_state_table $username]
  54. table timeout -subtable $static::lockout_state_table $username $static::lockout_period
  55.  
  56. # verification result value:
  57. # 0 = successful
  58. # 1 = failed
  59. # 2 = no key found
  60. # 3 = invalid key length
  61. # 4 = user locked out
  62.  
  63. # make sure that the user isn't locked out before calculating GA code
  64. if { $prev_attempts <= $static::lockout_attempts } {
  65.  
  66. # check that a valid key was retrieved, then proceed
  67. if { [string length $ga_key] == 16 } {
  68. # begin - Base32 decode to binary
  69.  
  70. # Base32 alphabet (see RFC 4648)
  71. array set static::b32_alphabet {
  72. A 0 B 1 C 2 D 3
  73. E 4 F 5 G 6 H 7
  74. I 8 J 9 K 10 L 11
  75. M 12 N 13 O 14 P 15
  76. Q 16 R 17 S 18 T 19
  77. U 20 V 21 W 22 X 23
  78. Y 24 Z 25 2 26 3 27
  79. 4 28 5 29 6 30 7 31
  80. }
  81.  
  82. set ga_key [string toupper $ga_key]
  83. set l [string length $ga_key]
  84. set n 0
  85. set j 0
  86. set ga_key_bin ""
  87.  
  88. for { set i 0 } { $i < $l } { incr i } {
  89. set n [expr $n << 5]
  90. set n [expr $n + $static::b32_alphabet([string index $ga_key $i])]
  91. set j [incr j 5]
  92.  
  93. if { $j >= 8 } {
  94. set j [incr j -8]
  95. append ga_key_bin [format %c [expr ($n & (0xFF << $j)) >> $j]]
  96. }
  97. }
  98.  
  99. # end - Base32 decode to binary
  100.  
  101. # begin - HMAC-SHA1 calculation of Google Auth token
  102.  
  103. set time [binary format W* [expr [clock seconds] / 30]]
  104.  
  105. set ipad ""
  106. set opad ""
  107.  
  108. for { set j 0 } { $j < [string length $ga_key_bin] } { incr j } {
  109. binary scan $ga_key_bin @${j}H2 k
  110. set o [expr 0x$k ^ 0x5C]
  111. set i [expr 0x$k ^ 0x36]
  112. append ipad [format %c $i]
  113. append opad [format %c $o]
  114. }
  115.  
  116. while { $j < 64 } {
  117. append ipad 6
  118. append opad \\
  119. incr j
  120. }
  121.  
  122. binary scan [sha1 $opad[sha1 ${ipad}${time}]] H* token
  123.  
  124. # end - HMAC-SHA1 calculation of Google Auth hex token
  125.  
  126. # begin - extract code from Google Auth hex token
  127.  
  128. set offset [expr ([scan [string index $token end] %x] & 0x0F) << 1]
  129. set ga_code [expr (0x[string range $token $offset [expr $offset + 7]] & 0x7FFFFFFF) % 1000000]
  130. set ga_code [format %06d $ga_code]
  131.  
  132. # end - extract code from Google Auth hex token
  133.  
  134. if { $ga_code_attempt eq $ga_code } {
  135. # code verification successful
  136. set ga_result 0
  137. } else {
  138. # code verification failed
  139. set ga_result 1
  140. }
  141. } elseif { [string length $ga_key] > 0 } {
  142. # invalid key length, greater than 0, but not length not equal to 16 chars
  143. set ga_result 3
  144. } else {
  145. # could not retrieve user's key
  146. set ga_result 2
  147. }
  148. } else {
  149. # user locked out due to too many failed attempts
  150. set ga_result 4
  151. }
  152.  
  153. # set code verification result in session variable
  154. ACCESS::session data set session.custom.ga_result $ga_result
  155. }
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement