Advertisement
Guest User

Untitled

a guest
Jul 13th, 2017
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.31 KB | None | 0 0
  1. (ql:quickload :cl-base32)
  2. (ql:quickload :hunchentoot)
  3. (ql:quickload :cl-one-time-passwords)
  4. (ql:quickload :cl-qrencode)
  5. (ql:quickload :cl-pass)
  6. (ql:quickload :babel)
  7. (ql:quickload :flexi-streams)
  8. (ql:quickload :cl-who)
  9. (ql:quickload :ironclad)
  10.  
  11. (defpackage otp-test
  12. (:use :cl))
  13.  
  14. (in-package :otp-test)
  15.  
  16. (setf *random-state* (make-random-state t))
  17. (setf crypto:*prng* (crypto:make-prng :fortuna))
  18. (setf totp:*time-step-in-seconds* 30)
  19.  
  20. (defun make-otp-secret ()
  21. (ironclad:byte-array-to-hex-string (crypto:random-data 20)))
  22.  
  23. (defclass user ()
  24. ((username :initarg :username
  25. :accessor username
  26. :initform nil)
  27. (password :initarg :password
  28. :accessor password
  29. :initform nil)
  30. (otp-secret :initarg :otp-secret
  31. :accessor otp-secret
  32. :initform nil)))
  33.  
  34. (defmethod totp-uri ((user user))
  35. (format nil "otpauth://totp/2FATest:~A?secret=~A&issuer=2FATest"
  36. (username user)
  37. (cl-base32:bytes-to-base32
  38. (ironclad:hex-string-to-byte-array
  39. (otp-secret user)))))
  40.  
  41. (defparameter *user* (make-instance 'user
  42. :username "testuser"
  43. :password (cl-pass:hash "testuser")
  44. :otp-secret (make-otp-secret)))
  45.  
  46.  
  47. (hunchentoot:define-easy-handler (qrcode :uri "/qrcode") ()
  48. (setf (hunchentoot:content-type*) "image/png")
  49. (flex:with-output-to-sequence (stream)
  50. (cl-qrencode:encode-png-stream (totp-uri *user*) stream
  51. :level :level-m
  52. :mode :byte)))
  53.  
  54. (defun call-with-test-page (function)
  55. (who:with-html-output-to-string (html)
  56. (:html
  57. (:header
  58. (:title "2FA FreeOTP test"))
  59. (:body
  60. (:h1 (who:str "2FA FreeOTP test"))
  61. (:p (who:str "This is a FreeOTP test for Two Factor Authentication"))
  62. (:h3 (who:str "Instructions"))
  63. (:ol
  64. (:li (who:str "Install FreeOTP"))
  65. (:li (who:str "Scan the QR code"))
  66. (:li (who:str "Generate tokens in your phone and input here"))
  67. (:li (who:str "Click on \"Test\" button and verify it succeeds")))
  68. (:p (:b (who:str "IMPORTANT NOTE:")) "FreeOTP is very sensible regarding clock times, and tokens are valid for only 30 seconds, so it is very easy to get out of sync with the server. So you should make sure your phone's clock is uptodate")
  69. (:img :src "/qrcode" :width 200 :height 200)
  70. (:form :action "/login" :method :post
  71. (:input :type "text" :name "token")
  72. (:input :type "submit" :value "Test"))
  73. (funcall function html)))))
  74.  
  75. (hunchentoot:define-easy-handler (test :uri "/") ()
  76. (call-with-test-page (lambda (html))))
  77.  
  78. (hunchentoot:define-easy-handler (login :uri "/login") ()
  79. (call-with-test-page (lambda (html)
  80. (who:with-html-output (html html)
  81. (if (= (totp:totp (otp-secret *user*))
  82. (parse-integer (hunchentoot:parameter "token")))
  83. (who:htm (:h1 :style "color:green;"
  84. "Success!!"))
  85. (who:htm (:h1 :style "color:red;"
  86. "Failed")))))))
  87.  
  88. (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 9095))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement