diff --git a/truststore_java.go b/truststore_java.go index 410e453..8ad84bb 100644 --- a/truststore_java.go +++ b/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, diff --git a/truststore_nss.go b/truststore_nss.go index 1cb1eaa..a7c315e 100644 --- a/truststore_nss.go +++ b/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...)