auth.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package auth
  2. import (
  3. "crypto"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "encoding/base64"
  8. "encoding/pem"
  9. log "github.com/sirupsen/logrus"
  10. "os"
  11. "pmail/db"
  12. "pmail/models"
  13. "pmail/utils/context"
  14. "strings"
  15. )
  16. // HasAuth 检查当前用户是否有某个邮件的auth
  17. func HasAuth(ctx *context.Context, email *models.Email) bool {
  18. if ctx.IsAdmin {
  19. return true
  20. }
  21. var ue *models.UserEmail
  22. err := db.Instance.Where("email_id = ?", email.Id).Find(&ue)
  23. if err != nil {
  24. log.Errorf("Error while checking user: %v", err)
  25. return false
  26. }
  27. return ue != nil
  28. }
  29. func DkimGen() string {
  30. privKeyStr, _ := os.ReadFile("./config/dkim/dkim.priv")
  31. publicKeyStr, _ := os.ReadFile("./config/dkim/dkim.public")
  32. if len(privKeyStr) > 0 && len(publicKeyStr) > 0 {
  33. return string(publicKeyStr)
  34. }
  35. var (
  36. privKey crypto.Signer
  37. err error
  38. )
  39. privKey, err = rsa.GenerateKey(rand.Reader, 1024)
  40. if err != nil {
  41. log.Fatalf("Failed to generate key: %v", err)
  42. }
  43. privBytes, err := x509.MarshalPKCS8PrivateKey(privKey)
  44. if err != nil {
  45. log.Fatalf("Failed to marshal private key: %v", err)
  46. }
  47. f, err := os.OpenFile("./config/dkim/dkim.priv", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
  48. if err != nil {
  49. log.Fatalf("Failed to create key file: %v", err)
  50. }
  51. defer f.Close()
  52. privBlock := pem.Block{
  53. Type: "PRIVATE KEY",
  54. Bytes: privBytes,
  55. }
  56. if err := pem.Encode(f, &privBlock); err != nil {
  57. log.Fatalf("Failed to write key PEM block: %v", err)
  58. }
  59. if err := f.Close(); err != nil {
  60. log.Fatalf("Failed to close key file: %v", err)
  61. }
  62. var pubBytes []byte
  63. switch pubKey := privKey.Public().(type) {
  64. case *rsa.PublicKey:
  65. // RFC 6376 is inconsistent about whether RSA public keys should
  66. // be formatted as RSAPublicKey or SubjectPublicKeyInfo.
  67. // Erratum 3017 (https://www.rfc-editor.org/errata/eid3017)
  68. // proposes allowing both. We use SubjectPublicKeyInfo for
  69. // consistency with other implementations including opendkim,
  70. // Gmail, and Fastmail.
  71. pubBytes, err = x509.MarshalPKIXPublicKey(pubKey)
  72. if err != nil {
  73. log.Fatalf("Failed to marshal public key: %v", err)
  74. }
  75. default:
  76. panic("unreachable")
  77. }
  78. params := []string{
  79. "v=DKIM1",
  80. "k=rsa",
  81. "p=" + base64.StdEncoding.EncodeToString(pubBytes),
  82. }
  83. publicKey := strings.Join(params, "; ")
  84. os.WriteFile("./config/dkim/dkim.public", []byte(publicKey), 0666)
  85. return publicKey
  86. }