truststore_firefox.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package main
  2. import (
  3. "log"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "runtime"
  8. "strings"
  9. )
  10. var (
  11. hasFirefox bool
  12. hasCertutil bool
  13. certutilPath string
  14. )
  15. func init() {
  16. _, err := os.Stat(FirefoxPath)
  17. hasFirefox = !os.IsNotExist(err)
  18. out, err := exec.Command("brew", "--prefix", "nss").Output()
  19. if err != nil {
  20. return
  21. }
  22. certutilPath = filepath.Join(strings.TrimSpace(string(out)), "bin", "certutil")
  23. _, err = os.Stat(certutilPath)
  24. hasCertutil = !os.IsNotExist(err)
  25. }
  26. func (m *mkcert) checkFirefox() bool {
  27. if !hasCertutil {
  28. return false
  29. }
  30. success := true
  31. if m.forEachFirefoxProfile(func(profile string) {
  32. err := exec.Command(certutilPath, "-V", "-d", profile, "-u", "L", "-n", m.caUniqueName()).Run()
  33. if err != nil {
  34. success = false
  35. }
  36. }) == 0 {
  37. success = false
  38. }
  39. return success
  40. }
  41. func (m *mkcert) installFirefox() {
  42. if m.forEachFirefoxProfile(func(profile string) {
  43. cmd := exec.Command(certutilPath, "-A", "-d", profile, "-t", "C,,", "-n", m.caUniqueName(), "-i", filepath.Join(m.CAROOT, rootName))
  44. out, err := cmd.CombinedOutput()
  45. if err != nil {
  46. log.Printf("!!! You've hit a known issue. Please report the entire command output at https://github.com/FiloSottile/mkcert/issues/12\nProfile path: %s\nOS: %s/%s\ncertutil: %s\n", profile, runtime.GOOS, runtime.GOARCH, certutilPath)
  47. cmd := exec.Command("ls", "-l", profile[4:])
  48. cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr
  49. cmd.Run()
  50. }
  51. fatalIfCmdErr(err, "certutil -A", out)
  52. }) == 0 {
  53. log.Println("ERROR: no Firefox security databases found")
  54. }
  55. if !m.checkFirefox() {
  56. log.Println("Installing in Firefox failed. Please report the issue with details about your environment at https://github.com/FiloSottile/mkcert/issues/new 👎")
  57. log.Println("Note that if you never started Firefox, you need to do that at least once.")
  58. }
  59. }
  60. func (m *mkcert) uninstallFirefox() {
  61. m.forEachFirefoxProfile(func(profile string) {
  62. err := exec.Command(certutilPath, "-V", "-d", profile, "-u", "L", "-n", m.caUniqueName()).Run()
  63. if err != nil {
  64. return
  65. }
  66. cmd := exec.Command(certutilPath, "-D", "-d", profile, "-n", m.caUniqueName())
  67. out, err := cmd.CombinedOutput()
  68. fatalIfCmdErr(err, "certutil -D", out)
  69. })
  70. }
  71. func (m *mkcert) forEachFirefoxProfile(f func(profile string)) (found int) {
  72. profiles, _ := filepath.Glob(FirefoxProfile)
  73. if len(profiles) == 0 {
  74. return
  75. }
  76. for _, profile := range profiles {
  77. if _, err := os.Stat(filepath.Join(profile, "cert8.db")); !os.IsNotExist(err) {
  78. f("dbm:" + profile)
  79. found++
  80. }
  81. if _, err := os.Stat(filepath.Join(profile, "cert9.db")); !os.IsNotExist(err) {
  82. f("sql:" + profile)
  83. found++
  84. }
  85. }
  86. return
  87. }