🎣 Open-Source Phishing Toolkit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.8 KiB

  1. package auth
  2. import (
  3. "encoding/gob"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "crypto/rand"
  9. "github.com/gophish/gophish/models"
  10. ctx "github.com/gorilla/context"
  11. "github.com/gorilla/securecookie"
  12. "github.com/gorilla/sessions"
  13. "golang.org/x/crypto/bcrypt"
  14. )
  15. //init registers the necessary models to be saved in the session later
  16. func init() {
  17. gob.Register(&models.User{})
  18. gob.Register(&models.Flash{})
  19. }
  20. // Store contains the session information for the request
  21. var Store = sessions.NewCookieStore(
  22. []byte(securecookie.GenerateRandomKey(64)), //Signing key
  23. []byte(securecookie.GenerateRandomKey(32)))
  24. // ErrInvalidPassword is thrown when a user provides an incorrect password.
  25. var ErrInvalidPassword = errors.New("Invalid Password")
  26. // Login attempts to login the user given a request.
  27. func Login(r *http.Request) (bool, error) {
  28. username, password := r.FormValue("username"), r.FormValue("password")
  29. session, _ := Store.Get(r, "gophish")
  30. u, err := models.GetUserByUsername(username)
  31. if err != nil && err != models.ErrUsernameTaken {
  32. return false, err
  33. }
  34. //If we've made it here, we should have a valid user stored in u
  35. //Let's check the password
  36. err = bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(password))
  37. if err != nil {
  38. ctx.Set(r, "user", nil)
  39. return false, ErrInvalidPassword
  40. }
  41. ctx.Set(r, "user", u)
  42. session.Values["id"] = u.Id
  43. return true, nil
  44. }
  45. // Register attempts to register the user given a request.
  46. func Register(r *http.Request) (bool, error) {
  47. username, password := r.FormValue("username"), r.FormValue("password")
  48. u, err := models.GetUserByUsername(username)
  49. // If we have an error which is not simply indicating that no user was found, report it
  50. if err != nil {
  51. fmt.Println(err)
  52. return false, err
  53. }
  54. u = models.User{}
  55. //If we've made it here, we should have a valid username given
  56. //Let's create the password hash
  57. h, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
  58. if err != nil {
  59. return false, err
  60. }
  61. u.Username = username
  62. u.Hash = string(h)
  63. u.ApiKey = GenerateSecureKey()
  64. err = models.PutUser(&u)
  65. return true, nil
  66. }
  67. // GenerateSecureKey creates a secure key to use
  68. // as an API key
  69. func GenerateSecureKey() string {
  70. // Inspired from gorilla/securecookie
  71. k := make([]byte, 32)
  72. io.ReadFull(rand.Reader, k)
  73. return fmt.Sprintf("%x", k)
  74. }
  75. func ChangePassword(r *http.Request) error {
  76. u := ctx.Get(r, "user").(models.User)
  77. c, n := r.FormValue("current_password"), r.FormValue("new_password")
  78. // Check the current password
  79. err := bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(c))
  80. if err != nil {
  81. return ErrInvalidPassword
  82. } else {
  83. // Generate the new hash
  84. h, err := bcrypt.GenerateFromPassword([]byte(n), bcrypt.DefaultCost)
  85. if err != nil {
  86. return err
  87. }
  88. u.Hash = string(h)
  89. if err = models.PutUser(&u); err != nil {
  90. return err
  91. }
  92. return nil
  93. }
  94. }