Bladeren bron

truststore_nss: retry certtool with sudo when it fails due to permissions

Based on @rfay's investigation and fix.

Fixes #192
Closes #193
Filippo Valsorda 5 jaren geleden
bovenliggende
commit
1b4ad6c774
2 gewijzigde bestanden met toevoegingen van 22 en 8 verwijderingen
  1. 4 4
      truststore_java.go
  2. 18 4
      truststore_nss.go

+ 4 - 4
truststore_java.go

@@ -87,7 +87,7 @@ func (m *mkcert) installJava() {
 		"-alias", m.caUniqueName(),
 	}
 
-	out, err := m.execKeytool(exec.Command(keytoolPath, args...))
+	out, err := execKeytool(exec.Command(keytoolPath, args...))
 	fatalIfCmdErr(err, "keytool -importcert", out)
 }
 
@@ -98,7 +98,7 @@ func (m *mkcert) uninstallJava() {
 		"-keystore", cacertsPath,
 		"-storepass", storePass,
 	}
-	out, err := m.execKeytool(exec.Command(keytoolPath, args...))
+	out, err := execKeytool(exec.Command(keytoolPath, args...))
 	if bytes.Contains(out, []byte("does not exist")) {
 		return // cert didn't exist
 	}
@@ -107,11 +107,11 @@ func (m *mkcert) uninstallJava() {
 
 // execKeytool will execute a "keytool" command and if needed re-execute
 // the command with commandWithSudo to work around file permissions.
-func (m *mkcert) execKeytool(cmd *exec.Cmd) ([]byte, error) {
+func execKeytool(cmd *exec.Cmd) ([]byte, error) {
 	out, err := cmd.CombinedOutput()
 	if err != nil && bytes.Contains(out, []byte("java.io.FileNotFoundException")) && runtime.GOOS != "windows" {
 		origArgs := cmd.Args[1:]
-		cmd = commandWithSudo(keytoolPath)
+		cmd = commandWithSudo(cmd.Path)
 		cmd.Args = append(cmd.Args, origArgs...)
 		cmd.Env = []string{
 			"JAVA_HOME=" + javaHome,

+ 18 - 4
truststore_nss.go

@@ -5,6 +5,7 @@
 package main
 
 import (
+	"bytes"
 	"log"
 	"os"
 	"os/exec"
@@ -83,8 +84,8 @@ func (m *mkcert) checkNSS() bool {
 func (m *mkcert) installNSS() bool {
 	if m.forEachNSSProfile(func(profile string) {
 		cmd := exec.Command(certutilPath, "-A", "-d", profile, "-t", "C,,", "-n", m.caUniqueName(), "-i", filepath.Join(m.CAROOT, rootName))
-		out, err := cmd.CombinedOutput()
-		fatalIfCmdErr(err, "certutil -A", out)
+		out, err := execCertutil(cmd)
+		fatalIfCmdErr(err, "certutil -A -d "+profile, out)
 	}) == 0 {
 		log.Printf("ERROR: no %s security databases found", NSSBrowsers)
 		return false
@@ -104,11 +105,24 @@ func (m *mkcert) uninstallNSS() {
 			return
 		}
 		cmd := exec.Command(certutilPath, "-D", "-d", profile, "-n", m.caUniqueName())
-		out, err := cmd.CombinedOutput()
-		fatalIfCmdErr(err, "certutil -D", out)
+		out, err := execCertutil(cmd)
+		fatalIfCmdErr(err, "certutil -D -d "+profile, out)
 	})
 }
 
+// execCertutil will execute a "certutil" command and if needed re-execute
+// the command with commandWithSudo to work around file permissions.
+func execCertutil(cmd *exec.Cmd) ([]byte, error) {
+	out, err := cmd.CombinedOutput()
+	if err != nil && bytes.Contains(out, []byte("SEC_ERROR_READ_ONLY")) && runtime.GOOS != "windows" {
+		origArgs := cmd.Args[1:]
+		cmd = commandWithSudo(cmd.Path)
+		cmd.Args = append(cmd.Args, origArgs...)
+		out, err = cmd.CombinedOutput()
+	}
+	return out, err
+}
+
 func (m *mkcert) forEachNSSProfile(f func(profile string)) (found int) {
 	profiles, _ := filepath.Glob(FirefoxProfile)
 	profiles = append(profiles, nssDBs...)