Skip to content

Commit

Permalink
truststore_nss: retry certtool with sudo when it fails due to permiss…
Browse files Browse the repository at this point in the history
…ions

Based on @rfay's investigation and fix.

Fixes #192
Closes #193
  • Loading branch information
FiloSottile committed Nov 9, 2019
1 parent 71aa64e commit edc487d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
8 changes: 4 additions & 4 deletions truststore_java.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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
}
Expand All @@ -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,
Expand Down
22 changes: 18 additions & 4 deletions truststore_nss.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package main

import (
"bytes"
"log"
"os"
"os/exec"
Expand Down Expand Up @@ -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
Expand All @@ -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...)
Expand Down

0 comments on commit edc487d

Please sign in to comment.